src/compiler/Parser.cpp
author David Anderson <dvander@alliedmods.net>
Sun Jan 06 13:52:21 2013 -0800 (2013-01-06)
changeset 256 3c184218462d
parent 252 1dee2330aa78
child 257 9db4cc815ebc
permissions -rw-r--r--
Initial implementation of module imports.
[email protected]
     1
/* vim: set ts=4 sw=4 tw=99 et:
[email protected]
     2
 *
[email protected]
     3
 * Copyright (C) 2012 David Anderson
[email protected]
     4
 *
[email protected]
     5
 * This file is part of SourcePawn.
[email protected]
     6
 *
[email protected]
     7
 * SourcePawn is free software: you can redistribute it and/or modify it under
[email protected]
     8
 * the terms of the GNU General Public License as published by the Free
[email protected]
     9
 * Software Foundation, either version 3 of the License, or (at your option)
[email protected]
    10
 * any later version.
[email protected]
    11
 * 
[email protected]
    12
 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
[email protected]
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
[email protected]
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
[email protected]
    15
 *
[email protected]
    16
 * You should have received a copy of the GNU General Public License along with
[email protected]
    17
 * SourcePawn. If not, see http://www.gnu.org/licenses/.
[email protected]
    18
 */
[email protected]
    19
#include <string.h>
[email protected]
    20
#include "../Zone.h"
[email protected]
    21
#include "../FixedArray.h"
[email protected]
    22
#include "../Heap.h"
[email protected]
    23
#include "../Strings.h"
[email protected]
    24
#include "../TypeManager.h"
[email protected]
    25
#include "Parser.h"
[email protected]
    26
#include "../Heap-inl.h"
[email protected]
    27
[email protected]
    28
using namespace ke;
[email protected]
    29
[email protected]
    30
Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
[email protected]
    31
  : zone_(zone),
[email protected]
    32
    cc_(cc),
[email protected]
    33
    pool_(zone_->pool()),
[email protected]
    34
    scanner_(cc, stream, length),
[email protected]
    35
    unbound_(NULL)
[email protected]
    36
{
[email protected]
    37
    unbound_ = new (pool_) PoolList<NameProxy *>();
[email protected]
    38
    imports_ = new (pool_) PoolList<ImportStatement *>();
[email protected]
    39
}
[email protected]
    40
[email protected]
    41
bool
[email protected]
    42
Parser::peek(TokenKind kind)
[email protected]
    43
{
[email protected]
    44
    return scanner_.peek() == kind;
[email protected]
    45
}
[email protected]
    46
[email protected]
    47
bool
[email protected]
    48
Parser::match(TokenKind kind)
[email protected]
    49
{
[email protected]
    50
    if (!peek(kind))
[email protected]
    51
        return false;
[email protected]
    52
    scanner_.scan();
[email protected]
    53
    return true;
[email protected]
    54
}
[email protected]
    55
[email protected]
    56
bool
[email protected]
    57
Parser::matchSemicolon()
[email protected]
    58
{
[email protected]
    59
    return expect(TOK_SEMICOLON);
[email protected]
    60
}
[email protected]
    61
[email protected]
    62
bool
[email protected]
    63
Parser::expect(TokenKind kind)
[email protected]
    64
{
[email protected]
    65
    TokenKind got = scanner_.scan();
[email protected]
    66
    if (got == kind)
[email protected]
    67
        return true;
[email protected]
    68
    cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
[email protected]
    69
    return false;
[email protected]
    70
}
[email protected]
    71
[email protected]
    72
bool
[email protected]
    73
Parser::matchName(String **name, TokenKind kind)
[email protected]
    74
{
[email protected]
    75
    assert(kind == TOK_NAME || kind == TOK_LABEL);
[email protected]
    76
    *name = NULL;
[email protected]
    77
    if (!match(kind))
[email protected]
    78
        return false;
[email protected]
    79
    *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
[email protected]
    80
    return true;
[email protected]
    81
}
[email protected]
    82
[email protected]
    83
String *
[email protected]
    84
Parser::expectName()
[email protected]
    85
{
[email protected]
    86
    if (!expect(TOK_NAME))
[email protected]
    87
        return NULL;
[email protected]
    88
    return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
[email protected]
    89
}
[email protected]
    90
[email protected]
    91
Expression *
[email protected]
    92
