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