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