Skip to content

Commit 47b58fe

Browse files
author
Bowen Fu
committed
Lambda recursive calls
1 parent 3e13185 commit 47b58fe

File tree

3 files changed

+71
-11
lines changed

3 files changed

+71
-11
lines changed

evaluator.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ ExprPtr Lambda::eval(Env& env)
66
return std::shared_ptr<Expr>(new CompoundProcedure(proc));
77
}
88

9+
ExprPtr Definition::eval(Env& env)
10+
{
11+
if (dynamic_cast<Lambda*>(mValue.get()))
12+
{
13+
return env.defineVariable(dynamic_cast<Variable*>(mVariable.get())->name(), mValue);
14+
}
15+
return env.defineVariable(dynamic_cast<Variable*>(mVariable.get())->name(), mValue->eval(env));
16+
}
17+
918
#if 0
1019
int32_t main()
1120
{

evaluator.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,7 @@ class Definition final : public Expr
162162
, mValue{value}
163163
{
164164
}
165-
ExprPtr eval(Env& env) override
166-
{
167-
return env.defineVariable(dynamic_cast<Variable*>(mVariable.get())->name(), mValue->eval(env));
168-
}
165+
ExprPtr eval(Env& env) override;
169166
std::string toString() const override
170167
{
171168
return "Definition ( " + mVariable->toString() + " : " + mValue->toString() + " )";
@@ -185,11 +182,19 @@ class If final : public Expr
185182
ExprPtr mConsequent;
186183
ExprPtr mAlternative;
187184
public:
185+
If(ExprPtr const& predicate, ExprPtr const& consequent, ExprPtr const& alternative)
186+
: mPredicate{predicate}
187+
, mConsequent{consequent}
188+
, mAlternative{alternative}
189+
{}
188190
ExprPtr eval(Env& env) override
189191
{
190192
return isTrue(mPredicate->eval(env)) ? mConsequent->eval(env) : mAlternative->eval(env);
191193
}
192-
std::string toString() const override;
194+
std::string toString() const override
195+
{
196+
return "(if " + mPredicate->toString() + " " + mConsequent->toString() + " " + mAlternative->toString() + ")";
197+
}
193198
};
194199

195200
class Sequence final : public Expr
@@ -314,7 +319,7 @@ class Application final : public Expr
314319
{}
315320
ExprPtr eval(Env& env) override
316321
{
317-
auto op = mOperator->eval(env);
322+
auto op = mOperator->eval(env)->eval(env);
318323
auto args = listOfValues(mOperands, env);
319324
return dynamic_cast<Procedure&>(*op).apply(args);
320325
}

parser.cpp

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ class Parser
146146
ExprPtr atomic()
147147
{
148148
assert(mLookAhead.type == TokenType::kWORD);
149-
if (isdigit(mLookAhead.text.front()))
149+
auto c = mLookAhead.text.front();
150+
if (isdigit(c) || (mLookAhead.text.size() > 1 && c == '-'))
150151
{
151152
return number();
152153
}
@@ -184,6 +185,10 @@ class Parser
184185
{
185186
return lambda();
186187
}
188+
else if (mLookAhead.text == "if")
189+
{
190+
return if_();
191+
}
187192
else
188193
{
189194
return application();
@@ -231,6 +236,14 @@ class Parser
231236
auto body = sequence();
232237
return ExprPtr{new Lambda(params, body)};
233238
}
239+
ExprPtr if_()
240+
{
241+
assert(match({TokenType::kWORD, "if"}));
242+
auto predicate = sexpr();
243+
auto consequent = sexpr();
244+
auto alternative = sexpr();
245+
return ExprPtr{new If(predicate, consequent, alternative)};
246+
}
234247
ExprPtr application()
235248
{
236249
auto op = sexpr();
@@ -249,15 +262,18 @@ class Parser
249262

250263
int32_t main()
251264
{
252-
Lexer lex("(define square (lambda (y) (* y y))) (square 7)");
265+
// Lexer lex("(define square (lambda (y) (* y y))) (square 7)");
266+
Lexer lex("(define factorial (lambda (y) (if (= y 0) 1 (* y (factorial (- y 1)))))) (factorial 5)");
253267
Parser p(lex);
254268

269+
#if 0
255270
auto t = lex.nextToken();
256271
while (t.type != TokenType::kEOF)
257272
{
258273
std::cout << t.text << std::endl;
259274
t = lex.nextToken();
260275
}
276+
#endif
261277

262278
Env env{};
263279

@@ -272,11 +288,41 @@ int32_t main()
272288
);
273289
return std::shared_ptr<Expr>(new Number(result));
274290
};
275-
auto mulOp = ExprPtr{new PrimitiveProcedure{mul}};
276-
auto variableMul = ExprPtr{new Variable{"*"}};
277-
auto defMul = Definition(variableMul, mulOp);
291+
auto defMul = Definition(ExprPtr{new Variable{"*"}}, ExprPtr{new PrimitiveProcedure{mul}});
278292
defMul.eval(env);
279293

294+
auto gt = [](std::vector<std::shared_ptr<Expr>> const& args)
295+
{
296+
assert(args.size() == 2);
297+
auto num1 = dynamic_cast<Number&>(*args.at(0));
298+
auto num2 = dynamic_cast<Number&>(*args.at(1));
299+
using Bool = Literal<bool>;
300+
return std::shared_ptr<Expr>(new Bool(num1.get() > num2.get()));
301+
};
302+
auto defGT = Definition(ExprPtr{new Variable{">"}}, ExprPtr{new PrimitiveProcedure{gt}});
303+
defGT.eval(env);
304+
305+
auto eq = [](std::vector<std::shared_ptr<Expr>> const& args)
306+
{
307+
assert(args.size() == 2);
308+
auto num1 = dynamic_cast<Number&>(*args.at(0));
309+
auto num2 = dynamic_cast<Number&>(*args.at(1));
310+
using Bool = Literal<bool>;
311+
return std::shared_ptr<Expr>(new Bool(num1.get() == num2.get()));
312+
};
313+
auto defEQ = Definition(ExprPtr{new Variable{"="}}, ExprPtr{new PrimitiveProcedure{eq}});
314+
defEQ.eval(env);
315+
316+
auto sub = [](std::vector<std::shared_ptr<Expr>> const& args)
317+
{
318+
assert(args.size() == 2);
319+
auto num1 = dynamic_cast<Number&>(*args.at(0));
320+
auto num2 = dynamic_cast<Number&>(*args.at(1));
321+
return std::shared_ptr<Expr>(new Number(num1.get() - num2.get()));
322+
};
323+
auto defSub = Definition(ExprPtr{new Variable{"-"}}, ExprPtr{new PrimitiveProcedure{sub}});
324+
defSub.eval(env);
325+
280326
auto e = p.sexpr();
281327
while (true)
282328
{

0 commit comments

Comments
 (0)