diff --git a/src/eval.cpp b/src/eval.cpp index 8cd81f9..cb151f4 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: MIT */ -#include // sd::advance, std::next +#include // sd::advance, std::next, std::prev #include #include // std::static_pointer_cast #include // std::span @@ -57,6 +57,9 @@ ASTNodePtr Eval::evalImpl(ASTNodePtr ast, EnvironmentPtr env) if (symbol == "let*") { return evalLet(nodes, env); } + if (symbol == "do") { + return evalDo(nodes, env); + } } // Function call @@ -200,6 +203,22 @@ ASTNodePtr Eval::evalLet(const std::list& nodes, EnvironmentPtr env) return evalImpl(second_argument, let_env); } +ASTNodePtr Eval::evalDo(const std::list& nodes, EnvironmentPtr env) +{ + if (nodes.size() == 0) { + Error::the().addError(format("wrong number of arguments: do, {}", nodes.size())); + return nullptr; + } + + // Evaluate all nodes except the last + for (auto it = nodes.begin(); it != std::prev(nodes.end(), 1); ++it) { + evalImpl(*it, env); + } + + // Eval and return last node + return evalImpl(nodes.back(), env); +} + ASTNodePtr Eval::apply(std::shared_ptr evaluated_list) { if (evaluated_list == nullptr) { diff --git a/src/eval.h b/src/eval.h index 350dbdd..64a3ee7 100644 --- a/src/eval.h +++ b/src/eval.h @@ -27,6 +27,7 @@ private: ASTNodePtr evalAst(ASTNodePtr ast, EnvironmentPtr env); ASTNodePtr evalDef(const std::list& nodes, EnvironmentPtr env); ASTNodePtr evalLet(const std::list& nodes, EnvironmentPtr env); + ASTNodePtr evalDo(const std::list& nodes, EnvironmentPtr env); ASTNodePtr apply(std::shared_ptr evaluated_list); ASTNodePtr m_ast;