Browse Source

Eval: Merge eval, eval-ast and macroexpand

master
Riyyi 1 year ago
parent
commit
67b982fd4c
  1. 141
      src/eval.cpp
  2. 6
      src/eval.h

141
src/eval.cpp

@ -39,6 +39,10 @@ ValuePtr Eval::evalImpl()
ValuePtr ast = nullptr; ValuePtr ast = nullptr;
EnvironmentPtr env = nullptr; EnvironmentPtr env = nullptr;
if (env == nullptr) {
env = m_outer_env;
}
while (true) { while (true) {
if (Error::the().hasAnyError()) { if (Error::the().hasAnyError()) {
return nullptr; return nullptr;
@ -47,18 +51,17 @@ ValuePtr Eval::evalImpl()
ast = m_ast; ast = m_ast;
env = m_env; env = m_env;
if (env == nullptr) { if (is<Symbol>(ast.get())) {
env = m_outer_env; return evalSymbol(ast, env);
} }
if (is<Vector>(ast.get())) {
if (!is<List>(ast.get())) { return evalVector(ast, env);
return evalAst(ast, env); }
if (is<HashMap>(ast.get())) {
return evalHashMap(ast, env);
} }
ast = macroExpand(ast, env);
if (!is<List>(ast.get())) { if (!is<List>(ast.get())) {
return evalAst(ast, env); return ast;
} }
auto list = std::static_pointer_cast<List>(ast); auto list = std::static_pointer_cast<List>(ast);
@ -115,80 +118,86 @@ ValuePtr Eval::evalImpl()
} }
} }
auto evaluated_list = std::static_pointer_cast<List>(evalAst(ast, env)); m_ast = list->front();
m_env = env;
auto evaluated_front = evalImpl();
auto unevaluated_nodes = list->rest();
if (evaluated_list == nullptr) { if (is<Macro>(evaluated_front.get())) { // FIXME
return nullptr; auto lambda = std::static_pointer_cast<Lambda>(evaluated_front);
m_ast = lambda->body();
m_env = Environment::create(lambda, std::move(unevaluated_nodes));
m_ast = evalImpl();
m_env = env;
continue; // TCO
}
ValueVector evaluated_nodes(unevaluated_nodes.size());
for (size_t i = 0; i < unevaluated_nodes.size(); ++i) {
m_ast = unevaluated_nodes[i];
m_env = env;
evaluated_nodes[i] = evalImpl();
} }
// Regular list // Regular list
if (is<Lambda>(evaluated_list->front().get())) { if (is<Lambda>(evaluated_front.get())) {
auto lambda = std::static_pointer_cast<Lambda>(evaluated_list->front()); auto lambda = std::static_pointer_cast<Lambda>(evaluated_front);
m_ast = lambda->body(); m_ast = lambda->body();
m_env = Environment::create(lambda, evaluated_list->rest()); m_env = Environment::create(lambda, std::move(evaluated_nodes));
continue; // TCO continue; // TCO
} }
// Function call // Function call
return apply(evaluated_list); return apply(evaluated_front, evaluated_nodes);
} }
} }
ValuePtr Eval::evalAst(ValuePtr ast, EnvironmentPtr env) ValuePtr Eval::evalSymbol(ValuePtr ast, EnvironmentPtr env)
{ {
if (ast == nullptr || env == nullptr) { auto result = env->get(std::static_pointer_cast<Symbol>(ast)->symbol());
if (!result) {
Error::the().add(::format("'{}' not found", ast));
return nullptr; return nullptr;
} }
Value* ast_raw_ptr = ast.get(); return result;
if (is<Symbol>(ast_raw_ptr)) { }
auto result = env->get(std::static_pointer_cast<Symbol>(ast)->symbol());
if (!result) { ValuePtr Eval::evalVector(ValuePtr ast, EnvironmentPtr env)
Error::the().add(::format("'{}' not found", ast)); {
const auto& nodes = std::static_pointer_cast<Collection>(ast)->nodesRead();
size_t count = nodes.size();
auto evaluated_nodes = ValueVector(count);
for (size_t i = 0; i < count; ++i) {
m_ast = nodes[i];
m_env = env;
ValuePtr eval_node = evalImpl();
if (eval_node == nullptr) {
return nullptr; return nullptr;
} }
evaluated_nodes.at(i) = eval_node;
return result;
} }
else if (is<Collection>(ast_raw_ptr)) {
const auto& nodes = std::static_pointer_cast<Collection>(ast)->nodesRead();
size_t count = nodes.size();
auto evaluated_nodes = ValueVector(count);
for (size_t i = 0; i < count; ++i) {
m_ast = nodes[i];
m_env = env;
ValuePtr eval_node = evalImpl();
if (eval_node == nullptr) {
return nullptr;
}
evaluated_nodes.at(i) = eval_node;
}
if (is<Vector>(ast_raw_ptr)) { return makePtr<Vector>(evaluated_nodes);
return makePtr<Vector>(evaluated_nodes); }
}
return makePtr<List>(evaluated_nodes); ValuePtr Eval::evalHashMap(ValuePtr ast, EnvironmentPtr env)
} {
else if (is<HashMap>(ast_raw_ptr)) { const auto& elements = std::static_pointer_cast<HashMap>(ast)->elements();
const auto& elements = std::static_pointer_cast<HashMap>(ast)->elements(); Elements evaluated_elements;
Elements evaluated_elements; for (const auto& element : elements) {
for (const auto& element : elements) { m_ast = element.second;
m_ast = element.second; m_env = env;
m_env = env; ValuePtr element_node = evalImpl();
ValuePtr element_node = evalImpl(); if (element_node == nullptr) {
if (element_node == nullptr) { return nullptr;
return nullptr;
}
evaluated_elements.insert_or_assign(element.first, element_node);
} }
evaluated_elements.insert_or_assign(element.first, element_node);
return makePtr<HashMap>(evaluated_elements);
} }
return ast; return makePtr<HashMap>(evaluated_elements);
} }
// ----------------------------------------- // -----------------------------------------
@ -237,22 +246,16 @@ ValuePtr Eval::macroExpand(ValuePtr ast, EnvironmentPtr env)
// ----------------------------------------- // -----------------------------------------
ValuePtr Eval::apply(std::shared_ptr<List> evaluated_list) ValuePtr Eval::apply(ValuePtr function, const ValueVector& nodes)
{ {
if (evaluated_list == nullptr) { if (!is<Function>(function.get())) {
return nullptr; Error::the().add(::format("invalid function: {}", function));
}
auto front = evaluated_list->front();
if (!is<Function>(front.get())) {
Error::the().add(::format("invalid function: {}", front));
return nullptr; return nullptr;
} }
auto function = std::static_pointer_cast<Function>(front)->function(); auto func = std::static_pointer_cast<Function>(function)->function();
return function(evaluated_list->begin() + 1, evaluated_list->end()); return func(nodes.begin(), nodes.end());
} }
} // namespace blaze } // namespace blaze