Parser::primitive()
[email protected]
    93
{
[email protected]
    94
    TokenKind kind = scanner_.peek();
[email protected]
    95
    switch (kind) {
[email protected]
    96
      case TOK_FLOAT_LITERAL:
[email protected]
    97
      {
[email protected]
    98
        scanner_.scan();
[email protected]
    99
        double value = Scanner::ParseDouble(scanner_.literal());
[email protected]
   100
        return new (pool_) FloatLiteral(scanner_.begin(), value);
[email protected]
   101
      }
[email protected]
   102
[email protected]
   103
      case TOK_HEX_LITERAL:
[email protected]
   104
      {
[email protected]
   105
        scanner_.scan();
[email protected]
   106
        int value = strtol(scanner_.literal(), NULL, 16);
[email protected]
   107
        return new (pool_) IntegerLiteral(scanner_.begin(), value);
[email protected]
   108
      }
[email protected]
   109
[email protected]
   110
      case TOK_INTEGER_LITERAL:
[email protected]
   111
      {
[email protected]
   112
        scanner_.scan();
[email protected]
   113
        int value = atoi(scanner_.literal());
[email protected]
   114
        return new (pool_) IntegerLiteral(scanner_.begin(), value);
[email protected]
   115
      }
[email protected]
   116
[email protected]
   117
      case TOK_TRUE:
[email protected]
   118
      case TOK_FALSE:
[email protected]
   119
        scanner_.scan();
[email protected]
   120
        return new (pool_) BooleanLiteral(scanner_.begin(), kind);
[email protected]
   121
[email protected]
   122
      case TOK_STRING_LITERAL:
[email protected]
   123
      {
[email protected]
   124
        scanner_.scan();
[email protected]
   125
        Local<String> string(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
[email protected]
   126
        return new (pool_) StringLiteral(scanner_.begin(), string);
[email protected]
   127
      }
[email protected]
   128
[email protected]
   129
      default:
[email protected]
   130
      {
[email protected]
   131
        if (kind != TOK_ERROR)
[email protected]
   132
            cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
[email protected]
   133
        return NULL;
[email protected]
   134
      }
[email protected]
   135
    }
[email protected]
   136
}
[email protected]
   137
[email protected]
   138
Expression *
[email protected]
   139
Parser::fixedArrayLiteral()
[email protected]
   140
{
[email protected]
   141
    SourcePosition pos = scanner_.begin();
[email protected]
   142
[email protected]
   143
    ExpressionList *list = new (pool_) ExpressionList();
[email protected]
   144
    do {
[email protected]
   145
        // { } is an illegal array literal.
[email protected]
   146
        if (list->length() > 0 && match(TOK_LBRACE))
[email protected]
   147
            break;
[email protected]
   148
[email protected]
   149
        Expression *expr = NULL;
[email protected]
   150
        if (peek(TOK_LBRACE))
[email protected]
   151
            expr = fixedArrayLiteral();
[email protected]
   152
        else
[email protected]
   153
            expr = primitive();
[email protected]
   154
        if (!expr)
[email protected]
   155
            return NULL;
[email protected]
   156
[email protected]
   157
        if (!list->append(expr))
[email protected]
   158
            return NULL;
[email protected]
   159
[email protected]
   160
        if (!match(TOK_COMMA)) {
[email protected]
   161
            if (!expect(TOK_RBRACE))
[email protected]
   162
                return NULL;
[email protected]
   163
            break;
[email protected]
   164
        }
[email protected]
   165
    } while (true);
[email protected]
   166
[email protected]
   167
    return new (pool_) ArrayLiteral(pos, TOK_LBRACE, list);
[email protected]
   168
}
[email protected]
   169
[email protected]
   170
Expression *
[email protected]
   171
Parser::prefix()
[email protected]
   172
{
[email protected]
   173
    switch (scanner_.peek()) {
[email protected]
   174
      case TOK_LPAREN:
[email protected]
   175
      {
[email protected]
   176
        scanner_.scan();
[email protected]
   177
        Expression *expr = expression();
[email protected]
   178
        if (!expr)
[email protected]
   179
            return NULL;
[email protected]
   180
        if (!expect(TOK_RPAREN))
[email protected]
   181
            return NULL;
[email protected]
   182
        return expr;
[email protected]
   183
      }
[email protected]
   184
[email protected]
   185
      case TOK_NAME:
[email protected]
   186
      {
[email protected]
   187
        Local<String> name(zone_, expectName());
[email protected]
   188
        if (!name)
[email protected]
   189
            return NULL;
[email protected]
   190
        return new (pool_) NameProxy(scanner_.begin(), name);
[email protected]
   191
      }
[email protected]
   192
[email protected]
   193
      default:
[email protected]
   194
        return primitive();
[email protected]
   195
    }
[email protected]
   196
}
[email protected]
   197
[email protected]
   198
// Parses only old-style declarations.
[email protected]
   199
bool
[email protected]
   200
Parser::typeAndName(Expression **type, String **namep)
[email protected]
   201
{
[email protected]
   202
    if (match(TOK_LABEL)) {
[email protected]
   203
        // Old-style declaration:
[email protected]
   204
        //   new X:type
[email protected]
   205
        Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
[email protected]
   206
        if (!name)
[email protected]
   207
            return false;
[email protected]
   208
[email protected]
   209
        *type = new (pool_) NameProxy(scanner_.begin(), name);
[email protected]
   210
        *namep = expectName();
[email protected]
   211
        return !!*namep;
[email protected]
   212
    }
[email protected]
   213
    
[email protected]
   214
    *type = NULL;
[email protected]
   215
    *namep = expectName();
[email protected]
   216
[email protected]
   217
    return !!*namep;
[email protected]
   218
}
[email protected]
   219
[email protected]
   220
// Parses both old and new style declarations.
[email protected]
   221
bool
[email protected]
   222
Parser::fullTypeAndName(Expression **type, String **namep, DeclKind kind)
[email protected]
   223
{
[email protected]
   224
    //   decl    ::= newdecl | olddecl
[email protected]
   225
    //   newdecl ::= Type Ident
[email protected]
   226
    //   olddecl ::= Label? (Ident | "...")
[email protected]
   227
    //   type    ::= Ident
[email protected]
   228
    //   label   ::= Ident ":"
[email protected]
   229
    //
[email protected]
   230
    if (match(TOK_LABEL)) {
[email protected]
   231
        // We something of the form:
[email protected]
   232
        //     Label Ident
[email protected]
   233
        // or: Label "..."
[email protected]
   234
        Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
[email protected]
   235
        if (!name)
[email protected]
   236
            return false;
[email protected]
   237
[email protected]
   238
        *type = new (pool_) NameProxy(scanner_.begin(), name);
[email protected]
   239
        if (kind == DeclArg && match(TOK_ELLIPSES)) {
[email protected]
   240
            *namep = NULL;
[email protected]
   241
        } else {
[email protected]
   242
            if ((*namep = expectName()) == NULL)
[email protected]
   243
                return false;
[email protected]
   244
        }
[email protected]
   245
        return true;
[email protected]
   246
    }
[email protected]
   247
[email protected]
   248
    Local<String> name(zone_, expectName());
[email protected]
   249
    if (!name)
[email protected]
   250
        return false;
[email protected]
   251
[email protected]
   252
    if (peek(TOK_NAME) || (kind == DeclArg && peek(TOK_ELLIPSES))) {
[email protected]
   253
        // We got something of the form:
[email protected]
   254
        //    Ident Ident
[email protected]
   255
        *type = new (pool_) NameProxy(scanner_.begin(), name);
[email protected]
   256
        if (peek(TOK_NAME)) {
[email protected]
   257
            if ((*namep = expectName()) == NULL)
[email protected]
   258
                return false;
[email protected]
   259
        } else {
[email protected]
   260
            *namep = NULL;
[email protected]
   261
        }
[email protected]
   262
        return true;
[email protected]
   263
    }
[email protected]
   264
[email protected]
   265
    // We got something of the form:
[email protected]
   266
    //    Ident
[email protected]
   267
    *type = NULL;
[email protected]
   268
    *namep = name;
[email protected]
   269
    return true;
[email protected]
   270
}
[email protected]
   271
[email protected]
   272
Expression *
[email protected]
   273
Parser::call(Expression *callee)
[email protected]
   274
{
[email protected]
   275
    ExpressionList *arguments = new (pool_) ExpressionList();
[email protected]
   276
[email protected]
   277
    SourcePosition pos = scanner_.begin();
[email protected]
   278
    expect(TOK_LPAREN);
[email protected]
   279
    
[email protected]
   280
    if (!match(TOK_RPAREN)) {
[email protected]
   281
        while (true) {
[email protected]
   282
            Expression *expr = expression();
[email protected]
   283
            if (!expr)
[email protected]
   284
                return NULL;
[email protected]
   285
[email protected]
   286
            if (!arguments->append(expr))
[email protected]
   287
                return NULL;
[email protected]
   288
[email protected]
   289
            if (!match(TOK_COMMA))
[email protected]
   290
                break;
[email protected]
   291
        }
[email protected]
   292
[email protected]
   293
        if (!expect(TOK_RPAREN))
[email protected]
   294
            return NULL;
[email protected]
   295
    }
[email protected]
   296
[email protected]
   297
    return new (pool_) CallExpression(pos, callee, arguments);
[email protected]
   298
}
[email protected]
   299
[email protected]
   300
Expression *
[email protected]
   301
Parser::index(Expression *left)
[email protected]
   302
{
[email protected]
   303
    expect(TOK_LBRACKET);
[email protected]
   304
    
[email protected]
   305
    SourcePosition pos = scanner_.begin();
[email protected]
   306
    Expression *expr = expression();
[email protected]
   307
    if (!expr)
[email protected]
   308
        return NULL;
[email protected]
   309
[email protected]
   310
    if (!expect(TOK_RBRACKET))
[email protected]
   311
        return NULL;
[email protected]
   312
[email protected]
   313
    return new (pool_) IndexExpression(pos, left, expr);
[email protected]
   314
}
[email protected]
   315
[email protected]
   316
Expression *
[email protected]
   317
Parser::field(Expression *left)
[email protected]
   318
{
[email protected]
   319
    expect(TOK_DOT);
[email protected]
   320
[email protected]
   321
    SourcePosition pos = scanner_.begin();
[email protected]
   322
    Local<String> name(zone_, expectName());
[email protected]
   323
    if (!name)
[email protected]
   324
        return NULL;
[email protected]
   325
[email protected]
   326
    return new (pool_) FieldExpression(pos, left, name);
[email protected]
   327
}
[email protected]
   328
[email protected]
   329
Expression *
[email protected]
   330
Parser::primary()
[email protected]
   331
{
[email protected]
   332
    Expression *expr = prefix();
[email protected]
   333
    if (!expr)
[email protected]
   334
        return NULL;
[email protected]
   335
[email protected]
   336
    for (;;) {
[email protected]
   337
        switch (scanner_.peek()) {
[email protected]
   338
          case TOK_LPAREN:
[email protected]
   339
            if ((expr = call(expr)) == NULL)
[email protected]
   340
                return NULL;
[email protected]
   341
            break;
[email protected]
   342
[email protected]
   343
          case TOK_LBRACKET:
[email protected]
   344
            if ((expr = index(expr)) == NULL)
[email protected]
   345
                return NULL;
[email protected]
   346
            break;
[email protected]
   347
[email protected]
   348
          case TOK_DOT:
[email protected]
   349
            if ((expr = field(expr)) == NULL)
[email protected]
   350
                return NULL;
[email protected]
   351
            break;
[email protected]
   352
[email protected]
   353
          default:
[email protected]
   354
            return expr;
[email protected]
   355
        }
[email protected]
   356
    }
[email protected]
   357
}
[email protected]
   358
[email protected]
   359
Expression *
[email protected]
   360
Parser::unary()
[email protected]
   361
{
[email protected]
   362
    TokenKind token = scanner_.peek();
[email protected]
   363
[email protected]
   364
    SourcePosition pos = scanner_.begin();
[email protected]
   365
    switch (token) {
[email protected]
   366
      case TOK_INCREMENT:
[email protected]
   367
      case TOK_DECREMENT:
[email protected]
   368
      {
[email protected]
   369
        scanner_.scan();
[email protected]
   370
        Expression *expr = unary();
[email protected]
   371
        if (!expr)
[email protected]
   372
            return NULL;
[email protected]
   373
        return new (pool_) IncDecExpression(pos, token, expr, false);
[email protected]
   374
      }
[email protected]
   375
[email protected]
   376
      case TOK_MINUS:
[email protected]
   377
      case TOK_NOT:
[email protected]
   378
      case TOK_TILDE:
[email protected]
   379
      {
[email protected]
   380
        scanner_.scan();
[email protected]
   381
        Expression *expr = unary();
[email protected]
   382
        if (!expr)
[email protected]
   383
            return NULL;
[email protected]
   384
        return new (pool_) UnaryExpression(pos, token, expr);
[email protected]
   385
      }
[email protected]
   386
[email protected]
   387
      case TOK_SIZEOF:
[email protected]
   388
      {
[email protected]
   389
        scanner_.scan();
[email protected]
   390
        if (!expect(TOK_LPAREN))
[email protected]
   391
            return NULL;
[email protected]
   392
        Expression *expr = unary();
[email protected]
   393
        if (!expr)
[email protected]
   394
            return NULL;
[email protected]
   395
        if (!expect(TOK_RPAREN))
[email protected]
   396
            return NULL;
[email protected]
   397
        return new (pool_) UnaryExpression(pos, token, expr);
[email protected]
   398
      }
[email protected]
   399
[email protected]
   400
      case TOK_LABEL:
[email protected]
   401
      {
[email protected]
   402
        scanner_.scan();
[email protected]
   403
        Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
[email protected]
   404
        if (!tag)
[email protected]
   405
            return NULL;
[email protected]
   406
[email protected]
   407
        NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), tag);
[email protected]
   408
[email protected]
   409
        Expression *expr = unary();
[email protected]
   410
        if (!expr)
[email protected]
   411
            return NULL;
[email protected]
   412
[email protected]
   413
        return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, proxy);
[email protected]
   414
      }
[email protected]
   415
[email protected]
   416
      default:
[email protected]
   417
        break;
[email protected]
   418
    }
[email protected]
   419
[email protected]
   420
    Expression *expr = primary();
[email protected]
   421
[email protected]
   422
    token = scanner_.peek();
[email protected]
   423
    if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
[email protected]
   424
        scanner_.scan();
[email protected]
   425
        return new (pool_) IncDecExpression(pos, token, expr, true);
[email protected]
   426
    }
[email protected]
   427
[email protected]
   428
    return expr;
[email protected]
   429
}
[email protected]
   430
[email protected]
   431
Expression *
[email protected]
   432
Parser::multiplication()
[email protected]
   433
{
[email protected]
   434
    Expression *left = unary();
[email protected]
   435
    do {
[email protected]
   436
        if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
[email protected]
   437
            break;
[email protected]
   438
        SourcePosition pos = scanner_.begin();
[email protected]
   439
        TokenKind kind = scanner_.last();
[email protected]
   440
        Expression *right = unary();
[email protected]
   441
        if (!right)
[email protected]
   442
            return NULL;
[email protected]
   443
        left = new (pool_) BinaryExpression(pos, kind, left, right);
[email protected]
   444
    } while (left);
[email protected]
   445
    return left;
[email protected]
   446
}
[email protected]
   447
[email protected]
   448
Expression *
[email protected]
   449
