Browse Source

Eval: Change (macroexpand) into (macroexpand-1)

master
Riyyi 1 year ago
parent
commit
1915621427
  1. 56
      src/eval-special-form.cpp
  2. 51
      src/eval.cpp
  3. 5
      src/eval.h

56
src/eval-special-form.cpp

@ -88,12 +88,7 @@ ValuePtr Eval::evalFn(const ValueVector& nodes, EnvironmentPtr env)
return makePtr<Lambda>(bindings, *std::next(nodes.begin()), env); return makePtr<Lambda>(bindings, *std::next(nodes.begin()), env);
} }
ValuePtr Eval::evalMacroExpand(const ValueVector& nodes, EnvironmentPtr env) // -----------------------------------------
{
CHECK_ARG_COUNT_IS("macroexpand", nodes.size(), 1);
return macroExpand(nodes.front(), env);
}
// (quasiquoteexpand x) // (quasiquoteexpand x)
ValuePtr Eval::evalQuasiQuoteExpand(const ValueVector& nodes) ValuePtr Eval::evalQuasiQuoteExpand(const ValueVector& nodes)
@ -237,6 +232,53 @@ void Eval::evalLet(const ValueVector& nodes, EnvironmentPtr env)
// ----------------------------------------- // -----------------------------------------
// (x y z)
static bool isMacroCall(ValuePtr ast, EnvironmentPtr env)
{
auto list = dynamic_cast<List*>(ast.get());
if (list == nullptr || list->empty()) {
return false;
}
auto front = list->front().get();
if (!is<Symbol>(front)) {
return false;
}
auto symbol = dynamic_cast<Symbol*>(front)->symbol();
auto value = env->get(symbol).get();
if (!is<Macro>(value)) {
return false;
}
return true;
}
void Eval::evalMacroExpand1(const ValueVector& nodes, EnvironmentPtr env)
{
CHECK_ARG_COUNT_IS("macroexpand-1", nodes.size(), 1, void());
if (!isMacroCall(nodes.front(), env)) {
m_ast = nodes.front();
m_env = env;
return;
}
auto list = std::static_pointer_cast<List>(nodes.front());
auto value = env->get(std::static_pointer_cast<Symbol>(list->front())->symbol());
auto lambda = std::static_pointer_cast<Lambda>(value);
m_ast = lambda->body();
m_env = Environment::create(lambda, list->rest());
return; // TCO
}
// -----------------------------------------
static bool isSymbol(ValuePtr value, const std::string& symbol) static bool isSymbol(ValuePtr value, const std::string& symbol)
{ {
if (!is<Symbol>(value.get())) { if (!is<Symbol>(value.get())) {
@ -331,6 +373,8 @@ void Eval::evalQuasiQuote(const ValueVector& nodes, EnvironmentPtr env)
return; // TCO return; // TCO
} }
// -----------------------------------------
// (while true body...) // (while true body...)
void Eval::evalWhile(const ValueVector& nodes, EnvironmentPtr env) void Eval::evalWhile(const ValueVector& nodes, EnvironmentPtr env)
{ {

51
src/eval.cpp

@ -83,9 +83,6 @@ ValuePtr Eval::evalImpl()
if (symbol == "fn*") { if (symbol == "fn*") {
return evalFn(nodes, env); return evalFn(nodes, env);
} }
if (symbol == "macroexpand") {
return evalMacroExpand(nodes, env);
}
if (symbol == "quasiquoteexpand") { if (symbol == "quasiquoteexpand") {
return evalQuasiQuoteExpand(nodes); return evalQuasiQuoteExpand(nodes);
} }
@ -108,6 +105,10 @@ ValuePtr Eval::evalImpl()
evalLet(nodes, env); evalLet(nodes, env);
continue; // TCO continue; // TCO
} }
if (symbol == "macroexpand-1") {
evalMacroExpand1(nodes, env);
continue; // TCO
}
if (symbol == "quasiquote") { if (symbol == "quasiquote") {
evalQuasiQuote(nodes, env); evalQuasiQuote(nodes, env);
continue; // TCO continue; // TCO
@ -202,50 +203,6 @@ ValuePtr Eval::evalHashMap(ValuePtr ast, EnvironmentPtr env)
// ----------------------------------------- // -----------------------------------------
// (x y z)
bool Eval::isMacroCall(ValuePtr ast, EnvironmentPtr env)
{
auto list = dynamic_cast<List*>(ast.get());
if (list == nullptr || list->empty()) {
return false;
}
auto front = list->front().get();
if (!is<Symbol>(front)) {
return false;
}
auto symbol = dynamic_cast<Symbol*>(front)->symbol();
auto value = env->get(symbol).get();
if (!is<Macro>(value)) {
return false;
}
return true;
}
// (x y z)
ValuePtr Eval::macroExpand(ValuePtr ast, EnvironmentPtr env)
{
while (isMacroCall(ast, env)) {
auto list = std::static_pointer_cast<List>(ast);
auto value = env->get(std::static_pointer_cast<Symbol>(list->front())->symbol());
auto lambda = std::static_pointer_cast<Lambda>(value);
m_ast = lambda->body();
m_env = Environment::create(lambda, list->rest());
ast = evalImpl();
}
return ast;
}
// -----------------------------------------
ValuePtr Eval::apply(ValuePtr function, const ValueVector& nodes) ValuePtr Eval::apply(ValuePtr function, const ValueVector& nodes)
{ {
if (!is<Function>(function.get())) { if (!is<Function>(function.get())) {

5
src/eval.h

@ -31,13 +31,9 @@ private:
ValuePtr evalVector(ValuePtr ast, EnvironmentPtr env); ValuePtr evalVector(ValuePtr ast, EnvironmentPtr env);
ValuePtr evalHashMap(ValuePtr ast, EnvironmentPtr env); ValuePtr evalHashMap(ValuePtr ast, EnvironmentPtr env);
bool isMacroCall(ValuePtr ast, EnvironmentPtr env);
ValuePtr macroExpand(ValuePtr ast, EnvironmentPtr env);
ValuePtr evalDef(const ValueVector& nodes, EnvironmentPtr env); ValuePtr evalDef(const ValueVector& nodes, EnvironmentPtr env);
ValuePtr evalDefMacro(const ValueVector& nodes, EnvironmentPtr env); ValuePtr evalDefMacro(const ValueVector& nodes, EnvironmentPtr env);
ValuePtr evalFn(const ValueVector& nodes, EnvironmentPtr env); ValuePtr evalFn(const ValueVector& nodes, EnvironmentPtr env);
ValuePtr evalMacroExpand(const ValueVector& nodes, EnvironmentPtr env);
ValuePtr evalQuasiQuoteExpand(const ValueVector& nodes); ValuePtr evalQuasiQuoteExpand(const ValueVector& nodes);
ValuePtr evalQuote(const ValueVector& nodes); ValuePtr evalQuote(const ValueVector& nodes);
ValuePtr evalTry(const ValueVector& nodes, EnvironmentPtr env); ValuePtr evalTry(const ValueVector& nodes, EnvironmentPtr env);
@ -45,6 +41,7 @@ private:
void evalDo(const ValueVector& nodes, EnvironmentPtr env); void evalDo(const ValueVector& nodes, EnvironmentPtr env);
void evalIf(const ValueVector& nodes, EnvironmentPtr env); void evalIf(const ValueVector& nodes, EnvironmentPtr env);
void evalLet(const ValueVector& nodes, EnvironmentPtr env); void evalLet(const ValueVector& nodes, EnvironmentPtr env);
void evalMacroExpand1(const ValueVector& nodes, EnvironmentPtr env);
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);

Loading…
Cancel
Save