diff --git a/src/eval-special-form.cpp b/src/eval-special-form.cpp index ac4e186..eab1057 100644 --- a/src/eval-special-form.cpp +++ b/src/eval-special-form.cpp @@ -30,8 +30,8 @@ ValuePtr Eval::evalDef(const ValueVector& nodes, EnvironmentPtr env) VALUE_CAST(symbol, Symbol, nodes.front()); // Eval second argument - m_ast_stack.push(*std::next(nodes.begin())); - m_env_stack.push(env); + m_ast = *std::next(nodes.begin()); + m_env = env; ValuePtr value = evalImpl(); // Dont overwrite symbols after an error @@ -52,8 +52,8 @@ ValuePtr Eval::evalDefMacro(const ValueVector& nodes, EnvironmentPtr env) VALUE_CAST(symbol, Symbol, nodes.front()); // Eval second argument - m_ast_stack.push(*std::next(nodes.begin())); - m_env_stack.push(env); + m_ast = *std::next(nodes.begin()); + m_env = env; ValuePtr value = evalImpl(); VALUE_CAST(lambda, Lambda, value); @@ -118,14 +118,14 @@ void Eval::evalDo(const ValueVector& nodes, EnvironmentPtr env) // Evaluate all nodes except the last for (auto it = nodes.begin(); it != std::prev(nodes.end(), 1); ++it) { - m_ast_stack.push(*it); - m_env_stack.push(env); + m_ast = *it; + m_env = env; evalImpl(); } // Eval last node - m_ast_stack.push(nodes.back()); - m_env_stack.push(env); + m_ast = nodes.back(); + m_env = env; return; // TCO } @@ -138,18 +138,18 @@ void Eval::evalIf(const ValueVector& nodes, EnvironmentPtr env) auto second_argument = *std::next(nodes.begin()); auto third_argument = (nodes.size() == 3) ? *std::next(std::next(nodes.begin())) : makePtr(Constant::Nil); - m_ast_stack.push(first_argument); - m_env_stack.push(env); + m_ast = first_argument; + m_env = env; auto first_evaluated = evalImpl(); if (!is(first_evaluated.get()) || std::static_pointer_cast(first_evaluated)->state() == Constant::True) { - m_ast_stack.push(second_argument); - m_env_stack.push(env); + m_ast = second_argument; + m_env = env; return; // TCO } - m_ast_stack.push(third_argument); - m_env_stack.push(env); + m_ast = third_argument; + m_env = env; return; // TCO } @@ -173,16 +173,16 @@ void Eval::evalLet(const ValueVector& nodes, EnvironmentPtr env) VALUE_CAST(elt, Symbol, (*it), void()); std::string key = elt->symbol(); - m_ast_stack.push(*std::next(it)); - m_env_stack.push(let_env); + m_ast = *std::next(it); + m_env = let_env; ValuePtr value = evalImpl(); let_env->set(key, value); } // TODO: Remove limitation of 3 arguments // Eval all arguments in this new env, return last sexp of the result - m_ast_stack.push(*std::next(nodes.begin())); - m_env_stack.push(let_env); + m_ast = *std::next(nodes.begin()); + m_env = let_env; return; // TCO } @@ -277,8 +277,8 @@ void Eval::evalQuasiQuote(const ValueVector& nodes, EnvironmentPtr env) auto result = evalQuasiQuoteImpl(nodes.front()); - m_ast_stack.push(result); - m_env_stack.push(env); + m_ast = result; + m_env = env; return; // TCO } @@ -288,8 +288,8 @@ void Eval::evalTry(const ValueVector& nodes, EnvironmentPtr env) CHECK_ARG_COUNT_AT_LEAST("try*", nodes.size(), 1, void()); // Try 'x' - m_ast_stack.push(nodes.front()); - m_env_stack.push(env); + m_ast = nodes.front(); + m_env = env; auto result = evalImpl(); // Catch @@ -317,13 +317,13 @@ void Eval::evalTry(const ValueVector& nodes, EnvironmentPtr env) catch_env->set(catch_binding->symbol(), error); // Evaluate 'z' using the new Environment - m_ast_stack.push(catch_nodes.back()); - m_env_stack.push(catch_env); + m_ast = catch_nodes.back(); + m_env = catch_env; return; // TCO } - m_ast_stack.push(result); - m_env_stack.push(env); + m_ast = result; + m_env = env; return; // TCO } diff --git a/src/eval.cpp b/src/eval.cpp index cd59b9b..2919bde 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -23,6 +23,7 @@ namespace blaze { Eval::Eval(ValuePtr ast, EnvironmentPtr env) : m_ast(ast) , m_env(env) + , m_outer_env(env) { } @@ -30,11 +31,6 @@ Eval::Eval(ValuePtr ast, EnvironmentPtr env) void Eval::eval() { - m_ast_stack = std::stack(); - m_env_stack = std::stack(); - m_ast_stack.push(m_ast); - m_env_stack.push(m_env); - m_ast = evalImpl(); } @@ -48,20 +44,13 @@ ValuePtr Eval::evalImpl() return nullptr; } - if (m_ast_stack.size() == 0) { - return nullptr; - } + ast = m_ast; + env = m_env; - if (m_env_stack.size() == 0) { - m_env_stack.push(m_env); + if (env == nullptr) { + env = m_outer_env; } - ast = m_ast_stack.top(); - env = m_env_stack.top(); - - m_ast_stack.pop(); - m_env_stack.pop(); - if (!is(ast.get())) { return evalAst(ast, env); } @@ -133,8 +122,8 @@ ValuePtr Eval::evalImpl() if (is(evaluated_list->front().get())) { auto lambda = std::static_pointer_cast(evaluated_list->front()); - m_ast_stack.push(lambda->body()); - m_env_stack.push(Environment::create(lambda, evaluated_list->rest())); + m_ast = lambda->body(); + m_env = Environment::create(lambda, evaluated_list->rest()); continue; // TCO } @@ -165,8 +154,8 @@ ValuePtr Eval::evalAst(ValuePtr ast, EnvironmentPtr env) auto evaluated_nodes = ValueVector(count); for (size_t i = 0; i < count; ++i) { - m_ast_stack.push(nodes[i]); - m_env_stack.push(env); + m_ast = nodes[i]; + m_env = env; ValuePtr eval_node = evalImpl(); if (eval_node == nullptr) { return nullptr; @@ -184,8 +173,8 @@ ValuePtr Eval::evalAst(ValuePtr ast, EnvironmentPtr env) const auto& elements = std::static_pointer_cast(ast)->elements(); Elements evaluated_elements; for (const auto& element : elements) { - m_ast_stack.push(element.second); - m_env_stack.push(env); + m_ast = element.second; + m_env = env; ValuePtr element_node = evalImpl(); if (element_node == nullptr) { return nullptr; @@ -231,11 +220,12 @@ ValuePtr Eval::macroExpand(ValuePtr ast, EnvironmentPtr env) { while (isMacroCall(ast, env)) { auto list = std::static_pointer_cast(ast); + auto value = env->get(std::static_pointer_cast(list->front())->symbol()); auto lambda = std::static_pointer_cast(value); - m_ast_stack.push(lambda->body()); - m_env_stack.push(Environment::create(lambda, list->rest())); + m_ast = lambda->body(); + m_env = Environment::create(lambda, list->rest()); ast = evalImpl(); } diff --git a/src/eval.h b/src/eval.h index 6acb657..a39835f 100644 --- a/src/eval.h +++ b/src/eval.h @@ -48,9 +48,7 @@ private: ValuePtr m_ast; EnvironmentPtr m_env; - - std::stack m_ast_stack; - std::stack m_env_stack; + EnvironmentPtr m_outer_env; }; } // namespace blaze diff --git a/src/functions.cpp b/src/functions.cpp index 1feb0a5..0cc90d0 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -518,7 +518,7 @@ ADD_FUNCTION( return makePtr(collection->rest()); }); -// (apply + 1 2 (list 3 4)) -> (+ 1 2 3 4) +// (apply + 1 2 (list 3 4)) -> (+ 1 2 3 4) -> 10 ADD_FUNCTION( "apply", { @@ -984,8 +984,8 @@ ADD_FUNCTION( void installFunctions(EnvironmentPtr env) { - for (const auto& [name, lambda] : s_functions) { - env->set(name, makePtr(name, lambda)); + for (const auto& [name, function] : s_functions) { + env->set(name, makePtr(name, function)); } }