Parser::addition()
[email protected]
   450
{
[email protected]
   451
    Expression *left = multiplication();
[email protected]
   452
    while (left) {
[email protected]
   453
        if (!match(TOK_PLUS) && !match(TOK_MINUS))
[email protected]
   454
            break;
[email protected]
   455
        SourcePosition pos = scanner_.begin();
[email protected]
   456
        TokenKind kind = scanner_.last();
[email protected]
   457
        Expression *right = multiplication();
[email protected]
   458
        if (!right)
[email protected]
   459
            return NULL;
[email protected]
   460
        left = new (pool_) BinaryExpression(pos, kind, left, right);
[email protected]
   461
    }
[email protected]
   462
    return left;
[email protected]
   463
}
[email protected]
   464
[email protected]
   465
Expression *
[email protected]
   466
Parser::shift()
[email protected]
   467
{
[email protected]
   468
    Expression *left = addition();
[email protected]
   469
    while (left) {
[email protected]
   470
        if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
[email protected]
   471
            break;
[email protected]
   472
        SourcePosition pos = scanner_.begin();
[email protected]
   473
        TokenKind kind = scanner_.last();
[email protected]
   474
        Expression *right = addition();
[email protected]
   475
        if (!right)
[email protected]
   476
            return NULL;
[email protected]
   477
        left = new (pool_) BinaryExpression(pos, kind, left, right);
[email protected]
   478
    }
[email protected]
   479
    return left;
[email protected]
   480
}
[email protected]
   481
[email protected]
   482
Expression *
[email protected]
   483
Parser::bitand_()
[email protected]
   484
{
[email protected]
   485
    Expression *left = shift();
[email protected]
   486
    while (left) {
[email protected]
   487
        if (!match(TOK_BITAND))
[email protected]
   488
            break;
[email protected]
   489
        SourcePosition pos = scanner_.begin();
[email protected]
   490
        Expression *right = shift();
[email protected]
   491
        if (!right)
[email protected]
   492
            return NULL;
[email protected]
   493
        left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
[email protected]
   494
    }
[email protected]
   495
    return left;
[email protected]
   496
}
[email protected]
   497
[email protected]
   498
Expression *
[email protected]
   499
Parser::bitxor()
[email protected]
   500
{
[email protected]
   501
    Expression *left = bitand_();
[email protected]
   502
    while (left) {
[email protected]
   503
        if (!match(TOK_BITXOR))
[email protected]
   504
            break;
[email protected]
   505
        SourcePosition pos = scanner_.begin();
[email protected]
   506
        Expression *right = shift();
[email protected]
   507
        if (!right)
[email protected]
   508
            return NULL;
[email protected]
   509
        left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
[email protected]
   510
    }
[email protected]
   511
    return left;
[email protected]
   512
}
[email protected]
   513
[email protected]
   514
Expression *
[email protected]
   515
Parser::bitor_()
[email protected]
   516
{
[email protected]
   517
    Expression *left = bitxor();
[email protected]
   518
    while (left) {
[email protected]
   519
        if (!match(TOK_BITOR))
[email protected]
   520
            break;
[email protected]
   521
        SourcePosition pos = scanner_.begin();
[email protected]
   522
        Expression *right = bitxor();
[email protected]
   523
        if (!right)
[email protected]
   524
            return NULL;
[email protected]
   525
        left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
[email protected]
   526
    }
[email protected]
   527
    return left;
[email protected]
   528
}
[email protected]
   529
[email protected]
   530
Expression *
[email protected]
   531
Parser::relational()
[email protected]
   532
{
[email protected]
   533
    Expression *left = bitor_();
[email protected]
   534
    while (left) {
[email protected]
   535
        TokenKind kind = scanner_.peek();
[email protected]
   536
        if (kind < TOK_LT || kind > TOK_GE)
[email protected]
   537
            break;
[email protected]
   538
        scanner_.scan();
[email protected]
   539
        SourcePosition pos = scanner_.begin();
[email protected]
   540
        Expression *right = shift();
[email protected]
   541
        if (!right)
[email protected]
   542
            return NULL;
[email protected]
   543
        left = new (pool_) BinaryExpression(pos, kind, left, right);
[email protected]
   544
    }
[email protected]
   545
    return left;
[email protected]
   546
}
[email protected]
   547
[email protected]
   548
Expression *
[email protected]
   549
Parser::equals()
[email protected]
   550
{
[email protected]
   551
    Expression *left = relational();
[email protected]
   552
    while (left) {
[email protected]
   553
        if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
[email protected]
   554
            break;
[email protected]
   555
        TokenKind kind = scanner_.last();
[email protected]
   556
        SourcePosition pos = scanner_.begin();
[email protected]
   557
        Expression *right = relational();
[email protected]
   558
        if (!right)
[email protected]
   559
            return NULL;
[email protected]
   560
        left = new (pool_) BinaryExpression(pos, kind, left, right);
[email protected]
   561
    }
[email protected]
   562
    return left;
[email protected]
   563
}
[email protected]
   564
[email protected]
   565
Expression *
[email protected]
   566
Parser::and_()
[email protected]
   567
{
[email protected]
   568
    Expression *left = equals();
[email protected]
   569
    while (left) {
[email protected]
   570
        if (!match(TOK_AND))
[email protected]
   571
            break;
[email protected]
   572
        SourcePosition pos = scanner_.begin();
[email protected]
   573
        Expression *right = equals();
[email protected]
   574
        if (!right)
[email protected]
   575
            return NULL;
[email protected]
   576
        left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
[email protected]
   577
    }
[email protected]
   578
    return left;
[email protected]
   579
}
[email protected]
   580
[email protected]
   581
Expression *
[email protected]
   582
Parser::or_()
[email protected]
   583
{
[email protected]
   584
    Expression *left = and_();
[email protected]
   585
    while (left) {
[email protected]
   586
        if (!match(TOK_OR))
[email protected]
   587
            break;
[email protected]
   588
        SourcePosition pos = scanner_.begin();
[email protected]
   589
        Expression *right = and_();
[email protected]
   590
        if (!right)
[email protected]
   591
            return NULL;
[email protected]
   592
        left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
[email protected]
   593
    }
[email protected]
   594
    return left;
[email protected]
   595
}
[email protected]
   596
[email protected]
   597
Expression *
[email protected]
   598
Parser::ternary()
[email protected]
   599
{
[email protected]
   600
    Expression *cond = or_();
[email protected]
   601
    if (!cond)
[email protected]
   602
        return NULL;
[email protected]
   603
    
[email protected]
   604
    if (!match(TOK_QMARK))
[email protected]
   605
        return cond;
[email protected]
   606
[email protected]
   607
    Expression *left;
[email protected]
   608
    SourcePosition pos = scanner_.begin();
[email protected]
   609
    AutoAllowTags<false> disableTags(scanner_);
[email protected]
   610
    {
[email protected]
   611
        if ((left = expression()) == NULL)
[email protected]
   612
            return NULL;
[email protected]
   613
    }
[email protected]
   614
[email protected]
   615
    if (!expect(TOK_COLON))
[email protected]
   616
        return NULL;
[email protected]
   617
[email protected]
   618
    Expression *right = expression();
[email protected]
   619
    if (!right)
[email protected]
   620
        return NULL;
[email protected]
   621
[email protected]
   622
    return new (pool_) TernaryExpression(pos, cond, left, right);
[email protected]
   623
}
[email protected]
   624
[email protected]
   625
Expression *
[email protected]
   626
Parser::assignment()
[email protected]
   627
{
[email protected]
   628
    Expression *left = ternary();
[email protected]
   629
    while (left) {
[email protected]
   630
        TokenKind token = scanner_.peek();
[email protected]
   631
        if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
d[email protected]
   632
            break;
[email protected]
   633
        scanner_.scan();
[email protected]
   634
        SourcePosition pos = scanner_.begin();
[email protected]
   635
        Expression *expr = ternary();
[email protected]
   636
        if (!expr)
[email protected]
   637
            return NULL;
[email protected]
   638
[email protected]
   639
        left = new (pool_) Assignment(pos, token, left, expr);
d[email protected]
   640
    }
[email protected]
   641
    return left;
[email protected]
   642
}
[email protected]
   643
[email protected]
   644
Expression *
[email protected]
   645
Parser::expression()
[email protected]
   646
{
[email protected]
   647
    return assignment();
[email protected]
   648
}
[email protected]
   649
[email protected]
   650
Statement *
[email protected]
   651
Parser::while_()
[email protected]
   652
{
[email protected]
   653
    // while ::= "while" "(" expr ")" statement
[email protected]
   654
    SourcePosition pos = scanner_.begin();
[email protected]
   655
    scanner_.scan();
[email protected]
   656
[email protected]
   657
    if (!expect(TOK_LPAREN))
[email protected]
   658
        return NULL;
[email protected]
   659
[email protected]
   660
    Expression *condition = expression();
[email protected]
   661
    if (!condition)
[email protected]
   662
        return NULL;
[email protected]
   663
[email protected]
   664
    if (!expect(TOK_RPAREN))
[email protected]
   665
        return NULL;
[email protected]
   666
[email protected]
   667
    Statement *body;
[email protected]
   668
    if (scanner_.peek() == TOK_LBRACE)
[email protected]
   669
        body = block();
[email protected]
   670
    else
[email protected]
   671
        body = localStatement();
[email protected]
   672
    if (!body)
[email protected]
   673
        return NULL;
[email protected]
   674
[email protected]
   675
    return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
[email protected]
   676
}
[email protected]
   677
[email protected]
   678
Statement *
[email protected]
   679
Parser::do_()
[email protected]
   680
{
[email protected]
   681
    // do ::= "do" block "while" "(" expr ")"
[email protected]
   682
    SourcePosition pos = scanner_.begin();
[email protected]
   683
    scanner_.scan();
[email protected]
   684
[email protected]
   685
    Statement *body = block();
[email protected]
   686
    if (!body)
[email protected]
   687
        return NULL;
[email protected]
   688
[email protected]
   689
    if (!expect(TOK_WHILE))
[email protected]
   690
        return NULL;
[email protected]
   691
[email protected]
   692
    if (!expect(TOK_LPAREN))
[email protected]
   693
        return NULL;
[email protected]
   694
    Expression *condition = expression();
[email protected]
   695
    if (!condition)
[email protected]
   696
        return NULL;
[email protected]
   697
    if (!expect(TOK_RPAREN))
[email protected]
   698
        return NULL;
[email protected]
   699
[email protected]
   700
    return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
[email protected]
   701
}
[email protected]
   702
