diff --git a/CMakeLists.txt b/CMakeLists.txt index e73f25f..4e528d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,14 @@ set(TEST_FILES add_executable(OMGL src/main.cpp ${SOURCE_FILES}) -# add_executable(Test tests/MainTest.cpp ${TEST_FILES} ${SOURCE_FILES}) +add_executable(Test tests/MainTest.cpp ${TEST_FILES} ${SOURCE_FILES}) -# target_link_libraries(Test ${GTEST_LIBRARIES} Threads::Threads) +target_link_libraries(Test ${GTEST_LIBRARIES} Threads::Threads) + +add_custom_target(copy-files ALL + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_SOURCE_DIR}/tests/programs/ + ${CMAKE_BINARY_DIR}/programs + ) + +add_dependencies(Test copy-files) diff --git a/include/syntax_tree.hpp b/include/syntax_tree.hpp index 106354b..d83b636 100644 --- a/include/syntax_tree.hpp +++ b/include/syntax_tree.hpp @@ -10,6 +10,9 @@ struct Variable; struct VariableInStack; struct Expression; +void SetPrintStringStream(); +std::stringstream& GetPrintStringStream(); + struct Node { Node* parent = nullptr; Node* next = nullptr; diff --git a/src/main.cpp b/src/main.cpp index 0a5b4db..df7efca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "preprocessor.hpp" #include "lexer.hpp" #include "syntax_tree.hpp" @@ -12,7 +13,6 @@ int main(int argc, char* argv[]) { return 1; } std::ifstream fin(argv[1]); - { std::string str; while (getline(fin, str)) { diff --git a/src/syntax_tree.cpp b/src/syntax_tree.cpp index 185b372..f6122fe 100644 --- a/src/syntax_tree.cpp +++ b/src/syntax_tree.cpp @@ -2,10 +2,32 @@ #include #include #include +#include +#include #include "syntax_tree.hpp" using Type = Lexer::LexerToken::Type; +std::optional output_print; + +void SetPrintStringStream() { + output_print = std::stringstream(); +} + +std::stringstream& GetPrintStringStream() { + if (output_print) { + return *output_print; + } + throw std::logic_error("not string stream"); +} + +std::ostream& GetPrintOstream() { + if (output_print) { + return *output_print; + } + return std::cout; +} + bool IsOperation(Type type) { switch (type) { case Type::Equal: @@ -651,12 +673,12 @@ void CallFunction::Run(std::vector>& stack) { for (size_t i = 0; i < parameters.size(); ++i) { std::shared_ptr& t = *(stack.end() - parameters.size() + i); if (t->type_variable.id == TypeVariable::ID::type_int) { - std::cout << *((int*) t->memory) << " "; + GetPrintOstream() << *((int*) t->memory) << (i + 1 != parameters.size() ? " " : ""); } else if (t->type_variable.id == TypeVariable::ID::type_string) { - std::cout << *((std::string*) t->memory) << " "; + GetPrintOstream() << *((std::string*) t->memory) << (i + 1 != parameters.size() ? " " : ""); } } - std::cout << std::endl; + GetPrintOstream() << std::endl; } } diff --git a/tests/MainTest.cpp b/tests/MainTest.cpp index 83bd23c..99784e9 100644 --- a/tests/MainTest.cpp +++ b/tests/MainTest.cpp @@ -1,4 +1,46 @@ #include +#include +#include +#include "preprocessor.hpp" +#include "lexer.hpp" +#include "syntax_tree.hpp" + +std::string LoadFile(const std::string& file) { + std::string program; + std::ifstream fin(file); + { + std::string str; + while (getline(fin, str)) { + str.push_back('\n'); + program += str; + } + } + return program; +} + +void RunTest(const std::string& program_file, const std::string& result_file) { + std::string program = LoadFile(program_file); + program = Preprocessor(std::move(program)); + Lexer lexer; + lexer.ParseText(program); + auto tokens = lexer.GetTokens(); + SyntaxTree tree; + tree.PushLexerTokenList(tokens); + tree.Compile(); + + SetPrintStringStream(); + tree.Run(); + std::string result = LoadFile(result_file); + ASSERT_EQ(result, GetPrintStringStream().str()); +} + +TEST(test_int, full_test) { + RunTest("programs/int/1.omgpl", "programs/int/1.res"); +} + +TEST(test_string, full_test) { + RunTest("programs/string/1.omgpl", "programs/string/1.res"); +} int main() { testing::InitGoogleTest(); diff --git a/tests/programs/int/1.omgpl b/tests/programs/int/1.omgpl new file mode 100644 index 0000000..ca84f71 --- /dev/null +++ b/tests/programs/int/1.omgpl @@ -0,0 +1,13 @@ +int x = 0; +for (int i = 0; i < 10; i += 1) { + x += i; +} +print(x); +for (int i = 0; i < 10; i += 1) { + x -= i; +} +print(x); +for (int i = 0; i < 4; i += 1) { + x = (x + 1) * i; +} +print(x); \ No newline at end of file diff --git a/tests/programs/int/1.res b/tests/programs/int/1.res new file mode 100644 index 0000000..a60126d --- /dev/null +++ b/tests/programs/int/1.res @@ -0,0 +1,3 @@ +45 +0 +15 diff --git a/tests/programs/string/1.omgpl b/tests/programs/string/1.omgpl new file mode 100644 index 0000000..463fe6e --- /dev/null +++ b/tests/programs/string/1.omgpl @@ -0,0 +1,11 @@ +string s = ""; + +for (int i = 0; i < 10; i += 1) { + if ((i / 2) * 2 == i) { + s += "a"; + } + if ((i / 2) * 2 != i) { + s += "b"; + } +} +print(s); \ No newline at end of file diff --git a/tests/programs/string/1.res b/tests/programs/string/1.res new file mode 100644 index 0000000..160610a --- /dev/null +++ b/tests/programs/string/1.res @@ -0,0 +1 @@ +ababababab