6
src/eval.h

@ -27,7 +27,9 @@ public:
private: private:
ValuePtr evalImpl(); ValuePtr evalImpl();
ValuePtr evalAst(ValuePtr ast, EnvironmentPtr env); ValuePtr evalSymbol(ValuePtr ast, EnvironmentPtr env);
ValuePtr evalVector(ValuePtr ast, EnvironmentPtr env);
ValuePtr evalHashMap(ValuePtr ast, EnvironmentPtr env);
bool isMacroCall(ValuePtr ast, EnvironmentPtr env); bool isMacroCall(ValuePtr ast, EnvironmentPtr env);
ValuePtr macroExpand(ValuePtr ast, EnvironmentPtr env); ValuePtr macroExpand(ValuePtr ast, EnvironmentPtr env);
@ -46,7 +48,7 @@ private:
void evalQuasiQuote(const ValueVector& nodes, EnvironmentPtr env); void evalQuasiQuote(const ValueVector& nodes, EnvironmentPtr env);
void evalWhile(const ValueVector& nodes, EnvironmentPtr env); void evalWhile(const ValueVector& nodes, EnvironmentPtr env);
ValuePtr apply(std::shared_ptr<List> evaluated_list); ValuePtr apply(ValuePtr function, const ValueVector& nodes);
ValuePtr m_ast; ValuePtr m_ast;
EnvironmentPtr m_env; EnvironmentPtr m_env;

Loading…
Cancel
Save