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  +}