diff --git a/CMakeLists.txt b/CMakeLists.txt index 48b80aa..ab50798 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set( MY_INCLUDES ${PROJECT_SOURCE_DIR}/include) -set( MY_SOURCES main.cpp src/Parser.cpp src/LALRParser.cpp src/GraphStructuredStack.cpp src/RNGLRParser.cpp src/ParseAction.cpp src/ParseRule.cpp src/Symbol.cpp src/StringReader.cpp src/State.cpp src/util.cpp src/Lexer.cpp src/RegEx.cpp src/RegExState.cpp src/Table.cpp src/ASTData.cpp src/ASTTransformation.cpp src/CGenerator.cpp src/Type.cpp src/Importer.cpp ) +set( MY_SOURCES main.cpp src/Parser.cpp src/LALRParser.cpp src/GraphStructuredStack.cpp src/RNGLRParser.cpp src/ParseAction.cpp src/ParseRule.cpp src/Symbol.cpp src/StringReader.cpp src/State.cpp src/util.cpp src/Lexer.cpp src/RegEx.cpp src/RegExState.cpp src/Table.cpp src/ASTData.cpp src/ASTTransformation.cpp src/CGenerator.cpp src/Type.cpp src/Importer.cpp src/Tester.cpp ) add_custom_target(STDLibCopy ALL) add_custom_command(TARGET STDLibCopy POST_BUILD diff --git a/include/Tester.h b/include/Tester.h new file mode 100644 index 0000000..7bf1815 --- /dev/null +++ b/include/Tester.h @@ -0,0 +1,31 @@ +#include +#include + +#include + +#include "util.h" + +#ifndef TESTER_H +#define TESTER_H + +class Tester { + public: + Tester(std::string krakenInvocation, std::string krakenGrammerLocation); + ~Tester(); + int ssystem(std::string command); + bool run(std::string fileName); + bool compareFiles(std::string file1Path, std::string file2Path); + void cleanExtras(std::string fileName); + + private: + std::string krakenInvocation; + std::string krakenGrammerLocation; + std::string removeCmd; + std::string resultsExtention; + std::string expectedExtention; + std::string krakenExtention; + std::string shell; + std::string changePermissions; + std::string redirect; +}; +#endif diff --git a/include/util.h b/include/util.h index 7f17f51..87edef2 100644 --- a/include/util.h +++ b/include/util.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include std::string intToString(int theInt); std::string replaceExEscape(std::string first, std::string search, std::string replace); @@ -16,6 +18,9 @@ std::string strSlice(std::string str, int begin, int end); int findPerenEnd(std::string str, int i); std::vector split(const std::string &str, char delim); std::string join(const std::vector &strVec, std::string joinStr); +std::string readFile(std::istream &file); + + template bool contains(std::vector vec, T item) { for (auto i : vec) diff --git a/main.cpp b/main.cpp index 06d6e61..ace2966 100644 --- a/main.cpp +++ b/main.cpp @@ -16,16 +16,34 @@ #include "CGenerator.h" #include "util.h" +#include "Tester.h" int main(int argc, char* argv[]) { std::vector includePaths; includePaths.push_back(""); //Local - if (argc == 2 && std::string(argv[1]) == "--test") { + if (argc >= 2 && std::string(argv[1]) == "--test") { StringReader::test(); RegEx::test(); Lexer::test(); //std::cout << strSlice("123", 0, -1) << std::endl; + if (argc >= 3) { + std::string testResults, line; + int passed = 0, failed = 0; + Tester test(argv[0], "../krakenGrammer.kgm"); + for (int i = 2; i < argc; i++) { + bool result = test.run(argv[i]); + if (result) + line = std::string(argv[i]) + "\t\tpassed!\n", passed++; + else + line = std::string(argv[i]) + "\t\tFAILED!\n", failed++; + std::cout << line << std::endl; + testResults += line; + } + std::cout << "===========Done Testing===========" << std::endl; + std::cout << testResults << std::endl; + std::cout << "Test results: " << passed << "/" << passed+failed << std::endl; + } return 0; } std::string krakenDir = argv[0]; diff --git a/src/Tester.cpp b/src/Tester.cpp new file mode 100644 index 0000000..3f4cbdf --- /dev/null +++ b/src/Tester.cpp @@ -0,0 +1,69 @@ +#include "Tester.h" + +Tester::Tester(std::string krakenInvocation, std::string krakenGrammerLocation) : krakenInvocation(krakenInvocation), krakenGrammerLocation(krakenGrammerLocation) { + //initlization list + removeCmd = "rm"; + resultsExtention = ".results"; + expectedExtention = ".expected_results"; + krakenExtention = ".krak"; + changePermissions = "chmod 755"; + shell = "sh"; + redirect = ">"; +} + +Tester::~Tester() { + //Nothing +} + +int Tester::ssystem(std::string command) { + return system(command.c_str()); +} + +void Tester::cleanExtras(std::string fileName) { + ssystem(removeCmd + " " + fileName); + ssystem(removeCmd + " " + fileName + krakenExtention + "out*"); + ssystem(removeCmd + " " + fileName + krakenExtention + ".c"); + ssystem(removeCmd + " " + fileName + ".sh"); + ssystem(removeCmd + " " + fileName + resultsExtention); +} + +bool Tester::run(std::string fileName) { + std::cout << "Testing: " << fileName << " with " << krakenInvocation << " and " << krakenGrammerLocation << std::endl; + + cleanExtras(fileName); + + ssystem(changePermissions + " " + fileName); + ssystem(krakenInvocation + " " + fileName + krakenExtention + " " + krakenGrammerLocation + " " + fileName); + ssystem(shell + " " + fileName + ".sh"); + ssystem(fileName + " " + redirect + " " + fileName + resultsExtention); + + bool result = compareFiles(fileName + expectedExtention, fileName + resultsExtention); + + //If the test was succesful, we don't need all the extra files + if (result) + cleanExtras(fileName); + + return result; +} + +bool Tester::compareFiles(std::string file1Path, std::string file2Path) { + std::ifstream file1, file2; + file1.open(file1Path); + if (!file1.is_open()) { + std::cout << file1Path << " could not be opened!" << std::endl; + return false; + } + file2.open(file2Path); + if (!file2.is_open()) { + std::cout << file2Path << " could not be opened!" << std::endl; + return false; + } + + std::string file1contents = readFile(file1); + std::string file2contents = readFile(file2); + + // std::cout << "file1: " << file1contents << std::endl; + // std::cout << "file2: " << file2contents << std::endl; + // std::cout << "comp: " << file1contents.compare(file2contents) << std::endl; + return file1contents.compare(file2contents) == 0; +} diff --git a/src/util.cpp b/src/util.cpp index a3c7802..296807e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -71,4 +71,13 @@ std::string join(const std::vector &strVec, std::string joinStr) { return joinedStr; } +std::string readFile(std::istream &file) { + std::string line, contents; + while(file.good()) { + getline(file, line); + contents.append(line+"\n"); + } + return contents; +} + diff --git a/tests/OperatorOverloadTest.expected_results b/tests/OperatorOverloadTest.expected_results new file mode 100644 index 0000000..78b0a52 --- /dev/null +++ b/tests/OperatorOverloadTest.expected_results @@ -0,0 +1,5 @@ +3 9 +6 18 +Subtraction +3 9 +-97 -61 diff --git a/tests/OperatorOverloadTest.krak b/tests/OperatorOverloadTest.krak new file mode 100644 index 0000000..2362187 --- /dev/null +++ b/tests/OperatorOverloadTest.krak @@ -0,0 +1,64 @@ +import io; + +typedef Vec2 { + int x; + int y; + + void print() { + print(x); + print(" "); + print(y); + } + + Vec2 add(Vec2 other) { + Vec2 toReturn; + toReturn.x = x + other.x; + toReturn.y = y + other.y; + print(); + return toReturn; + } + + Vec2 subtract(Vec2 other) { + Vec2 toReturn; + toReturn.x = x - other.x; + toReturn.y = y - other.y; + print(); + return toReturn; + } + + Vec2 operator+(Vec2 other) { + return add(other); + } + +}; + +Vec2 operator-(Vec2 lhs, Vec2 rhs) { + return lhs.subtract(rhs); +} + +int main() { + Vec2 vector1; + Vec2 vector2; + vector1.x = 3; + vector1.y = 9; + vector2 = vector1; + /* NOTE COMMENT + Vec2 vector3; + vector3.x = vector1.x + vector2.x; + vector3.y = vector1.y + vector2.y; + vector2.print(); + */ + Vec2 addition = vector1 + vector2; + print("\n"); + addition.print(); + print("\nSubtraction\n"); + vector2.x = 100; + vector2.y = 70; + Vec2 subtraction = vector1 - vector2; + print("\n"); + print(subtraction.x); print(" "); print(subtraction.y); + + print("\n"); + + return 0; +} diff --git a/tests/RecursiveTest.expected_results b/tests/RecursiveTest.expected_results new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/tests/RecursiveTest.expected_results @@ -0,0 +1 @@ +5 diff --git a/tests/RecursiveTest.krak b/tests/RecursiveTest.krak new file mode 100644 index 0000000..4e61ccc --- /dev/null +++ b/tests/RecursiveTest.krak @@ -0,0 +1,14 @@ +import io; + +int fibanacci(int num) { + if (num < 2) + return 1; + return fibanacci(num-1) + fibanacci(num-2); +} + +int main() { + print(fibanacci(4)); + print("\n"); + return 0; +} + diff --git a/tests/functionTemplateTest.expected_results b/tests/functionTemplateTest.expected_results new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/tests/functionTemplateTest.expected_results @@ -0,0 +1 @@ +22 diff --git a/tests/functionTemplateTest.krak b/tests/functionTemplateTest.krak new file mode 100644 index 0000000..dd51c3d --- /dev/null +++ b/tests/functionTemplateTest.krak @@ -0,0 +1,14 @@ +import io; + +template T addAndPrint(T a, T b) { + print(a+b); + return a+b; +} + +int main() { + + addAndPrint(10,12); + print("\n"); + + return 0; +} \ No newline at end of file diff --git a/tests/memTest.expected_results b/tests/memTest.expected_results new file mode 100644 index 0000000..abd8421 --- /dev/null +++ b/tests/memTest.expected_results @@ -0,0 +1,3 @@ +11 +Hello decent memory! Quite a nice feeling + diff --git a/tests/memTest.krak b/tests/memTest.krak new file mode 100644 index 0000000..44acd40 --- /dev/null +++ b/tests/memTest.krak @@ -0,0 +1,27 @@ +import mem; +import io; + +typedef AnObject { + int a; + int b; + char* c; + + void print() { + print(a+b); + print("\n"); + print(c); + print("\n"); + } +}; + + +int main() { + AnObject* ptr = new(); + ptr->a = 4; + ptr->b = 7; + ptr->c = "Hello decent memory! Quite a nice feeling\n"; + ptr->print(); + delete(ptr); + + return 0; +} \ No newline at end of file diff --git a/tests/moreComplexObjectTest.expected_results b/tests/moreComplexObjectTest.expected_results new file mode 100644 index 0000000..8b751d2 --- /dev/null +++ b/tests/moreComplexObjectTest.expected_results @@ -0,0 +1,2 @@ +742 +1337 diff --git a/tests/moreComplexObjectTest.krak b/tests/moreComplexObjectTest.krak new file mode 100644 index 0000000..8da7762 --- /dev/null +++ b/tests/moreComplexObjectTest.krak @@ -0,0 +1,29 @@ +import io; + +typedef firstObject { + int objectNum; + int other; + void print() { + print(other); + } + void printInd() { + print(); + } +}; + +typedef Int int; + +Int aliasNum; + +int main() { + firstObject wooObject; + wooObject.objectNum = 7; + print(wooObject.objectNum); + firstObject* objPtr = &wooObject; + objPtr->objectNum = 42; + print(objPtr->objectNum); + print("\n"); + objPtr->other = 1337; + objPtr->printInd(); + print("\n"); +} diff --git a/tests/objectOrderingTest.expected_results b/tests/objectOrderingTest.expected_results new file mode 100644 index 0000000..48082f7 --- /dev/null +++ b/tests/objectOrderingTest.expected_results @@ -0,0 +1 @@ +12 diff --git a/tests/objectOrderingTest.krak b/tests/objectOrderingTest.krak new file mode 100644 index 0000000..80a96cb --- /dev/null +++ b/tests/objectOrderingTest.krak @@ -0,0 +1,27 @@ +import io; + +typedef objectA { + int a; +}; + +typedef BigObject { + objectA a; + objectB b; + int add() { + return a.a + b.b; + } +}; + +typedef objectB { + int b; +}; + + +int main() { + BigObject c; + c.a.a = 4; + c.b.b = 8; + print(c.add()); + print("\n"); + return 0; +} diff --git a/tests/simpleFunctionTest.expected_results b/tests/simpleFunctionTest.expected_results new file mode 100644 index 0000000..635328e --- /dev/null +++ b/tests/simpleFunctionTest.expected_results @@ -0,0 +1 @@ +1919 diff --git a/tests/simpleFunctionTest.krak b/tests/simpleFunctionTest.krak new file mode 100644 index 0000000..c78e629 --- /dev/null +++ b/tests/simpleFunctionTest.krak @@ -0,0 +1,14 @@ +import io; + +int addAndPrintInt(int a, int b) { + print(a+b); + return a+b; +} + +int main() { + + print(addAndPrintInt(7,12)); + print("\n"); + + return 0; +} \ No newline at end of file diff --git a/tests/simpleObjectTest.expected_results b/tests/simpleObjectTest.expected_results new file mode 100644 index 0000000..e1617e8 --- /dev/null +++ b/tests/simpleObjectTest.expected_results @@ -0,0 +1 @@ +57 diff --git a/tests/simpleObjectTest.krak b/tests/simpleObjectTest.krak new file mode 100644 index 0000000..9a96ac5 --- /dev/null +++ b/tests/simpleObjectTest.krak @@ -0,0 +1,18 @@ + +import io; + +typedef FirstObject { + int objectNum; + void PrintSelf(int a) { + print(objectNum); + print(a); + } +}; + +int main() { + FirstObject wooObject; + wooObject.objectNum = 5; + wooObject.PrintSelf(7); + print("\n"); + return 0; +} diff --git a/tests/templateTest.expected_results b/tests/templateTest.expected_results new file mode 100644 index 0000000..15fa1a4 --- /dev/null +++ b/tests/templateTest.expected_results @@ -0,0 +1,8 @@ +a: 5 +b: 7 +1337 +a: 9 +b: Hello Templates! +Woooo nesting! +From another file! Whoh! +1919 diff --git a/tests/templateTest.krak b/tests/templateTest.krak new file mode 100644 index 0000000..a755ce2 --- /dev/null +++ b/tests/templateTest.krak @@ -0,0 +1,52 @@ +import io; +import trivial_container; + +typedef template TemplateTest { + int a; + T b; + trivialContainer c; + void print() { + print("a: "); + print(a); + print("\n"); + print("b: "); + print(b); + print("\n"); + c.print(); + print("\n"); + } +}; + +typedef MyInt int; + +MyInt c; + + +template T addAndPrint(T a, T b) { + print(a+b); + return a+b; +} + +int main() { + TemplateTest test; + TemplateTest test2; + test.a = 5; + test.b = 7; + test.c.data = 1337; + test2.a = 9; + test2.b = "Hello Templates!"; + test2.c.data = "Woooo nesting!"; + + test.print(); + test2.print(); + + trivialContainer testImport; + testImport.data = "From another file! Whoh!"; + testImport.print(); + print("\n"); + + print(addAndPrint(7,12)); + print("\n"); + + return 0; +} \ No newline at end of file diff --git a/tests/testArrayNotation.expected_results b/tests/testArrayNotation.expected_results new file mode 100644 index 0000000..6e68a0f --- /dev/null +++ b/tests/testArrayNotation.expected_results @@ -0,0 +1 @@ +777 diff --git a/tests/testArrayNotation.krak b/tests/testArrayNotation.krak new file mode 100644 index 0000000..9d4a0d9 --- /dev/null +++ b/tests/testArrayNotation.krak @@ -0,0 +1,13 @@ +import io; +import mem; + +int main() { + int b; + int* a = &b; + a [ 0 ] = 7; + print(a [ 0 ] ); + print(*a); + print(b); + print("\n"); + return 0; +}