From 7c75a90627ff937981566f51257199c42956eb0b Mon Sep 17 00:00:00 2001 From: Michael Bozhilov Date: Wed, 15 Nov 2023 18:53:22 +0200 Subject: [PATCH] Add initial interpreting logic for return statements --- nulascript/eval/eval.cc | 12 +++++++++++- nulascript/storage/storage.cc | 6 ++++++ nulascript/storage/storage.h | 19 ++++++++++++------- nulascript/tests/eval_test.cc | 14 ++++++++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/nulascript/eval/eval.cc b/nulascript/eval/eval.cc index a5f8cdc..bbf9fa7 100644 --- a/nulascript/eval/eval.cc +++ b/nulascript/eval/eval.cc @@ -111,7 +111,8 @@ Storage* evaluateIf(Conditional* expression) { return nilStorage; } -bool checkBase(Node* passed, const std::type_info& expected) { +template +bool checkBase(T* passed, const std::type_info& expected) { return typeid(*passed) == expected; } @@ -143,6 +144,10 @@ Storage* evaluate(Node* node) { } else if (checkBase(node, typeid(Conditional))) { auto conditional = dynamic_cast(node); return evaluateIf(conditional); + } else if (checkBase(node, typeid(ReturnStatement))) { + auto statement = dynamic_cast(node); + auto result = evaluate(statement->returnValue); + return new ReturnStorage(result); } return nilStorage; @@ -153,6 +158,11 @@ Storage* evaluateSequence(std::vector statements) { for (auto statement : statements) { result = evaluate(statement); + + if (checkBase(result, typeid(ReturnStorage))) { + auto returnVal = dynamic_cast(result); + return returnVal->value; + } } return result; diff --git a/nulascript/storage/storage.cc b/nulascript/storage/storage.cc index f766ef2..77f2c91 100644 --- a/nulascript/storage/storage.cc +++ b/nulascript/storage/storage.cc @@ -19,3 +19,9 @@ NilStorage::NilStorage() {} StorageType NilStorage::getType() const { return StorageType::NIL; } std::string NilStorage::evaluate() const { return "nil"; } + +ReturnStorage::ReturnStorage(Storage* value) : value(value){}; + +StorageType ReturnStorage::getType() const { return StorageType::RETURN; } + +std::string ReturnStorage::evaluate() const { return value->evaluate(); } \ No newline at end of file diff --git a/nulascript/storage/storage.h b/nulascript/storage/storage.h index 1229aae..f619dd6 100644 --- a/nulascript/storage/storage.h +++ b/nulascript/storage/storage.h @@ -6,7 +6,7 @@ #include #include -enum class StorageType { INTEGER, BOOLEAN, NIL }; +enum class StorageType { INTEGER, BOOLEAN, NIL, RETURN }; class Storage { public: @@ -18,10 +18,9 @@ class IntegerStorage : public Storage { public: int64_t value; - // Constructor + public: IntegerStorage(int64_t value); - // Overrides StorageType getType() const override; std::string evaluate() const override; }; @@ -30,20 +29,26 @@ class BooleanStorage : public Storage { public: bool value; - // Constructor + public: BooleanStorage(bool value); - // Overrides StorageType getType() const override; std::string evaluate() const override; }; class NilStorage : public Storage { public: - // Constructor NilStorage(); + StorageType getType() const override; + std::string evaluate() const override; +}; + +class ReturnStorage : public Storage { + public: + Storage* value; - // Overrides + public: + ReturnStorage(Storage* value); StorageType getType() const override; std::string evaluate() const override; }; diff --git a/nulascript/tests/eval_test.cc b/nulascript/tests/eval_test.cc index fd06d1a..2e6a1e6 100644 --- a/nulascript/tests/eval_test.cc +++ b/nulascript/tests/eval_test.cc @@ -61,6 +61,20 @@ TEST(EvalSuite, TestIfStatement) { std::vector tests = {{"if (true) { 69 }", "69"}, {"if (false) { 69 }", "nil"}}; + for (auto test : tests) { + auto result = getEvaluatedStorage(test.input); + ASSERT_EQ(result->evaluate(), test.expected); + } +} + +TEST(EvalSuite, TestReturn) { + struct Test { + std::string input; + std::string expected; + }; + + std::vector tests = {{"return 69", "69"}}; + for (auto test : tests) { auto result = getEvaluatedStorage(test.input); ASSERT_EQ(result->evaluate(), test.expected);