[email protected]
   703
Statement *
[email protected]
   704
Parser::switch_()
[email protected]
   705
{
[email protected]
   706
    // switch ::= "switch" "(" expr ")" "{" case* defaultcase? "}"
[email protected]
   707
    // case ::= "case" casevals ":" statement
[email protected]
   708
    // defaultcase ::= "default" ":" statement
[email protected]
   709
    //
[email protected]
   710
    expect(TOK_SWITCH);
[email protected]
   711
[email protected]
   712
    SourcePosition pos = scanner_.begin();
[email protected]
   713
[email protected]
   714
    if (!expect(TOK_LPAREN))
[email protected]
   715
        return NULL;
[email protected]
   716
    Expression *expr = expression();
[email protected]
   717
    if (!expr)
[email protected]
   718
        return NULL;
[email protected]
   719
    if (!expect(TOK_RPAREN))
[email protected]
   720
        return NULL;
[email protected]
   721
[email protected]
   722
    if (!expect(TOK_LBRACE))
[email protected]
   723
        return NULL;
[email protected]
   724
[email protected]
   725
    SourcePosition defaultPos;
[email protected]
   726
    PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
[email protected]
   727
[email protected]
   728
    Statement *defaultCase = NULL;
[email protected]
   729
[email protected]
   730
    while (!peek(TOK_RBRACE)) {
[email protected]
   731
        Expression *expr = NULL;
[email protected]
   732
        ExpressionList *others = NULL;
[email protected]
   733
        if (match(TOK_DEFAULT)) {
[email protected]
   734
            if (defaultCase) {
[email protected]
   735
                cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
[email protected]
   736
                return NULL;
[email protected]
   737
            }
[email protected]
   738
[email protected]
   739
            defaultPos = scanner_.begin();
[email protected]
   740
        } else {
[email protected]
   741
            if (defaultCase) {
[email protected]
   742
                cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
[email protected]
   743
                return NULL;
[email protected]
   744
            }
[email protected]
   745
[email protected]
   746
            if (!expect(TOK_CASE))
[email protected]
   747
                return NULL;
[email protected]
   748
[email protected]
   749
            // A limitation in the grammar is that |case <NAME>:| will be
[email protected]
   750
            // detected as a label.
[email protected]
   751
            AutoAllowTags<false> disableTags(scanner_);
[email protected]
   752
[email protected]
   753
            if ((expr = expression()) == NULL)
[email protected]
   754
                return NULL;
[email protected]
   755
[email protected]
   756
            if (peek(TOK_COMMA)) {
[email protected]
   757
                others = new (pool_) ExpressionList();
[email protected]
   758
                while (match(TOK_COMMA)) {
[email protected]
   759
                    Expression *other = expression();
[email protected]
   760
                    if (!other)
[email protected]
   761
                        return NULL;
[email protected]
   762
                    if (!others->append(other))
[email protected]
   763
                        return NULL;
[email protected]
   764
                }
[email protected]
   765
            }
[email protected]
   766
        }
[email protected]
   767
[email protected]
   768
        if (!expect(TOK_COLON))
[email protected]
   769
            return NULL;
[email protected]
   770
[email protected]
   771
        Statement *statement = localStatement();
[email protected]
   772
        if (!statement)
[email protected]
   773
            return NULL;
[email protected]
   774
[email protected]
   775
        if (!peek(TOK_CASE) &&
[email protected]
   776
            !peek(TOK_DEFAULT) &&
[email protected]
   777
            !peek(TOK_RBRACE))
[email protected]
   778
        {
[email protected]
   779
            cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
[email protected]
   780
            return NULL;
[email protected]
   781
        }
[email protected]
   782
[email protected]
   783
        if (expr) {
[email protected]
   784
            Case *caze = new (pool_) Case(expr, others, statement);
[email protected]
   785
            if (!cases->append(caze))
[email protected]
   786
                return NULL;
[email protected]
   787
        } else {
[email protected]
   788
            defaultCase = statement;
[email protected]
   789
        }
[email protected]
   790
    }
[email protected]
   791
[email protected]
   792
    if (!expect(TOK_RBRACE))
[email protected]
   793
        return NULL;
[email protected]
   794
[email protected]
   795
    return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
[email protected]
   796
}
[email protected]
   797
[email protected]
   798
Statement *
[email protected]
   799
Parser::forStatement()
[email protected]
   800
{
[email protected]
   801
    // for ::= "for" "(" forinit? ";" forcond? ";" forstep ")" statement
[email protected]
   802
    // forint ::= "new" vardecl |
[email protected]
   803
    //            exprstmt
[email protected]
   804
    // forcond ::= expr
[email protected]
   805
    // forstep ::= exprstmt
[email protected]
   806
    //
[email protected]
   807
    SourcePosition pos = scanner_.begin();
[email protected]
   808
    scanner_.scan();
[email protected]
   809
    if (!expect(TOK_LPAREN))
[email protected]
   810
        return NULL;
[email protected]
   811
[email protected]
   812
    Statement *decl = NULL;
[email protected]
   813
    if (!match(TOK_SEMICOLON)) {
[email protected]
   814
        if (match(TOK_NEW)) {
[email protected]
   815
            if ((decl = vars(TypeQual_None)) == NULL)
[email protected]
   816
                return NULL;
[email protected]
   817
        } else {
[email protected]
   818
            if ((decl = expressionStatement()) == NULL)
[email protected]
   819
                return NULL;
[email protected]
   820
        }
[email protected]
   821
        if (!expect(TOK_SEMICOLON))
[email protected]
   822
            return NULL;
[email protected]
   823
    }
[email protected]
   824
[email protected]
   825
    Expression *condition = NULL;
[email protected]
   826
    if (!match(TOK_SEMICOLON)) {
[email protected]
   827
        if ((condition = expression()) == NULL)
[email protected]
   828
            return NULL;
[email protected]
   829
        if (!expect(TOK_SEMICOLON))
[email protected]
   830
            return NULL;
[email protected]
   831
    }
[email protected]
   832
[email protected]
   833
    Statement *update = NULL;
[email protected]
   834
    if (!match(TOK_RPAREN)) {
[email protected]
   835
        if ((update = expressionStatement()) == NULL)
[email protected]
   836
            return NULL;
[email protected]
   837
        if (!expect(TOK_RPAREN))
[email protected]
   838
            return NULL;
[email protected]
   839
    }
[email protected]
   840
[email protected]
   841
    Statement *body;
[email protected]
   842
    if (scanner_.peek() == TOK_LBRACE)
[email protected]
   843
        body = block();
[email protected]
   844
    else
[email protected]
   845
        body = localStatement();
[email protected]
   846
    if (!body)
[email protected]
   847
        return NULL;
[email protected]
   848
[email protected]
   849
    return new (pool_) ForStatement(pos, decl, condition, update, body);
[email protected]
   850
}
[email protected]
   851
[email protected]
   852
ExpressionList *
[email protected]
   853
Parser::dimensions()
[email protected]
   854
{
[email protected]
   855
    // dimensions ::= ("[" expr? "]")*
[email protected]
   856
[email protected]
   857
    ExpressionList *postDimensions = new (pool_) ExpressionList();
[email protected]
   858
    while (match(TOK_LBRACKET)) {
[email protected]
   859
        Expression *dim = NULL;
[email protected]
   860
        if (!match(TOK_RBRACKET)) {
[email protected]
   861
            if ((dim = expression()) == NULL)
[email protected]
   862
                return NULL;
[email protected]
   863
            if (!expect(TOK_RBRACKET))
[email protected]
   864
                return NULL;
[email protected]
   865
        }
[email protected]
   866
[email protected]
   867
        if (!postDimensions->append(dim))
[email protected]
   868
            return NULL;
[email protected]
   869
    }
[email protected]
   870
    return postDimensions;
[email protected]
   871
}
[email protected]
   872
[email protected]
   873
VariableDeclaration *
[email protected]
   874
Parser::var(TypeQualifiers qual)
[email protected]
   875
{
[email protected]
   876
    // vardecl ::= decl ("=" expr)?
[email protected]
   877
[email protected]
   878
    Expression *type;
[email protected]
   879
    Local<String> name(zone_);
[email protected]
   880
[email protected]
   881
    if (!typeAndName(&type, name.ref()))
[email protected]
   882
        return NULL;
[email protected]
   883
[email protected]
   884
    ExpressionList *dims = NULL;
[email protected]
   885
    if (peek(TOK_LBRACKET)) {
[email protected]
   886
        if ((dims = dimensions()) == NULL)
[email protected]
   887
            return NULL;;
[email protected]
   888
    }
[email protected]
   889
[email protected]
   890
    SourcePosition pos = scanner_.begin();
[email protected]
   891
    
[email protected]
   892
    Expression *expr = NULL;
[email protected]
   893
    if (match(TOK_ASSIGN)) {
[email protected]
   894
        switch (scanner_.peek()) {
[email protected]
   895
          // Note: we don't support [] literals yet.
[email protected]
   896
          case TOK_LBRACE:
[email protected]
   897
            scanner_.scan();
[email protected]
   898
            if ((expr = fixedArrayLiteral()) == NULL)
[email protected]
   899
                return NULL;
[email protected]
   900
            break;
[email protected]
   901
[email protected]
   902
          default:
[email protected]
   903
            if ((expr = expression()) == NULL)
[email protected]
   904
                return NULL;
[email protected]
   905
            break;
[email protected]
   906
        }
[email protected]
   907
    }
[email protected]
   908
[email protected]
   909
    return new (pool_) VariableDeclaration(pos, qual, name, type, dims, expr);
[email protected]
   910
}
[email protected]
   911
[email protected]
   912
Statement *
[email protected]
   913
