Differences From Artifact [a8c1fd55863166fb]:
- File
polemy/parse.d
- 2010-11-09 14:24:09 - part of checkin [2459e9a821] on branch trunk - refactored eof-driven REPL (user: kinaba) [annotate]
To Artifact [3e7ec41f1027e8ba]:
- File
polemy/parse.d
- 2010-11-09 15:19:20 - part of checkin [68546f3e9f] on branch trunk - several samples (user: kinaba) [annotate]
63 if( tryEat("(") ) { 63 if( tryEat("(") ) {
64 lex = saved; 64 lex = saved;
65 goto asExpression; 65 goto asExpression;
66 } 66 }
67 } 67 }
68 immutable LexPosition varpos = (lex.empty ? null : lex.f 68 immutable LexPosition varpos = (lex.empty ? null : lex.f
69 string var = eatId("after "~kwd,true); 69 string var = eatId("after "~kwd,true);
> 70 // [TODO] refactor. only auto e = ... differ
> 71 if(tryEat("(")) {
> 72 kwd = (kwd[0]=='@' ? kwd : ""); // "let, var, de
> 73 auto e = parseLambdaAfterOpenParen(varpos);
> 74 if( tryEat(";") && !lex.empty && (lex.front.quot
> 75 return new LetExpression(pos, var, kwd,
> 76 else
> 77 return new LetExpression(pos, var, kwd,
> 78 } else {
70 eat("=", "after "~kwd); | 79 eat("=", "after "~kwd);
71 kwd = (kwd[0]=='@' ? kwd : ""); // "let, var, def ==> ne | 80 kwd = (kwd[0]=='@' ? kwd : ""); // "let, var, de
72 auto e = E(0); | 81 auto e = E(0);
73 if( tryEat(";") && !lex.empty && (lex.front.quoted || ![ | 82 if( tryEat(";") && !lex.empty && (lex.front.quot
74 return new LetExpression(pos, var, kwd, e, Body( | 83 return new LetExpression(pos, var, kwd,
75 else | 84 else
76 return new LetExpression(pos, var, kwd, e, new V | 85 return new LetExpression(pos, var, kwd,
> 86 }
77 } 87 }
78 else 88 else
79 { 89 {
80 asExpression: 90 asExpression:
81 auto e = E(0); 91 auto e = E(0);
82 if( tryEat(";") && !lex.empty && (lex.front.quoted || (l 92 if( tryEat(";") && !lex.empty && (lex.front.quoted || (l
83 return new LetExpression(pos, "_", "", e, Body() 93 return new LetExpression(pos, "_", "", e, Body()
................................................................................................................................................................................
200 new FunLiteral(thenPos, [], th), 210 new FunLiteral(thenPos, [], th),
201 new FunLiteral(elsePos, [], el) 211 new FunLiteral(elsePos, [], el)
202 ); 212 );
203 } 213 }
204 if( tryEat("fun") || tryEat("\u03BB") ) 214 if( tryEat("fun") || tryEat("\u03BB") )
205 { 215 {
206 eat("(", "after fun"); 216 eat("(", "after fun");
207 string[] params; | 217 return parseLambdaAfterOpenParen(pos);
208 while( !tryEat(")") ) <
209 { <
210 params ~= eatId("for function parameter"); <
211 if( !tryEat(",") ) { <
212 eat(")", "after function parameters"); <
213 break; <
214 } <
215 } <
216 eat("{", "after function parameters"); <
217 auto funbody = Body(); <
218 eat("}", "after function body"); <
219 return new FunLiteral(pos, params, funbody); <
220 } 218 }
221 scope(exit) lex.popFront; 219 scope(exit) lex.popFront;
222 return new VarExpression(pos, lex.front.str); 220 return new VarExpression(pos, lex.front.str);
223 } 221 }
> 222
> 223 AST parseLambdaAfterOpenParen(immutable LexPosition pos)
> 224 {
> 225 string[] params;
> 226 while( !tryEat(")") )
> 227 {
> 228 params ~= eatId("for function parameter");
> 229 if( !tryEat(",") ) {
> 230 eat(")", "after function parameters");
> 231 break;
> 232 }
> 233 }
> 234 eat("{", "after function parameters");
> 235 auto funbody = Body();
> 236 eat("}", "after function body");
> 237 return new FunLiteral(pos, params, funbody);
> 238 }
224 239
225 private: 240 private:
226 Lexer lex; 241 Lexer lex;
227 this(Lexer lex) { this.lex = lex; } 242 this(Lexer lex) { this.lex = lex; }
228 243
229 void eat(string kwd, lazy string msg) 244 void eat(string kwd, lazy string msg)
230 { 245 {
................................................................................................................................................................................
328 assert_throw!ParseException(parseString(`1+2}`)); 343 assert_throw!ParseException(parseString(`1+2}`));
329 assert_throw!UnexpectedEOF(parseString(`let "x"`)); 344 assert_throw!UnexpectedEOF(parseString(`let "x"`));
330 assert_throw!UnexpectedEOF(parseString(`var`)); 345 assert_throw!UnexpectedEOF(parseString(`var`));
331 assert_throw!ParseException(parseString(`@val x ==`)); 346 assert_throw!ParseException(parseString(`@val x ==`));
332 assert_throw!ParseException(parseString(`if(){1}`)); 347 assert_throw!ParseException(parseString(`if(){1}`));
333 assert_throw!UnexpectedEOF(parseString(`f(`)); 348 assert_throw!UnexpectedEOF(parseString(`f(`));
334 } 349 }
> 350
> 351 unittest
> 352 {
> 353 mixin EasyAST;
> 354 assert_eq(parseString(`def foo(x) { x+1 }; foo`),
> 355 let("foo", "",
> 356 fun(["x"], call(var("+"), var("x"), intl(1))),
> 357 var("foo"))
> 358 );
> 359 }