Eval: Add special form "do"

This commit is contained in:
Riyyi
2023-03-28 22:22:03 +02:00
parent 35a32678d0
commit 38d8daa9d0
2 changed files with 21 additions and 1 deletions
+20 -1
View File
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#include <iterator> // sd::advance, std::next #include <iterator> // sd::advance, std::next, std::prev
#include <list> #include <list>
#include <memory> // std::static_pointer_cast #include <memory> // std::static_pointer_cast
#include <span> // std::span #include <span> // std::span
@@ -57,6 +57,9 @@ ASTNodePtr Eval::evalImpl(ASTNodePtr ast, EnvironmentPtr env)
if (symbol == "let*") { if (symbol == "let*") {
return evalLet(nodes, env); return evalLet(nodes, env);
} }
if (symbol == "do") {
return evalDo(nodes, env);
}
} }
// Function call // Function call
@@ -200,6 +203,22 @@ ASTNodePtr Eval::evalLet(const std::list<ASTNodePtr>& nodes, EnvironmentPtr env)
return evalImpl(second_argument, let_env); return evalImpl(second_argument, let_env);
} }
ASTNodePtr Eval::evalDo(const std::list<ASTNodePtr>& 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<List> evaluated_list) ASTNodePtr Eval::apply(std::shared_ptr<List> evaluated_list)
{ {
if (evaluated_list == nullptr) { if (evaluated_list == nullptr) {
+1
View File
@@ -27,6 +27,7 @@ private:
ASTNodePtr evalAst(ASTNodePtr ast, EnvironmentPtr env); ASTNodePtr evalAst(ASTNodePtr ast, EnvironmentPtr env);
ASTNodePtr evalDef(const std::list<ASTNodePtr>& nodes, EnvironmentPtr env); ASTNodePtr evalDef(const std::list<ASTNodePtr>& nodes, EnvironmentPtr env);
ASTNodePtr evalLet(const std::list<ASTNodePtr>& nodes, EnvironmentPtr env); ASTNodePtr evalLet(const std::list<ASTNodePtr>& nodes, EnvironmentPtr env);
ASTNodePtr evalDo(const std::list<ASTNodePtr>& nodes, EnvironmentPtr env);
ASTNodePtr apply(std::shared_ptr<List> evaluated_list); ASTNodePtr apply(std::shared_ptr<List> evaluated_list);
ASTNodePtr m_ast; ASTNodePtr m_ast;