Parser::vars(TypeQualifiers qual)
[email protected]
   914
{
[email protected]
   915
    // localvars ::= ("new" | "const" | "decl") vardecl ("," vardecl)*
[email protected]
   916
    // globalvars ::= ("public" | "const" | "new" | "public" "const") vardecl
[email protected]
   917
    VariableDeclaration *decl = var(qual);
[email protected]
   918
    if (!decl)
[email protected]
   919
        return NULL;
[email protected]
   920
[email protected]
   921
    if (!peek(TOK_COMMA))
[email protected]
   922
        return decl;
[email protected]
   923
[email protected]
   924
    StatementList *statements = new (pool_) StatementList();
[email protected]
   925
    if (!statements->append(decl))
[email protected]
   926
        return NULL;
[email protected]
   927
[email protected]
   928
    while (match(TOK_COMMA)) {
[email protected]
   929
        Statement *decl = var(qual);
[email protected]
   930
        if (!decl)
[email protected]
   931
            return NULL;
[email protected]
   932
        if (!statements->append(decl))
[email protected]
   933
            return NULL;
[email protected]
   934
    }
[email protected]
   935
[email protected]
   936
    // Create a fake-o block with no scope to create a statement list.
[email protected]
   937
    return new (pool_) BlockStatement(decl->pos(), statements, TOK_NEW);
[email protected]
   938
}
[email protected]
   939
[email protected]
   940
Statement *
[email protected]
   941
Parser::returnStatement()
[email protected]
   942
{
[email protected]
   943
    // return ::= "return" term |
[email protected]
   944
    //            "return" "expr"
[email protected]
   945
[email protected]
   946
    SourcePosition pos = scanner_.begin();
[email protected]
   947
    if (!expect(TOK_RETURN))
[email protected]
   948
        return NULL;
[email protected]
   949
[email protected]
   950
    Expression *expr = NULL;
[email protected]
   951
    if (scanner_.peek() != TOK_SEMICOLON) {
[email protected]
   952
        if ((expr = expression()) == NULL)
[email protected]
   953
            return NULL;
[email protected]
   954
[email protected]
   955
        // We only care about non-void returns when determining whether a
[email protected]
   956
        // tagless function is non-void.
[email protected]
   957
        encounteredReturn_ = true;
[email protected]
   958
    }
[email protected]
   959
[email protected]
   960
    return new (pool_) ReturnStatement(pos, expr);
[email protected]
   961
}
[email protected]
   962
[email protected]
   963
Statement *
[email protected]
   964
Parser::expressionStatement()
[email protected]
   965
{
[email protected]
   966
    // exprstmt ::= expr
[email protected]
   967
    Expression *left = assignment();
[email protected]
   968
    if (!left)
[email protected]
   969
        return NULL;
[email protected]
   970
[email protected]
   971
    return new (pool_) ExpressionStatement(left);
[email protected]
   972
}
[email protected]
   973
[email protected]
   974
Statement *
[email protected]
   975
Parser::block()
[email protected]
   976
{
[email protected]
   977
    // block ::= "{" statement* "}"
[email protected]
   978
[email protected]
   979
    if (!expect(TOK_LBRACE))
[email protected]
   980
        return NULL;
[email protected]
   981
[email protected]
   982
    SourcePosition pos = scanner_.begin();
[email protected]
   983
[email protected]
   984
    StatementList *statements = new (pool_) StatementList();
[email protected]
   985
    while (!match(TOK_RBRACE)) {
[email protected]
   986
        Statement *statement = localStatement();
[email protected]
   987
        if (statement == NULL)
[email protected]
   988
            return NULL;
[email protected]
   989
        if (!statements->append(statement))
[email protected]
   990
            return NULL;
[email protected]
   991
    }
[email protected]
   992
[email protected]
   993
    BlockStatement *block = new (pool_) BlockStatement(pos, statements, TOK_LBRACE);
[email protected]
   994
    return block;
[email protected]
   995
}
[email protected]
   996
[email protected]
   997
Statement *
[email protected]
   998
Parser::if_()
[email protected]
   999
{
[email protected]
  1000
    // if ::= "if" "(" expr ")" statement elseif* else?
[email protected]
  1001
    // elseif ::= "elseif" "(" expr ")" statement
[email protected]
  1002
    // else ::= "else" statement
[email protected]
  1003
    expect(TOK_IF);
[email protected]
  1004
  
[email protected]
  1005
    SourcePosition pos = scanner_.begin();
[email protected]
  1006
    if (!expect(TOK_LPAREN))
[email protected]
  1007
        return NULL;
[email protected]
  1008
[email protected]
  1009
    Expression *cond = expression();
dv[email protected]
  1010
    if (!cond)
[email protected]
  1011
        return NULL;
[email protected]
  1012
[email protected]
  1013
    if (!expect(TOK_RPAREN))
[email protected]
  1014
        return NULL;
[email protected]
  1015
[email protected]
  1016
    Statement *ifTrue = localStatement();
[email protected]
  1017
    if (!ifTrue)
[email protected]
  1018
        return NULL;
[email protected]
  1019
[email protected]
  1020
    IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
[email protected]
  1021
[email protected]
  1022
    IfStatement *last = outer;
[email protected]
  1023
    while (match(TOK_ELSE)) {
[email protected]
  1024
        if (!match(TOK_IF)) {
[email protected]
  1025
            Statement *ifFalse = localStatement();
[email protected]
  1026
            if (!ifFalse)
[email protected]
  1027
                return NULL;
[email protected]
  1028
[email protected]
  1029
            last->setIfFalse(ifFalse);
[email protected]
  1030
            break;
[email protected]
  1031
        }
[email protected]
  1032
[email protected]
  1033
        SourcePosition pos = scanner_.begin();
[email protected]
  1034
        if (!expect(TOK_LPAREN))
[email protected]
  1035
            return NULL;
[email protected]
  1036
[email protected]
  1037
        Expression *otherCond = expression();
[email protected]
  1038
        if (!otherCond)
[email protected]
  1039
            return NULL;
[email protected]
  1040
[email protected]
  1041
        if (!expect(TOK_RPAREN))
[email protected]
  1042
            return NULL;
[email protected]
  1043
[email protected]
  1044
        Statement *otherIfTrue = localStatement();
[email protected]
  1045
        if (!otherIfTrue)
[email protected]
  1046
            return NULL;
[email protected]
  1047
[email protected]
  1048
        IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
[email protected]
  1049
        last->setIfFalse(inner);
[email protected]
  1050
        last = inner;
[email protected]
  1051
    }
[email protected]
  1052
[email protected]
  1053
    return outer;
[email protected]
  1054
}
[email protected]
  1055
[email protected]
  1056
Statement *
[email protected]
  1057
Parser::localStatement()
[email protected]
  1058
{
[email protected]
  1059
    // statement ::= stmt term
[email protected]
  1060
    // stmt ::= do | for | if | while | struct | enum |
[email protected]
  1061
    //          localvars | return | switch | break | continue
[email protected]
  1062
[email protected]
  1063
    Statement *statement = NULL;
[email protected]
  1064
[email protected]
  1065
    // Statements which must be followed by a semicolon will break out of the
[email protected]
  1066
    // switch. If they may end in BlockStatements, they'll immediately return.
[email protected]
  1067
[email protected]
  1068
    TokenKind kind = scanner_.peek();
[email protected]
  1069
    switch (kind) {
[email protected]
  1070
      case TOK_CONST:
[email protected]
  1071
      case TOK_NEW:
[email protected]
  1072
      {
[email protected]
  1073
        TypeQualifiers quals = (kind == TOK_CONST)
[email protected]
  1074
                              ? TypeQual_Const
[email protected]
  1075
                              : TypeQual_None;
[email protected]
  1076
        scanner_.scan();
[email protected]
  1077
        if ((statement = vars(quals)) == NULL)
[email protected]
  1078
          return NULL;
[email protected]
  1079
        break;
[email protected]
  1080
      }
[email protected]
  1081
[email protected]
  1082
      case TOK_FOR:
[email protected]
  1083
        return forStatement();
[email protected]
  1084
[email protected]
  1085
      case TOK_WHILE:
[email protected]
  1086
        return while_();
[email protected]
  1087
[email protected]
  1088
      case TOK_BREAK:
[email protected]
  1089
        scanner_.scan();
[email protected]
  1090
        statement = new (pool_) BreakStatement(scanner_.begin());
[email protected]
  1091
        break;
[email protected]
  1092
[email protected]
  1093
      case TOK_CONTINUE:
[email protected]
  1094
        scanner_.scan();
[email protected]
  1095
        statement = new (pool_) ContinueStatement(scanner_.begin());
[email protected]
  1096
        break;
[email protected]
  1097
[email protected]
  1098
      case TOK_DO:
[email protected]
  1099
        if ((statement = do_()) == NULL)
[email protected]
  1100
            return NULL;
[email protected]
  1101
        break;
[email protected]
  1102
[email protected]
  1103
      case TOK_RETURN:
[email protected]
  1104
        if ((statement = returnStatement()) == NULL)
[email protected]
  1105
          return NULL;
[email protected]
  1106
        break;
[email protected]
  1107
[email protected]
  1108
      case TOK_ENUM:
[email protected]
  1109
        if ((statement = enum_()) == NULL)
[email protected]
  1110
          return NULL;
[email protected]
  1111
        break;
[email protected]
  1112
[email protected]
  1113
      case TOK_STRUCT:
[email protected]
  1114
        if ((statement = struct_()) == NULL)
[email protected]
  1115
          return NULL;
[email protected]
  1116
        break;
[email protected]
  1117
[email protected]
  1118
      case TOK_SWITCH:
[email protected]
  1119
        return switch_();
[email protected]
  1120
[email protected]
  1121
      case TOK_IF:
[email protected]
  1122
        return if_();
[email protected]
  1123
[email protected]
  1124
      case TOK_LBRACE:
[email protected]
  1125
        return block();
[email protected]
  1126
[email protected]
  1127
      default:
[email protected]
  1128
        break;
[email protected]
  1129
    }
[email protected]
  1130
[email protected]
  1131
    if (!statement) {
[email protected]
  1132
        if ((statement = expressionStatement()) == NULL)
[email protected]
  1133
            return NULL;
[email protected]
  1134
    }
[email protected]
  1135
[email protected]
  1136
    if (!expect(TOK_SEMICOLON))
[email protected]
  1137
        return NULL;
[email protected]
  1138
[email protected]
  1139
    return statement;
[email protected]
  1140
}
[email protected]
  1141
