Skip to content

Commit 018475b

Browse files
authored
Fix macro. (#19)
Co-authored-by: Bowen Fu <missing>
1 parent 0e3804b commit 018475b

File tree

4 files changed

+23
-12
lines changed

4 files changed

+23
-12
lines changed

include/lisp/evaluator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class Env
5656
auto iter = mFrame.find(variableName);
5757
if (iter == mFrame.end())
5858
{
59-
throw std::runtime_error{"call setVariableValue to undefined variables."};
59+
throw std::runtime_error{"call setVariableValue to undefined variables." + variableName};
6060
}
6161
iter->second = value;
6262
return value;
@@ -73,7 +73,7 @@ class Env
7373
{
7474
if (mFrame.count(variableName))
7575
{
76-
throw std::runtime_error{"call defineVariable to defined variables."};
76+
throw std::runtime_error{"call defineVariable to defined variables." + variableName};
7777
}
7878
mFrame.insert({variableName, value});
7979
return value;

include/lisp/parser.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,16 @@ inline ExprPtr application(ExprPtr const& car, ExprPtr const& cdr)
230230
return ExprPtr{new Application(op, params)};
231231
}
232232

233-
inline ExprPtr macroApplication(ExprPtr const& car, ExprPtr const& cdr)
233+
inline ExprPtr tryMacroApplication(ExprPtr const& car, ExprPtr const& cdr, std::shared_ptr<Env> const& env)
234234
{
235235
auto op = parse(car);
236-
std::vector<ExprPtr> params = consToVec(cdr);
237-
return ExprPtr{new Application(op, params)};
236+
auto evaledOp = op->eval(env);
237+
if (dynamic_cast<MacroProcedure const*>(evaledOp.get()))
238+
{
239+
std::vector<ExprPtr> params = consToVec(cdr);
240+
return Application(evaledOp, params).eval(env);
241+
}
242+
return ExprPtr{new Cons{car, cdr}};
238243
}
239244

240245
inline ExprPtr application(ExprPtr const& expr)
@@ -359,7 +364,7 @@ inline auto tryMacroCall(ExprPtr const& expr, std::shared_ptr<Env> const& env) -
359364
}
360365
if (env->variableDefined(carStr.value()))
361366
{
362-
return macroApplication(car, cdr)->eval(env);
367+
return tryMacroApplication(car, cdr, env);
363368
}
364369
return expr;
365370
}
@@ -472,16 +477,18 @@ void forEach(ExprPtr const& expr, Func func)
472477
func(expr);
473478
}
474479

475-
inline void defineMacros(ExprPtr const& expr, std::shared_ptr<Env> const& env)
480+
inline auto defineMacros(ExprPtr const& expr, std::shared_ptr<Env> const& env) -> ExprPtr
476481
{
477482
auto func = [&env](auto const& expr)
478483
{
479484
if (auto macroDefinition = parseMacroDefinition(expr))
480485
{
481486
macroDefinition->eval(env);
487+
return nil();
482488
}
489+
return expr;
483490
};
484-
forEach(expr, func);
491+
return transform(expr, func);
485492
}
486493

487494
// FIXME

sample/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,7 @@ do_test(test_macro_negate_add "(define negate (macro (x) `(- ,x))) (negate (+ 1
135135
do_test(test_macro_double "(define double (macro (x) `(* ,x 2))) (double (+ 1 1))" "4")
136136

137137
do_test(test_macro_show "(define show (macro (x) `(list ',x))) (show (+ 1 1))" "\\\\(\\\\'\\\\+ 1 1\\\\)")
138-
do_test(test_macro_first "(define first (macro (x) `(car ',x))) (first (+ 1 1))" "'+")
138+
do_test(test_macro_first "(define first (macro (x) `(car ',x))) (first (+ 1 1))" "'+")
139+
do_test(test_macro_first "(define rest (macro (x) `(cdr ',x))) (rest (+ 1 1))" "(1 1)")
140+
141+
do_test(test_macro_first "(define replaceOp (macro (orig op) `(,op . ,(cdr orig)))) (replaceOp (+ 3 3) *)" "9")

sample/loop.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,13 @@ auto eval(std::string const& input, std::shared_ptr<Env> const& env)
147147
Lexer lex(input);
148148
MetaParser p(lex);
149149
std::string result;
150-
auto macroEnv = std::make_shared<Env>();
150+
// auto macroEnv = std::make_shared<Env>();
151+
auto macroEnv = env;
151152
do
152153
{
153154
auto me = p.sexpr();
154-
defineMacros(me, macroEnv);
155-
auto ee = expandMacros(me, macroEnv);
155+
auto de = defineMacros(me, macroEnv);
156+
auto ee = expandMacros(de, macroEnv);
156157
#if DEBUG
157158
std::cout << "ee ## " << ee->toString() << std::endl;
158159
#endif // DEBUG

0 commit comments

Comments
 (0)