@@ -146,7 +146,8 @@ class Parser
146
146
ExprPtr atomic ()
147
147
{
148
148
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 == ' -' ))
150
151
{
151
152
return number ();
152
153
}
@@ -184,6 +185,10 @@ class Parser
184
185
{
185
186
return lambda ();
186
187
}
188
+ else if (mLookAhead .text == " if" )
189
+ {
190
+ return if_ ();
191
+ }
187
192
else
188
193
{
189
194
return application ();
@@ -231,6 +236,14 @@ class Parser
231
236
auto body = sequence ();
232
237
return ExprPtr{new Lambda (params, body)};
233
238
}
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
+ }
234
247
ExprPtr application ()
235
248
{
236
249
auto op = sexpr ();
@@ -249,15 +262,18 @@ class Parser
249
262
250
263
int32_t main ()
251
264
{
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)" );
253
267
Parser p (lex);
254
268
269
+ #if 0
255
270
auto t = lex.nextToken();
256
271
while (t.type != TokenType::kEOF)
257
272
{
258
273
std::cout << t.text << std::endl;
259
274
t = lex.nextToken();
260
275
}
276
+ #endif
261
277
262
278
Env env{};
263
279
@@ -272,11 +288,41 @@ int32_t main()
272
288
);
273
289
return std::shared_ptr<Expr>(new Number (result));
274
290
};
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}});
278
292
defMul.eval (env);
279
293
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
+
280
326
auto e = p.sexpr ();
281
327
while (true )
282
328
{
0 commit comments