[email protected]
  1142
Statement *
[email protected]
  1143
Parser::struct_()
[email protected]
  1144
{
[email protected]
  1145
    // struct ::= "struct" name { struct_fields }
[email protected]
  1146
    // struct_fields ::= struct_field |
[email protected]
  1147
    //                   struct_field struct_fields
[email protected]
  1148
    // struct_field ::= label? name term
[email protected]
  1149
    expect(TOK_STRUCT);
[email protected]
  1150
[email protected]
  1151
    Local<String> name(zone_, expectName());
[email protected]
  1152
    if (!name)
[email protected]
  1153
        return NULL;
[email protected]
  1154
[email protected]
  1155
    SourcePosition pos = scanner_.begin();
[email protected]
  1156
[email protected]
  1157
    if (!expect(TOK_LBRACE))
[email protected]
  1158
        return NULL;
[email protected]
  1159
[email protected]
  1160
    FieldList *fields = new (pool_) FieldList();
[email protected]
  1161
[email protected]
  1162
    while (!peek(TOK_RBRACE)) {
[email protected]
  1163
        Expression *type;
[email protected]
  1164
        Local<String> fieldName(zone_);
[email protected]
  1165
[email protected]
  1166
        if (!fullTypeAndName(&type, fieldName.ref(), DeclField))
[email protected]
  1167
            return NULL;
[email protected]
  1168
[email protected]
  1169
        SourcePosition pos = scanner_.begin();
[email protected]
  1170
[email protected]
  1171
        if (!matchSemicolon())
[email protected]
  1172
            return NULL;
[email protected]
  1173
[email protected]
  1174
        StructureStatement::Field *field =
[email protected]
  1175
            new (pool_) StructureStatement::Field(pos, type, fieldName);
[email protected]
  1176
        if (!field || !fields->append(field))
[email protected]
  1177
            return NULL;
[email protected]
  1178
    }
[email protected]
  1179
[email protected]
  1180
    if (!expect(TOK_RBRACE))
[email protected]
  1181
        return NULL;
[email protected]
  1182
[email protected]
  1183
    if (fields->empty()) {
[email protected]
  1184
        cc_.reportError(pos, Message_StructCantBeEmpty);
[email protected]
  1185
        return NULL;
[email protected]
  1186
    }
[email protected]
  1187
[email protected]
  1188
    return new (pool_) StructureStatement(pos, name, fields);
[email protected]
  1189
}
[email protected]
  1190
[email protected]
  1191
Statement *
[email protected]
  1192
Parser::enum_()
[email protected]
  1193
{
[email protected]
  1194
    // enum ::= "enum" name? { enum_members? }
[email protected]
  1195
    // enum_members ::= enum_member ","? |
[email protected]
  1196
    //                  enum_member "," enum_members
[email protected]
  1197
    // enum_member ::= ident ("=" constexpr)?
[email protected]
  1198
    expect(TOK_ENUM);
[email protected]
  1199
[email protected]
  1200
    SourcePosition pos = scanner_.begin();
[email protected]
  1201
[email protected]
  1202
    Local<String> name(zone_);
[email protected]
  1203
    if (matchName(name.ref()) && !name)
[email protected]
  1204
        return NULL;
[email protected]
  1205
[email protected]
  1206
    EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
[email protected]
  1207
[email protected]
  1208
    if (!expect(TOK_LBRACE))
[email protected]
  1209
        return NULL;
[email protected]
  1210
[email protected]
  1211
    do {
[email protected]
  1212
        if (scanner_.peek() == TOK_RBRACE)
[email protected]
  1213
            break;
[email protected]
  1214
[email protected]
  1215
        SourcePosition pos = scanner_.begin();
[email protected]
  1216
        Local<String> name(zone_, expectName());
[email protected]
  1217
        if (!name)
[email protected]
  1218
            return NULL;
[email protected]
  1219
[email protected]
  1220
        Expression *expr = NULL;
[email protected]
  1221
        if (match(TOK_ASSIGN)) {
[email protected]
  1222
            if ((expr = expression()) == NULL)
[email protected]
  1223
                return NULL;
[email protected]
  1224
        }
[email protected]
  1225
[email protected]
  1226
        if (!entries->append(EnumStatement::Entry(name, expr, pos)))
[email protected]
  1227
            return NULL;
[email protected]
  1228
    } while (match(TOK_COMMA));
[email protected]
  1229
    if (!expect(TOK_RBRACE))
[email protected]
  1230
        return NULL;
[email protected]
  1231
[email protected]
  1232
    return new (pool_) EnumStatement(pos, name, entries);
[email protected]
  1233
}
[email protected]
  1234
[email protected]
  1235
template <class T>
[email protected]
  1236
static inline ScopedRoot<T> *
[email protected]
  1237
NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
[email protected]
  1238
{
[email protected]
  1239
    return new (pool) ScopedRoot<T>(obj);
[email protected]
  1240
}
[email protected]
  1241
[email protected]
  1242
ImportStatement *
[email protected]
  1243
Parser::import()
[email protected]
  1244
{
[email protected]
  1245
    SourcePosition pos = scanner_.begin();
[email protected]
  1246
[email protected]
  1247
    // import       ::= import_path
[email protected]
  1248
    // import_path  ::= name |
[email protected]
  1249
    //                  name "." import_path
[email protected]
  1250
[email protected]
  1251
    Local<String> name(zone_, expectName());
[email protected]
  1252
    if (!name)
[email protected]
  1253
        return NULL;
[email protected]
  1254
[email protected]
  1255
    PathComponent *root = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
[email protected]
  1256
    PathComponent *current = root;
[email protected]
  1257
[email protected]
  1258
    TokenKind suffix = TOK_NONE;
[email protected]
  1259
    while (match(TOK_DOT)) {
[email protected]
  1260
        if ((name = expectName()) == NULL)
[email protected]
  1261
            return NULL;
[email protected]
  1262
[email protected]
  1263
        current->next = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
[email protected]
  1264
        current = current->next;
[email protected]
  1265
    }
[email protected]
  1266
[email protected]
  1267
    return new (pool_) ImportStatement(pos, root);
[email protected]
  1268
}
[email protected]
  1269
[email protected]
  1270
Statement *
[email protected]
  1271
Parser::function(TokenKind token)
[email protected]
  1272
{
[email protected]
  1273
    Expression *returnType;
[email protected]
  1274
    Local<String> name(zone_);
[email protected]
  1275
[email protected]
  1276
    if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
[email protected]
  1277
        return NULL;
[email protected]
  1278
[email protected]
  1279
    SourcePosition pos = scanner_.begin();
[email protected]
  1280
    ParameterList *parameters = new (pool_) ParameterList();
[email protected]
  1281
[email protected]
  1282
    if (!expect(TOK_LPAREN))
[email protected]
  1283
        return NULL;
[email protected]
  1284
[email protected]
  1285
    bool variadic = false;
[email protected]
  1286
[email protected]
  1287
    if (!match(TOK_RPAREN)) {
[email protected]
  1288
        while (true) {
[email protected]
  1289
            TypeQualifiers quals = TypeQual_None;
[email protected]
  1290
            if (match(TOK_CONST))
[email protected]
  1291
                quals = TypeQualifiers(quals | TypeQual_Const);
[email protected]
  1292
[email protected]
  1293
            bool ref = match(TOK_AMPERSAND);
[email protected]
  1294
[email protected]
  1295
            SourcePosition begin = scanner_.begin();
[email protected]
  1296
            Expression *type;
[email protected]
  1297
            Local<String> name(zone_);
[email protected]
  1298
            if (!fullTypeAndName(&type, name.ref(), DeclArg))
[email protected]
  1299
                return NULL;
[email protected]
  1300
[email protected]
  1301
            if (!name) {
[email protected]
  1302
                if ((quals & TypeQual_Const) || ref) {
[email protected]
  1303
                    cc_.reportError(begin, Message_InvalidVarArgs);
[email protected]
  1304
                    return NULL;
[email protected]
  1305
                }
[email protected]
  1306
[email protected]
  1307
                if (token != TOK_NATIVE) {
[email protected]
  1308
                    cc_.reportError(begin, Message_VarArgsOutsideNative);
[email protected]
  1309
                    return NULL;
[email protected]
  1310
                }
[email protected]
  1311
[email protected]
  1312
                variadic = true;
[email protected]
  1313
                break;
[email protected]
  1314
            }
[email protected]
  1315
[email protected]
  1316
            ExpressionList *dims = NULL;
[email protected]
  1317
            if (peek(TOK_LBRACKET)) {
[email protected]
  1318
                if ((dims = dimensions()) == NULL)
[email protected]
  1319
                    return NULL;
[email protected]
  1320
            }
[email protected]
  1321
[email protected]
  1322
            Expression *expr = NULL;
[email protected]
  1323
            if (match(TOK_ASSIGN)) {
[email protected]
  1324
                if ((expr = expression()) == NULL)
[email protected]
  1325
                    return NULL;
[email protected]
  1326
            }
[email protected]
  1327
[email protected]
  1328
            Parameter *parameter = new (pool_) Parameter(name, type, ref, quals, dims, expr, begin);
[email protected]
  1329
            if (!parameters->append(parameter))
[email protected]
  1330
                return NULL;
[email protected]
  1331
[email protected]
  1332
            if (!match(TOK_COMMA))
[email protected]
  1333
                break;
[email protected]
  1334
        }
[email protected]
  1335
        if (!expect(TOK_RPAREN))
[email protected]
  1336
            return NULL;
[email protected]
  1337
    }
[email protected]
  1338
[email protected]
  1339
    encounteredReturn_ = false;
[email protected]
  1340
[email protected]
  1341
    Statement *body = NULL;
[email protected]
  1342
    if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
[email protected]
  1343
        body = block();
[email protected]
  1344
        if (!body)
[email protected]
  1345
            return NULL;
[email protected]
  1346
    }
