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 63 if( tryEat("(") ) {
64 64 lex = saved;
65 65 goto asExpression;
66 66 }
67 67 }
68 68 immutable LexPosition varpos = (lex.empty ? null : lex.front.pos);
69 69 string var = eatId("after "~kwd,true);
70 - eat("=", "after "~kwd);
71 - kwd = (kwd[0]=='@' ? kwd : ""); // "let, var, def ==> neutral layer"
72 - auto e = E(0);
73 - if( tryEat(";") && !lex.empty && (lex.front.quoted || !["}",")","]"].canFind(lex.front.str)) )
74 - return new LetExpression(pos, var, kwd, e, Body());
75 - else
76 - return new LetExpression(pos, var, kwd, e, new VarExpression(varpos, var));
70 + // [TODO] refactor. only auto e = ... differ
71 + if(tryEat("(")) {
72 + kwd = (kwd[0]=='@' ? kwd : ""); // "let, var, def ==> neutral layer"
73 + auto e = parseLambdaAfterOpenParen(varpos);
74 + if( tryEat(";") && !lex.empty && (lex.front.quoted || !["}",")","]"].canFind(lex.front.str)) )
75 + return new LetExpression(pos, var, kwd, e, Body());
76 + else
77 + return new LetExpression(pos, var, kwd, e, new VarExpression(varpos, var));
78 + } else {
79 + eat("=", "after "~kwd);
80 + kwd = (kwd[0]=='@' ? kwd : ""); // "let, var, def ==> neutral layer"
81 + auto e = E(0);
82 + if( tryEat(";") && !lex.empty && (lex.front.quoted || !["}",")","]"].canFind(lex.front.str)) )
83 + return new LetExpression(pos, var, kwd, e, Body());
84 + else
85 + return new LetExpression(pos, var, kwd, e, new VarExpression(varpos, var));
86 + }
77 87 }
78 88 else
79 89 {
80 90 asExpression:
81 91 auto e = E(0);
82 92 if( tryEat(";") && !lex.empty && (lex.front.quoted || (lex.front.str!="}" && lex.front.str!=")")) )
83 93 return new LetExpression(pos, "_", "", e, Body());
................................................................................
200 210 new FunLiteral(thenPos, [], th),
201 211 new FunLiteral(elsePos, [], el)
202 212 );
203 213 }
204 214 if( tryEat("fun") || tryEat("\u03BB") )
205 215 {
206 216 eat("(", "after fun");
207 - string[] params;
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);
217 + return parseLambdaAfterOpenParen(pos);
220 218 }
221 219 scope(exit) lex.popFront;
222 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 240 private:
226 241 Lexer lex;
227 242 this(Lexer lex) { this.lex = lex; }
228 243
229 244 void eat(string kwd, lazy string msg)
230 245 {
................................................................................
328 343 assert_throw!ParseException(parseString(`1+2}`));
329 344 assert_throw!UnexpectedEOF(parseString(`let "x"`));
330 345 assert_throw!UnexpectedEOF(parseString(`var`));
331 346 assert_throw!ParseException(parseString(`@val x ==`));
332 347 assert_throw!ParseException(parseString(`if(){1}`));
333 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 +}