Eval: Change (macroexpand) into (macroexpand-1)
This commit is contained in:
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-47
@@ -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())) {
|
||||||
|
|||||||
+1
-4
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user