[email protected]
  1347
[email protected]
  1348
    FunctionSignature signature(returnType, parameters, variadic);
[email protected]
  1349
    if (token == TOK_TYPEDEF)
[email protected]
  1350
        return new (pool_) FunctionTypeStatement(pos, name, signature);
[email protected]
  1351
[email protected]
  1352
    return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
[email protected]
  1353
}
[email protected]
  1354
[email protected]
  1355
static inline bool
[email protected]
  1356
DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
[email protected]
  1357
{
[email protected]
  1358
    Local<String> tag(zone, zone->makeSymbol(name));
[email protected]
  1359
    if (!tag)
[email protected]
  1360
        return false;
[email protected]
  1361
[email protected]
  1362
    assert(false);
[email protected]
  1363
    return false; //return !!scope->declareType(tag, type);
[email protected]
  1364
}
[email protected]
  1365
[email protected]
  1366
static inline bool
[email protected]
  1367
DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
[email protected]
  1368
{
[email protected]
  1369
    Local<Type> primitive(zone, zone->types()->getPrimitive(type));
[email protected]
  1370
    assert(primitive);
[email protected]
  1371
    return DeclareIntrinsicType(zone, scope, name, primitive);
[email protected]
  1372
}
[email protected]
  1373
[email protected]
  1374
ParseTree *
[email protected]
  1375
Parser::parse()
[email protected]
  1376
{
[email protected]
  1377
    StatementList *statements = new (pool_) StatementList();
[email protected]
  1378
[email protected]
  1379
    for (;;) {
[email protected]
  1380
        Statement *statement = NULL;
[email protected]
  1381
[email protected]
  1382
        TokenKind kind = scanner_.peek();
[email protected]
  1383
        switch (kind) {
[email protected]
  1384
          case TOK_ERROR:
[email protected]
  1385
            return NULL;
[email protected]
  1386
[email protected]
  1387
          case TOK_EOF:
[email protected]
  1388
            break;
[email protected]
  1389
[email protected]
  1390
          case TOK_NAME:
[email protected]
  1391
            if ((statement = function(TOK_NAME)) == NULL)
[email protected]
  1392
                return NULL;
[email protected]
  1393
            break;
[email protected]
  1394
[email protected]
  1395
          case TOK_IMPORT:
[email protected]
  1396
          {
[email protected]
  1397
            scanner_.scan();
[email protected]
  1398
            if (statements->length())
[email protected]
  1399
                cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
[email protected]
  1400
            ImportStatement *stmt = import();
[email protected]
  1401
            if (!stmt)
[email protected]
  1402
                return NULL;
[email protected]
  1403
            if (!imports_->append(stmt))
[email protected]
  1404
                return NULL;
[email protected]
  1405
            if (!matchSemicolon())
[email protected]
  1406
                return NULL;
[email protected]
  1407
            continue;
[email protected]
  1408
          }
[email protected]
  1409
[email protected]
  1410
          case TOK_FORWARD:
[email protected]
  1411
          case TOK_PUBLIC:
[email protected]
  1412
          case TOK_NATIVE:
[email protected]
  1413
          case TOK_STOCK:
[email protected]
  1414
          case TOK_LABEL:
[email protected]
  1415
          case TOK_TYPEDEF:
[email protected]
  1416
          {
[email protected]
  1417
            if (kind != TOK_LABEL)
[email protected]
  1418
                scanner_.scan();
[email protected]
  1419
            if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
[email protected]
  1420
                if ((statement = var(TypeQual_Const)) == NULL)
[email protected]
  1421
                    return NULL;
[email protected]
  1422
                if (!matchSemicolon())
[email protected]
  1423
                    return NULL;
[email protected]
  1424
            } else {
[email protected]
  1425
                if ((statement = function(kind)) == NULL)
[email protected]
  1426
                    return NULL;
[email protected]
  1427
                if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
[email protected]
  1428
                    return NULL;
[email protected]
  1429
            }
[email protected]
  1430
            break;
[email protected]
  1431
          }
[email protected]
  1432
[email protected]
  1433
          case TOK_CONST:
[email protected]
  1434
          case TOK_NEW:
[email protected]
  1435
          {
[email protected]
  1436
            TypeQualifiers quals = (kind == TOK_CONST) ? TypeQual_Const : TypeQual_None;
[email protected]
  1437
            // Note: at global scope, we don't accept comma-delimited
[email protected]
  1438
            // declarations yet, to see if we can get away with forcing
[email protected]
  1439
            // a nicer top-level style.
[email protected]
  1440
            scanner_.scan();
[email protected]
  1441
            if ((statement = var(quals)) == NULL)
[email protected]
  1442
                return NULL;
[email protected]
  1443
            if (!matchSemicolon())
[email protected]
  1444
                return NULL;
[email protected]
  1445
            break;
[email protected]
  1446
          }
[email protected]
  1447
[email protected]
  1448
          case TOK_ENUM:
[email protected]
  1449
            if ((statement = enum_()) == NULL)
[email protected]
  1450
                return NULL;
[email protected]
  1451
            if (!matchSemicolon())
[email protected]
  1452
                return NULL;
[email protected]
  1453
            break;
[email protected]
  1454
[email protected]
  1455
          case TOK_STRUCT:
[email protected]
  1456
            if ((statement = struct_()) == NULL)
[email protected]
  1457
                return NULL;
[email protected]
  1458
            if (!matchSemicolon())
[email protected]
  1459
                return NULL;
[email protected]
  1460
            break;
[email protected]
  1461
[email protected]
  1462
          default:
[email protected]
  1463
            cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
[email protected]
  1464
            return NULL;
[email protected]
  1465
        }
[email protected]
  1466
[email protected]
  1467
        if (!statement)
[email protected]
  1468
            break;
[email protected]
  1469
[email protected]
  1470
        if (!statements->append(statement))
[email protected]
  1471
            return NULL;
[email protected]
  1472
    }
[email protected]
  1473
[email protected]
  1474
    return new (pool_) ParseTree(statements, unbound_, imports_);
[email protected]
  1475
}
[email protected]
  1476
[email protected]
  1477
class AstPrinter : public AstVisitor
[email protected]
  1478
{
[email protected]
  1479
    FILE *fp_;
[email protected]
  1480
    size_t level_;
[email protected]
  1481
[email protected]
  1482
  private:
[email protected]
  1483
    void prefix() {
[email protected]
  1484
        for (size_t i = 0; i < level_; i++)
[email protected]
  1485
            fprintf(fp_, "  ");
[email protected]
  1486
    }
[email protected]
  1487
    void indent() {
[email protected]
  1488
        level_++;
[email protected]
  1489
    }
[email protected]
  1490
    void unindent() {
[email protected]
  1491
        level_--;
[email protected]
  1492
    }
[email protected]
  1493
[email protected]
  1494
  public:
[email protected]
  1495
    AstPrinter(FILE *fp)
[email protected]
  1496
      : fp_(fp),
[email protected]
  1497
        level_(0)
[email protected]
  1498
    {
[email protected]
  1499
    }
[email protected]
  1500
[email protected]
  1501
    void dump(const FunctionSignature &sig) {
[email protected]
  1502
        prefix();
[email protected]
  1503
        fprintf(fp_, "()\n");
[email protected]
  1504
    }
[email protected]
  1505
    void visitNameProxy(NameProxy *name) {
[email protected]
  1506
        prefix();
[email protected]
  1507
        fprintf(fp_, "[ NameProxy (%s)\n", name->name()->chars());
[email protected]
  1508
    }
[email protected]
  1509
    void visitCallExpression(CallExpression *node) {
[email protected]
  1510
        prefix();
[email protected]
  1511
        fprintf(fp_, "[ CallExpression\n");
[email protected]
  1512
        indent();
[email protected]
  1513
        node->callee()->accept(this);
[email protected]
  1514
        for (size_t i = 0; i < node->arguments()->length(); i++)
[email protected]
  1515
            node->arguments()->at(i)->accept(this);
[email protected]
  1516
        unindent();
[email protected]
  1517
    }
[email protected]
  1518
    void visitFunctionTypeStatement(FunctionTypeStatement *node) {
[email protected]
  1519
        prefix();
[email protected]
  1520
        fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->name()->chars());
[email protected]
  1521
        indent();
[email protected]
  1522
        dump(node->signature());
[email protected]
  1523
        unindent();
[email protected]
  1524
    }
[email protected]
  1525
    void visitFunctionStatement(FunctionStatement *node) {
[email protected]
  1526
        prefix();
[email protected]
  1527
        fprintf(fp_, "[ FunctionStatement (%s)\n", node->name()->chars());
[email protected]
  1528
        indent();
[email protected]
  1529
        dump(node->signature());
[email protected]
  1530
        if (node->body())
[email protected]
  1531
            node->body()->accept(this);
[email protected]
  1532
        unindent();
[email protected]
  1533
    }
[email protected]
  1534
    void visitExpressionStatement(ExpressionStatement *node) {
[email protected]
  1535
        prefix();
[email protected]
  1536
        fprintf(fp_, "[ ExpressionStatement\n");
[email protected]
  1537
        indent();
[email protected]
  1538
        node->expression()->accept(this);
[email protected]
  1539
        unindent();
[email protected]
  1540
    }
[email protected]
  1541
    void visitAssignment(Assignment *node) {
[email protected]
  1542
        prefix();
[email protected]
  1543
        fprintf(fp_, "[ Assignment\n");
[email protected]
  1544
        indent();
[email protected]
  1545
        node->lvalue()->accept(this);
[email protected]
  1546
        node->expression()->accept(this);
[email protected]
  1547
        unindent();
[email protected]
  1548
    }
[email protected]
  1549
    void visitTernaryExpression(TernaryExpression *node) {
[email protected]
  1550
        prefix();
[email protected]
  1551
        fprintf(fp_, "[ TernaryExpression\n");
[email protected]
  1552
        indent();
[email protected]
  1553
        node->condition()->accept(this);
[email protected]
  1554
        node->left()->accept(this);
[email protected]
  1555
        node->right()->accept(this);
[email protected]
  1556
        unindent();
[email protected]
  1557
    }
