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  }