Differences From Artifact [10baa46251b8a0b6]:
- File
polemy/parse.d
- 2010-11-08 14:59:30 - part of checkin [b985f3bf91] on branch trunk - refactored parser to change AST to ML-like one. (user: kinaba) [annotate]
To Artifact [d47e2b014f260d66]:
- File
polemy/parse.d
- 2010-11-08 16:40:55 - part of checkin [aa770610d3] on branch trunk - added layered-let (user: kinaba) [annotate]
56 56
57 57 AST Body()
58 58 {
59 59 if( lex.empty || !lex.front.quoted && lex.front.str=="}" )
60 60 return doNothingExpression();
61 61
62 62 auto pos = lex.front.pos;
63 - if( tryEat("var") )
63 + string kwd = lex.front.str;
64 + if( tryEat("let") || tryEat("var") || tryEat("def") || tryEat("@") )
64 65 {
66 + if( kwd == "@" )
67 + kwd ~= eatId("after @");
65 68 immutable LexPosition varpos = (lex.empty ? null : lex.front.pos);
66 - string var = eatId("after var");
67 - eat("=", "after var");
69 + string var = eatId("after "~kwd);
70 + eat("=", "after "~kwd);
71 + kwd = (kwd[0]=='@' ? kwd : "@val");
68 72 auto e = E(0);
69 73 if( tryEat(";") && !lex.empty && (lex.front.quoted || (lex.front.str!="}" && lex.front.str!=")")) )
70 - return new LetExpression(pos, var, e, Body());
74 + return new LetExpression(pos, var, kwd, e, Body());
71 75 else
72 - return new LetExpression(pos, var, e, new VarExpression(varpos, var));
76 + return new LetExpression(pos, var, kwd, e, new VarExpression(varpos, var));
73 77 }
74 78 else
75 79 {
76 80 auto e = E(0);
77 81 if( tryEat(";") && !lex.empty && (lex.front.quoted || (lex.front.str!="}" && lex.front.str!=")")) )
78 - return new LetExpression(pos, "_", e, Body());
82 + return new LetExpression(pos, "_", "@val", e, Body());
79 83 else
80 84 return e;
81 85 }
82 86 }
83 87
84 88 // [TODO] make customizable from program
85 89 static immutable string[][] operator_perferences = [
................................................................................
183 187 return new FuncallExpression(pos,
184 188 new VarExpression(pos, "if"),
185 189 cond,
186 190 new FunLiteral(thenPos, [], th),
187 191 new FunLiteral(elsePos, [], el)
188 192 );
189 193 }
190 - if( tryEat("fun") )
194 + if( tryEat("fun") || tryEat("λ") )
191 195 {
192 196 eat("(", "after fun");
193 197 string[] params;
194 198 while( !tryEat(")") )
195 199 {
196 200 params ~= eatId("for function parameter");
197 201 if( !tryEat(",") ) {
................................................................................
251 255 {
252 256 mixin EasyAST;
253 257
254 258 assert_eq(parseString(`123`), intl(123));
255 259 assert_eq(parseString(`"foo"`), strl("foo"));
256 260 assert_eq(parseString(`fun(){1}`), fun([],intl(1)));
257 261 assert_eq(parseString(`fun(x){1}`), fun(["x"],intl(1)));
258 - assert_eq(parseString(`1;2`), let("_",intl(1),intl(2)));
259 - assert_eq(parseString(`1;2;`), let("_",intl(1),intl(2)));
260 - assert_eq(parseString(`var x=1;2`), let("x",intl(1),intl(2)));
261 - assert_eq(parseString(`var x=1;2;`), let("x",intl(1),intl(2)));
262 - assert_eq(parseString(`var x=1`), let("x",intl(1),var("x")));
263 - assert_eq(parseString(`var x=1;`), let("x",intl(1),var("x")));
262 + assert_eq(parseString(`λ(){1}`), fun([],intl(1)));
263 + assert_eq(parseString(`λ(x){1}`), fun(["x"],intl(1)));
264 + assert_eq(parseString(`1;2`), let("_","@val",intl(1),intl(2)));
265 + assert_eq(parseString(`1;2;`), let("_","@val",intl(1),intl(2)));
266 + assert_eq(parseString(`let x=1;2`), let("x","@val",intl(1),intl(2)));
267 + assert_eq(parseString(`var x=1;2;`), let("x","@val",intl(1),intl(2)));
268 + assert_eq(parseString(`def x=1`), let("x","@val",intl(1),var("x")));
269 + assert_eq(parseString(`@val x=1;`), let("x","@val",intl(1),var("x")));
270 + assert_eq(parseString(`@typ x="#int";`), let("x","@typ",strl("#int"),var("x")));
264 271 assert_eq(parseString(`f(1,2)`), call(var("f"),intl(1),intl(2)));
265 272 assert_eq(parseString(`if(1){2}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(178))));
266 273 assert_eq(parseString(`if(1){2}else{3}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(3))));
267 274 assert_eq(parseString(`if(1){}else{3}()()`),
268 275 call(call(call(var("if"),intl(1),fun([],intl(178)),fun([],intl(3))))));
269 276 assert_eq(parseString(`1+2*3`), call(var("+"),intl(1),call(var("*"),intl(2),intl(3))));
270 277 assert_eq(parseString(`(1+2)*3`), call(var("*"),call(var("+"),intl(1),intl(2)),intl(3)));
271 278 assert_eq(parseString(`1*(2+3)`), call(var("*"),intl(1),call(var("+"),intl(2),intl(3))));
272 279 assert_eq(parseString(`1*2+3`), call(var("+"),call(var("*"),intl(1),intl(2)),intl(3)));
273 280
274 281 assert_eq(parseString(`
275 - var x = 100; #comment
276 - var y = 200; #comment!!!!!
282 + let x = 100; #comment
283 + let y = 200; #comment!!!!!
277 284 x+y
278 285 `),
279 - let("x", intl(100), let("y", intl(200), call(var("+"), var("x"), var("y"))))
286 + let("x", "@val", intl(100), let("y", "@val", intl(200), call(var("+"), var("x"), var("y"))))
280 287 );
281 288
282 289 assert_eq(parseString(`
283 290 var fac = fun(x){ if(x <= 1) {1} else {x*fac(x-1)} };
284 291 fac(10)
285 292 `),
286 - let("fac", fun(["x"],
293 + let("fac", "@val", fun(["x"],
287 294 call(var("if"),
288 295 call(var("<="), var("x"), intl(1)),
289 296 fun([], intl(1)),
290 297 fun([], call(var("*"), var("x"), call(var("fac"),call(var("-"),var("x"),intl(1)))))
291 298 )),
292 299 call(var("fac"),intl(10))
293 300 )
................................................................................
294 301 );
295 302 }
296 303
297 304 unittest
298 305 {
299 306 assert_throw!ParseException(parseString(`1+`));
300 307 assert_throw!ParseException(parseString(`1+2}`));
301 - assert_throw!ParseException(parseString(`var "x"`));
308 + assert_throw!ParseException(parseString(`let "x"`));
302 309 assert_throw!ParseException(parseString(`var`));
303 - assert_throw!ParseException(parseString(`var x ==`));
310 + assert_throw!ParseException(parseString(`@val x ==`));
304 311 assert_throw!ParseException(parseString(`if(){1}`));
305 312 assert_throw!ParseException(parseString(`f(`));
306 313 }