Differences From Artifact [31eeea68e341add3]:
- File        
polemy/parse.d
- 2010-11-07 16:31:52 - part of checkin [633e700889] on branch trunk - If-expression implemented. Factorial now works. (user: kinaba) [annotate]
 
 
To Artifact [752d9af2ecdd593b]:
- File        
polemy/parse.d
- 2010-11-08 08:45:51 - part of checkin [8d297342aa] on branch trunk - Replaced Token.Kind with bool quoted (user: kinaba) [annotate]
 
 
    4   *                                                                                     4   *
    5   * Parser for Polemy programming language                                              5   * Parser for Polemy programming language
    6   */                                                                                    6   */
    7  module polemy.parse;                                                                   7  module polemy.parse;
    8  import polemy._common;                                                                 8  import polemy._common;
    9  import polemy.lex;                                                                     9  import polemy.lex;
   10  import polemy.ast;                                                                    10  import polemy.ast;
   11  import std.bigint;                                                               <
   12                                                                                        11  
   13  /// Parsing Failure                                                                   12  /// Parsing Failure
   14                                                                                        13  
   15  class ParserException : Exception                                                     14  class ParserException : Exception
   16  {                                                                                     15  {
   17  private:                                                                              16  private:
   18          this(string msg) { super(msg); }                                              17          this(string msg) { super(msg); }
................................................................................................................................................................................
   62                  }                                                                     61                  }
   63                  return p;                                                             62                  return p;
   64          }                                                                             63          }
   65                                                                                        64  
   66          Program parseStatements()                                                     65          Program parseStatements()
   67          {                                                                             66          {
   68                  Program p;                                                            67                  Program p;
   69                  while( !lex.empty && (lex.front.kind!=Token.Kind.identifier || l |    68                  while( !lex.empty && (lex.front.quoted || lex.front.str!="}") )
   70                          p ~= parseStatement();                                        69                          p ~= parseStatement();
   71                  return p;                                                             70                  return p;
   72          }                                                                             71          }
   73                                                                                        72  
   74          Statement parseStatement()                                                    73          Statement parseStatement()
   75          {                                                                             74          {
   76                  auto saved = lex.save;                                                75                  auto saved = lex.save;
   77                  scope(failure) lex = saved;                                           76                  scope(failure) lex = saved;
   78                                                                                        77  
   79                  if( lex.empty )                                                       78                  if( lex.empty )
   80                          throw new ParserException("EOF during parsing a statemen      79                          throw new ParserException("EOF during parsing a statemen
   81                  auto pos = lex.front.pos;                                             80                  auto pos = lex.front.pos;
   82                                                                                        81  
   83                  if( lex.front.kind==Token.Kind.identifier && lex.front.str=="var |    82                  if( !lex.front.quoted && lex.front.str=="var" )
   84                  {                                                                     83                  {
   85                          // "var" Var "=" Expression ";"                               84                          // "var" Var "=" Expression ";"
   86                          lex.popFront;                                                 85                          lex.popFront;
   87                          string var = lex.front.str;                                   86                          string var = lex.front.str;
   88                          lex.popFront;                                                 87                          lex.popFront;
   89                          eat("=", "for variable declaration");                         88                          eat("=", "for variable declaration");
   90                          auto parsed = new DeclStatement(pos, var, parseExpressio      89                          auto parsed = new DeclStatement(pos, var, parseExpressio
................................................................................................................................................................................
  177                                                                                       176  
  178          Expression parseBaseBaseExpression()                                         177          Expression parseBaseBaseExpression()
  179          {                                                                            178          {
  180                  if( lex.empty )                                                      179                  if( lex.empty )
  181                          throw new ParserException("EOF during parsing an express     180                          throw new ParserException("EOF during parsing an express
  182                  auto pos = lex.front.pos;                                            181                  auto pos = lex.front.pos;
  183                                                                                       182  
  184                  if( lex.front.kind == Token.Kind.number )                        |   183                  if( lex.front.quoted )
                                                                                        >   184                  {
                                                                                        >   185                          scope(exit) lex.popFront;
                                                                                        >   186                          return new StrLiteralExpression(pos, lex.front.str);
                                                                                        >   187                  }
                                                                                        >   188                  if( isNumber(lex.front.str) ) // is_number
  185                  {                                                                    189                  {
  186                          scope(exit) lex.popFront;                                    190                          scope(exit) lex.popFront;
  187                          return new IntLiteralExpression(pos, BigInt(cast(string)     191                          return new IntLiteralExpression(pos, BigInt(cast(string)
  188                  }                                                                    192                  }
  189                  if( lex.front.kind == Token.Kind.stringLiteral )                 <
  190                  {                                                                <
  191                          scope(exit) lex.popFront;                                <
  192                          return new StrLiteralExpression(pos, lex.front.str);     <
  193                  }                                                                <
  194                  if( tryEat("(") )                                                    193                  if( tryEat("(") )
  195                  {                                                                    194                  {
  196                          auto e = parseE();                                           195                          auto e = parseE();
  197                          eat(")", "after parenthesized expression");                  196                          eat(")", "after parenthesized expression");
  198                          return e;                                                    197                          return e;
  199                  }                                                                    198                  }
  200                  if( tryEat("if") )                                                   199                  if( tryEat("if") )
................................................................................................................................................................................
  227                          string[] params;                                             226                          string[] params;
  228                          while(!tryEat(")"))                                          227                          while(!tryEat(")"))
  229                          {                                                            228                          {
  230                                  if( lex.empty ) {                                    229                                  if( lex.empty ) {
  231                                          auto e = ParserException.create(lex,"Une     230                                          auto e = ParserException.create(lex,"Une
  232                                          throw e;                                     231                                          throw e;
  233                                  }                                                    232                                  }
  234                                  if( lex.front.kind != Token.Kind.identifier ) {  |   233                                  if( lex.front.quoted ) {
  235                                          auto e = ParserException.create(lex,"Ide     234                                          auto e = ParserException.create(lex,"Ide
  236                                          throw e;                                     235                                          throw e;
  237                                  }                                                    236                                  }
  238                                  params ~= lex.front.str;                             237                                  params ~= lex.front.str;
  239                                  lex.popFront;                                        238                                  lex.popFront;
  240                                  if( !tryEat(",") ) {                                 239                                  if( !tryEat(",") ) {
  241                                          eat(")", "after function parameters");       240                                          eat(")", "after function parameters");
................................................................................................................................................................................
  268                                  ~(lex.empty ? "EOF" : lex.front.str)~"' occured"     267                                  ~(lex.empty ? "EOF" : lex.front.str)~"' occured"
  269                          throw e;                                                     268                          throw e;
  270                  }                                                                    269                  }
  271          }                                                                            270          }
  272                                                                                       271  
  273          bool tryEat(string kwd)                                                      272          bool tryEat(string kwd)
  274          {                                                                            273          {
  275                  if( lex.empty || lex.front.kind!=Token.Kind.identifier || lex.fr |   274                  if( lex.empty || lex.front.quoted || lex.front.str!=kwd )
  276                          return false;                                                275                          return false;
  277                  lex.popFront;                                                        276                  lex.popFront;
  278                  return true;                                                         277                  return true;
  279          }                                                                            278          }
                                                                                        >   279  
                                                                                        >   280          bool isNumber(string s)
                                                                                        >   281          {
                                                                                        >   282                  return find!(`a<'0'||'9'<a`)(s).empty;
                                                                                        >   283          }
  280  }                                                                                    284  }
  281                                                                                       285  
  282  unittest                                                                             286  unittest
  283  {                                                                                    287  {
  284          auto p = parserFromString(`                                                  288          auto p = parserFromString(`
  285                  var x = 100;                                                         289                  var x = 100;
  286                  var y = 200;                                                         290                  var y = 200;
................................................................................................................................................................................
  339                  new IntLiteralExpression(null, BigInt(1)),                           343                  new IntLiteralExpression(null, BigInt(1)),
  340                  new FuncallExpression(null,                                          344                  new FuncallExpression(null,
  341                          new FunLiteralExpression(null, ["abc"], [                    345                          new FunLiteralExpression(null, ["abc"], [
  342                          ]),                                                          346                          ]),
  343                          new IntLiteralExpression(null, BigInt(4))                    347                          new IntLiteralExpression(null, BigInt(4))
  344                          ))));                                                        348                          ))));
  345  }                                                                                    349  }
                                                                                        >   350  
                                                                                        >   351  /*
  346  unittest                                                                             352  unittest
  347  {                                                                                    353  {
  348          auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x     354          auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x
  349          Program prog = p.parseProgram();                                             355          Program prog = p.parseProgram();
  350  }                                                                                    356  }
  351                                                                                       357  
  352  unittest                                                                             358  unittest
................................................................................................................................................................................
  357                  new VarExpression(null, "if"),                                       363                  new VarExpression(null, "if"),
  358                  new FuncallExpression(null, new VarExpression(null,"<"), new Var     364                  new FuncallExpression(null, new VarExpression(null,"<"), new Var
  359                          new IntLiteralExpression(null, BigInt(2))),                  365                          new IntLiteralExpression(null, BigInt(2))),
  360                  new FunLiteralExpression(null, [], [new ExprStatement(null, new      366                  new FunLiteralExpression(null, [], [new ExprStatement(null, new 
  361                  new FunLiteralExpression(null, [], [new ExprStatement(null, new      367                  new FunLiteralExpression(null, [], [new ExprStatement(null, new 
  362                  )));                                                                 368                  )));
  363  }                                                                                    369  }
                                                                                        >   370  */