[email protected]
  1558
    void visitBinaryExpression(BinaryExpression *node) {
[email protected]
  1559
        prefix();
[email protected]
  1560
        fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
[email protected]
  1561
        indent();
[email protected]
  1562
        node->left()->accept(this);
[email protected]
  1563
        node->right()->accept(this);
[email protected]
  1564
        unindent();
[email protected]
  1565
    }
[email protected]
  1566
    void visitUnaryExpression(UnaryExpression *node) {
[email protected]
  1567
        prefix();
[email protected]
  1568
        fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
[email protected]
  1569
        indent();
[email protected]
  1570
        node->expression()->accept(this);
[email protected]
  1571
        unindent();
[email protected]
  1572
    }
[email protected]
  1573
    void visitReturnStatement(ReturnStatement *node) {
[email protected]
  1574
        prefix();
[email protected]
  1575
        fprintf(fp_, "[ ReturnStatement\n");
[email protected]
  1576
        indent();
[email protected]
  1577
        if (node->expression())
[email protected]
  1578
            node->expression()->accept(this);
[email protected]
  1579
        unindent();
[email protected]
  1580
    }
[email protected]
  1581
    void visitForStatement(ForStatement *node) {
[email protected]
  1582
        prefix();
[email protected]
  1583
        fprintf(fp_, "[ ForStatement\n");
[email protected]
  1584
        indent();
[email protected]
  1585
        if (node->initialization())
[email protected]
  1586
            node->initialization()->accept(this);
[email protected]
  1587
        if (node->condition())
[email protected]
  1588
            node->condition()->accept(this);
[email protected]
  1589
        if (node->update())
[email protected]
  1590
            node->update()->accept(this);
[email protected]
  1591
        node->body()->accept(this);
[email protected]
  1592
        unindent();
[email protected]
  1593
    }
[email protected]
  1594
    void visitBlockStatement(BlockStatement *node) {
[email protected]
  1595
        prefix();
[email protected]
  1596
        fprintf(fp_, "[ BlockStatement\n");
[email protected]
  1597
        indent();
[email protected]
  1598
        for (size_t i = 0; i < node->statements()->length(); i++)
[email protected]
  1599
            node->statements()->at(i)->accept(this);
[email protected]
  1600
        unindent();
[email protected]
  1601
    }
[email protected]
  1602
    void visitVariableDeclaration(VariableDeclaration *node) {
[email protected]
  1603
        prefix();
[email protected]
  1604
        fprintf(fp_, "[ VariableDeclaration (%s)\n", node->name()->chars());
[email protected]
  1605
        indent();
[email protected]
  1606
        if (node->initialization())
[email protected]
  1607
            node->initialization()->accept(this);
[email protected]
  1608
        unindent();
[email protected]
  1609
    }
[email protected]
  1610
    void visitIntegerLiteral(IntegerLiteral *node) {
[email protected]
  1611
        prefix();
[email protected]
  1612
        fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
[email protected]
  1613
    }
[email protected]
  1614
    void visitBooleanLiteral(BooleanLiteral *node) {
[email protected]
  1615
        prefix();
[email protected]
  1616
        fprintf(fp_, "[ BooleanLiteral (%s)\n",
[email protected]
  1617
                (node->token() == TOK_TRUE) ? "true" : "false");
[email protected]
  1618
    }
[email protected]
  1619
    void visitFloatLiteral(FloatLiteral *node) {
[email protected]
  1620
        prefix();
[email protected]
  1621
        fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
[email protected]
  1622
    }
[email protected]
  1623
    void visitIfStatement(IfStatement *node) {
[email protected]
  1624
        prefix();
[email protected]
  1625
        fprintf(fp_, "[ IfStatement\n");
[email protected]
  1626
        indent();
[email protected]
  1627
        node->ifTrue()->accept(this);
[email protected]
  1628
        if (node->ifFalse())
[email protected]
  1629
            node->ifFalse()->accept(this);
[email protected]
  1630
        unindent();
[email protected]
  1631
    }
[email protected]
  1632
    void visitIndexExpression(IndexExpression *node) {
[email protected]
  1633
        prefix();
[email protected]
  1634
        fprintf(fp_, "[ IndexExpression\n");
[email protected]
  1635
        indent();
[email protected]
  1636
        node->left()->accept(this);
[email protected]
  1637
        node->right()->accept(this);
[email protected]
  1638
        unindent();
[email protected]
  1639
    }
[email protected]
  1640
    void visitEnumStatement(EnumStatement *node) {
[email protected]
  1641
        prefix();
[email protected]
  1642
        fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
[email protected]
  1643
        indent();
[email protected]
  1644
        for (size_t i = 0; i < node->entries()->length(); i++) {
[email protected]
  1645
            prefix();
[email protected]
  1646
            fprintf(fp_, "%s =\n", node->entries()->at(i).name->chars());
[email protected]
  1647
            if (node->entries()->at(i).expr) {
[email protected]
  1648
                indent();
[email protected]
  1649
                node->entries()->at(i).expr->accept(this);
[email protected]
  1650
                unindent();
[email protected]
  1651
            }
[email protected]
  1652
        }
[email protected]
  1653
        unindent();
[email protected]
  1654
    }
[email protected]
  1655
    void visitWhileStatement(WhileStatement *node) {
[email protected]
  1656
        prefix();
[email protected]
  1657
        fprintf(fp_, "[ WhileStatement (%s)\n",
[email protected]
  1658
                (node->token() == TOK_DO) ? "do" : "while");
[email protected]
  1659
        indent();
[email protected]
  1660
        if (node->token() == TOK_DO) {
[email protected]
  1661
            node->condition()->accept(this);
[email protected]
  1662
            node->body()->accept(this);
[email protected]
  1663
        } else {
[email protected]
  1664
            node->condition()->accept(this);
[email protected]
  1665
            node->body()->accept(this);
[email protected]
  1666
        }
[email protected]
  1667
        unindent();
[email protected]
  1668
    }
[email protected]
  1669
    void visitBreakStatement(BreakStatement *node) {
[email protected]
  1670
        prefix();
[email protected]
  1671
        fprintf(fp_, "[ BreakStatement\n");
[email protected]
  1672
    }
[email protected]
  1673
    void visitContinueStatement(ContinueStatement *node) {
[email protected]
  1674
        prefix();
[email protected]
  1675
        fprintf(fp_, "[ ContinueStatement\n");
[email protected]
  1676
    }
[email protected]
  1677
    void visitStringLiteral(StringLiteral *node) {
[email protected]
  1678
        prefix();
[email protected]
  1679
        fprintf(fp_, "[ StringLiteral\n");
[email protected]
  1680
    }
[email protected]
  1681
    void visitIncDecExpression(IncDecExpression *node) {
[email protected]
  1682
        prefix();
[email protected]
  1683
        fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
[email protected]
  1684
        indent();
[email protected]
  1685
        node->expression()->accept(this);
[email protected]
  1686
        unindent();
[email protected]
  1687
    }
[email protected]
  1688
    void visitStructureStatement(StructureStatement *node) {
[email protected]
  1689
        prefix();
[email protected]
  1690
        fprintf(fp_, "[ StructureStatement %s\n", node->name()->chars());
[email protected]
  1691
    }
[email protected]
  1692
    void visitFieldExpression(FieldExpression *node) {
[email protected]
  1693
        prefix();
[email protected]
  1694
        fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
[email protected]
  1695
        indent();
[email protected]
  1696
        node->left()->accept(this);
[email protected]
  1697
        unindent();
[email protected]
  1698
    }
[email protected]
  1699
    void visitSwitchStatement(SwitchStatement *node) {
[email protected]
  1700
        prefix();
[email protected]
  1701
        fprintf(fp_, "[ SwitchStatement\n");
[email protected]
  1702
        indent();
[email protected]
  1703
        node->expression()->accept(this);
[email protected]
  1704
        for (size_t i = 0; i < node->cases()->length(); i++) {
[email protected]
  1705
            Case *c = node->cases()->at(i);
[email protected]
  1706
            c->expression()->accept(this);
[email protected]
  1707
            if (c->others()) {
[email protected]
  1708
                for (size_t j = 0; j < c->others()->length(); j++)
[email protected]
  1709
                    c->others()->at(j)->accept(this);
[email protected]
  1710
            }
[email protected]
  1711
            indent();
[email protected]
  1712
            c->statement()->accept(this);
[email protected]
  1713
            unindent();
[email protected]
  1714
        }
[email protected]
  1715
        if (node->defaultCase())
[email protected]
  1716
            node->defaultCase()->accept(this);
[email protected]
  1717
        unindent();
[email protected]
  1718
    }
[email protected]
  1719
    void visitArrayLiteral(ArrayLiteral *node) {
[email protected]
  1720
        prefix();
[email protected]
  1721
        fprintf(fp_, "[ ArrayLiteral\n");
[email protected]
  1722
        indent();
[email protected]
  1723
        for (size_t i = 0; i < node->expressions()->length(); i++) {
[email protected]
  1724
            Expression *expr = node->expressions()->at(i);
[email protected]
  1725
            indent();
[email protected]
  1726
            expr->accept(this);
[email protected]
  1727
            unindent();
[email protected]
  1728
        }
[email protected]
  1729
    }
[email protected]
  1730
    void visitImportStatement(ImportStatement *node) {
[email protected]
  1731
        prefix();
[email protected]
  1732
        fprintf(fp_, "[ ImportStatement\n");
[email protected]
  1733
    }
[email protected]
  1734
};
[email protected]
  1735
[email protected]
  1736
void
[email protected]
  1737
ParseTree::dump(FILE *fp)
[email protected]
  1738
{
[email protected]
  1739
    AstPrinter printer(fp);
[email protected]
  1740
[email protected]
  1741
    for (size_t i = 0; i < statements_->length(); i++)
[email protected]
  1742
        statements_->at(i)->accept(&printer);
[email protected]
  1743
}