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