Eval: Add special form "do"
This commit is contained in:
+20
-1
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user