src/Parser.cpp
changeset 195 c1ba166f3fc4
parent 194 b029d63565a2
child 196 9904633b1dfc
     1.1 --- a/src/Parser.cpp	Mon Sep 17 00:10:01 2012 -0700
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1846 +0,0 @@
     1.4 -/* vim: set ts=4 sw=4 tw=99 et:
     1.5 - *
     1.6 - * Copyright (C) 2012 David Anderson
     1.7 - *
     1.8 - * This file is part of SourcePawn.
     1.9 - *
    1.10 - * SourcePawn is free software: you can redistribute it and/or modify it under
    1.11 - * the terms of the GNU General Public License as published by the Free
    1.12 - * Software Foundation, either version 3 of the License, or (at your option)
    1.13 - * any later version.
    1.14 - * 
    1.15 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    1.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    1.18 - *
    1.19 - * You should have received a copy of the GNU General Public License along with
    1.20 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
    1.21 - */
    1.22 -#include <string.h>
    1.23 -#include "Zone.h"
    1.24 -#include "Parser.h"
    1.25 -#include "FixedArray.h"
    1.26 -#include "Heap.h"
    1.27 -#include "Strings.h"
    1.28 -#include "TypeManager.h"
    1.29 -#include "Heap-inl.h"
    1.30 -
    1.31 -using namespace ke;
    1.32 -
    1.33 -Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
    1.34 -  : zone_(zone),
    1.35 -    cc_(cc),
    1.36 -    pool_(zone_->pool()),
    1.37 -    scanner_(cc, stream, length),
    1.38 -    scope_(NULL),
    1.39 -    unbound_(NULL)
    1.40 -{
    1.41 -    unbound_ = new (pool_) PoolList<NameProxy *>();
    1.42 -}
    1.43 -
    1.44 -bool
    1.45 -Parser::peek(TokenKind kind)
    1.46 -{
    1.47 -    return scanner_.peek() == kind;
    1.48 -}
    1.49 -
    1.50 -bool
    1.51 -Parser::match(TokenKind kind)
    1.52 -{
    1.53 -    if (!peek(kind))
    1.54 -        return false;
    1.55 -    scanner_.scan();
    1.56 -    return true;
    1.57 -}
    1.58 -
    1.59 -bool
    1.60 -Parser::matchSemicolon()
    1.61 -{
    1.62 -    return expect(TOK_SEMICOLON);
    1.63 -}
    1.64 -
    1.65 -bool
    1.66 -Parser::expect(TokenKind kind)
    1.67 -{
    1.68 -    TokenKind got = scanner_.scan();
    1.69 -    if (got == kind)
    1.70 -        return true;
    1.71 -    cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
    1.72 -    return false;
    1.73 -}
    1.74 -
    1.75 -Scope *
    1.76 -Parser::enterScope(Scope::Kind kind)
    1.77 -{
    1.78 -    scope_ = new (pool_) Scope(pool_, kind, scope_);
    1.79 -    if (!scope_->initialize())
    1.80 -        return NULL;
    1.81 -    return scope_;
    1.82 -}
    1.83 -
    1.84 -NameProxy *
    1.85 -Parser::bind(Handle<String> name)
    1.86 -{
    1.87 -    BoundName *bound = scope_->lookup(name);
    1.88 -    NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), name, bound);
    1.89 -    if (!bound && !unbound_->append(proxy))
    1.90 -        return NULL;
    1.91 -    return proxy;
    1.92 -}
    1.93 -
    1.94 -BoundName *
    1.95 -Parser::bindType(Handle<String> name)
    1.96 -{
    1.97 -    if (BoundName *binding = scope_->lookup(name))
    1.98 -        return binding;
    1.99 -
   1.100 -    return new (pool_) UnboundName(scope_, name);
   1.101 -}
   1.102 -
   1.103 -bool
   1.104 -Parser::matchName(String **name, TokenKind kind)
   1.105 -{
   1.106 -    assert(kind == TOK_NAME || kind == TOK_LABEL);
   1.107 -    *name = NULL;
   1.108 -    if (!match(kind))
   1.109 -        return false;
   1.110 -    *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
   1.111 -    return true;
   1.112 -}
   1.113 -
   1.114 -String *
   1.115 -Parser::expectName()
   1.116 -{
   1.117 -    if (!expect(TOK_NAME))
   1.118 -        return NULL;
   1.119 -    return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
   1.120 -}
   1.121 -
   1.122 -void
   1.123 -Parser::redeclarationError(BoundName *other)
   1.124 -{
   1.125 -    cc_.reportError(scanner_.begin(), Message_RedeclaredName, other->name()->chars(),
   1.126 -                    other->pos().line, other->pos().col);
   1.127 -}
   1.128 -
   1.129 -Expression *
   1.130 -Parser::primitive()
   1.131 -{
   1.132 -    TokenKind kind = scanner_.peek();
   1.133 -    switch (kind) {
   1.134 -      case TOK_FLOAT_LITERAL:
   1.135 -      {
   1.136 -        scanner_.scan();
   1.137 -        double value = Scanner::ParseDouble(scanner_.literal());
   1.138 -        return new (pool_) FloatLiteral(scanner_.begin(), value);
   1.139 -      }
   1.140 -
   1.141 -      case TOK_HEX_LITERAL:
   1.142 -      {
   1.143 -        scanner_.scan();
   1.144 -        int value = strtol(scanner_.literal(), NULL, 16);
   1.145 -        return new (pool_) IntegerLiteral(scanner_.begin(), value);
   1.146 -      }
   1.147 -
   1.148 -      case TOK_INTEGER_LITERAL:
   1.149 -      {
   1.150 -        scanner_.scan();
   1.151 -        int value = atoi(scanner_.literal());
   1.152 -        return new (pool_) IntegerLiteral(scanner_.begin(), value);
   1.153 -      }
   1.154 -
   1.155 -      case TOK_TRUE:
   1.156 -      case TOK_FALSE:
   1.157 -        scanner_.scan();
   1.158 -        return new (pool_) BooleanLiteral(scanner_.begin(), kind);
   1.159 -
   1.160 -      case TOK_STRING_LITERAL:
   1.161 -      {
   1.162 -        scanner_.scan();
   1.163 -        Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
   1.164 -        if (!array)
   1.165 -            return NULL;
   1.166 -        memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
   1.167 -        return new (pool_) StringLiteral(scanner_.begin(), array);
   1.168 -      }
   1.169 -
   1.170 -      default:
   1.171 -      {
   1.172 -        if (kind != TOK_ERROR)
   1.173 -            cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
   1.174 -        return NULL;
   1.175 -      }
   1.176 -    }
   1.177 -}
   1.178 -
   1.179 -Expression *
   1.180 -Parser::arrayLiteral(TokenKind kind)
   1.181 -{
   1.182 -    assert(kind == TOK_LBRACE || kind == TOK_LBRACKET);
   1.183 -
   1.184 -    TokenKind close = (kind == TOK_LBRACE)
   1.185 -                      ? TOK_RBRACE
   1.186 -                      : TOK_RBRACKET;
   1.187 -
   1.188 -    SourcePosition pos = scanner_.begin();
   1.189 -
   1.190 -    ExpressionList *list = new (pool_) ExpressionList();
   1.191 -    do {
   1.192 -        if (match(close))
   1.193 -            break;
   1.194 -
   1.195 -        Expression *expr = NULL;
   1.196 -        if (kind == TOK_LBRACE) {
   1.197 -            if (peek(TOK_LBRACE))
   1.198 -                expr = arrayLiteral(TOK_LBRACE);
   1.199 -            else
   1.200 -                expr = primitive();
   1.201 -        } else {
   1.202 -            expr = expression();
   1.203 -        }
   1.204 -        if (!expr)
   1.205 -            return NULL;
   1.206 -
   1.207 -        if (!list->append(expr))
   1.208 -            return NULL;
   1.209 -
   1.210 -        if (!match(TOK_COMMA)) {
   1.211 -            if (!expect(close))
   1.212 -                return NULL;
   1.213 -            break;
   1.214 -        }
   1.215 -    } while (true);
   1.216 -
   1.217 -    return new (pool_) ArrayLiteral(pos, kind, list);
   1.218 -}
   1.219 -
   1.220 -Expression *
   1.221 -Parser::prefix()
   1.222 -{
   1.223 -    switch (scanner_.peek()) {
   1.224 -      case TOK_LPAREN:
   1.225 -      {
   1.226 -        scanner_.scan();
   1.227 -        Expression *expr = expression();
   1.228 -        if (!expr)
   1.229 -            return NULL;
   1.230 -        if (!expect(TOK_RPAREN))
   1.231 -            return NULL;
   1.232 -        return expr;
   1.233 -      }
   1.234 -
   1.235 -      case TOK_NAME:
   1.236 -      {
   1.237 -        Local<String> name(zone_, expectName());
   1.238 -        if (!name)
   1.239 -            return NULL;
   1.240 -        return bind(name);
   1.241 -      }
   1.242 -
   1.243 -      default:
   1.244 -        return primitive();
   1.245 -    }
   1.246 -}
   1.247 -
   1.248 -Expression *
   1.249 -Parser::call(Expression *callee)
   1.250 -{
   1.251 -    ExpressionList *arguments = new (pool_) ExpressionList();
   1.252 -
   1.253 -    SourcePosition pos = scanner_.begin();
   1.254 -    expect(TOK_LPAREN);
   1.255 -    
   1.256 -    if (!match(TOK_RPAREN)) {
   1.257 -        while (true) {
   1.258 -            Expression *expr = expression();
   1.259 -            if (!expr)
   1.260 -                return NULL;
   1.261 -
   1.262 -            if (!arguments->append(expr))
   1.263 -                return NULL;
   1.264 -
   1.265 -            if (!match(TOK_COMMA))
   1.266 -                break;
   1.267 -        }
   1.268 -
   1.269 -        if (!expect(TOK_RPAREN))
   1.270 -            return NULL;
   1.271 -    }
   1.272 -
   1.273 -    return new (pool_) CallExpression(pos, callee, arguments);
   1.274 -}
   1.275 -
   1.276 -Expression *
   1.277 -Parser::index(Expression *left)
   1.278 -{
   1.279 -    expect(TOK_LBRACKET);
   1.280 -    
   1.281 -    SourcePosition pos = scanner_.begin();
   1.282 -    Expression *expr = expression();
   1.283 -    if (!expr)
   1.284 -        return NULL;
   1.285 -
   1.286 -    if (!expect(TOK_RBRACKET))
   1.287 -        return NULL;
   1.288 -
   1.289 -    return new (pool_) IndexExpression(pos, left, expr);
   1.290 -}
   1.291 -
   1.292 -Expression *
   1.293 -Parser::field(Expression *left)
   1.294 -{
   1.295 -    expect(TOK_DOT);
   1.296 -
   1.297 -    SourcePosition pos = scanner_.begin();
   1.298 -    Local<String> name(zone_, expectName());
   1.299 -    if (!name)
   1.300 -        return NULL;
   1.301 -
   1.302 -    return new (pool_) FieldExpression(pos, left, name);
   1.303 -}
   1.304 -
   1.305 -Expression *
   1.306 -Parser::primary()
   1.307 -{
   1.308 -    Expression *expr = prefix();
   1.309 -    if (!expr)
   1.310 -        return NULL;
   1.311 -
   1.312 -    for (;;) {
   1.313 -        switch (scanner_.peek()) {
   1.314 -          case TOK_LPAREN:
   1.315 -            if ((expr = call(expr)) == NULL)
   1.316 -                return NULL;
   1.317 -            break;
   1.318 -
   1.319 -          case TOK_LBRACKET:
   1.320 -            if ((expr = index(expr)) == NULL)
   1.321 -                return NULL;
   1.322 -            break;
   1.323 -
   1.324 -          case TOK_DOT:
   1.325 -            if ((expr = field(expr)) == NULL)
   1.326 -                return NULL;
   1.327 -            break;
   1.328 -
   1.329 -          default:
   1.330 -            return expr;
   1.331 -        }
   1.332 -    }
   1.333 -}
   1.334 -
   1.335 -Expression *
   1.336 -Parser::unary()
   1.337 -{
   1.338 -    TokenKind token = scanner_.peek();
   1.339 -
   1.340 -    SourcePosition pos = scanner_.begin();
   1.341 -    switch (token) {
   1.342 -      case TOK_INCREMENT:
   1.343 -      case TOK_DECREMENT:
   1.344 -      {
   1.345 -        scanner_.scan();
   1.346 -        Expression *expr = unary();
   1.347 -        if (!expr)
   1.348 -            return NULL;
   1.349 -        return new (pool_) IncDecExpression(pos, token, expr, false);
   1.350 -      }
   1.351 -
   1.352 -      case TOK_MINUS:
   1.353 -      case TOK_NOT:
   1.354 -      case TOK_TILDE:
   1.355 -      {
   1.356 -        scanner_.scan();
   1.357 -        Expression *expr = unary();
   1.358 -        if (!expr)
   1.359 -            return NULL;
   1.360 -        return new (pool_) UnaryExpression(pos, token, expr);
   1.361 -      }
   1.362 -
   1.363 -      case TOK_SIZEOF:
   1.364 -      {
   1.365 -        scanner_.scan();
   1.366 -        if (!expect(TOK_LPAREN))
   1.367 -            return NULL;
   1.368 -        Expression *expr = unary();
   1.369 -        if (!expr)
   1.370 -            return NULL;
   1.371 -        if (!expect(TOK_RPAREN))
   1.372 -            return NULL;
   1.373 -        return new (pool_) UnaryExpression(pos, token, expr);
   1.374 -      }
   1.375 -
   1.376 -      case TOK_LABEL:
   1.377 -      {
   1.378 -        scanner_.scan();
   1.379 -        Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
   1.380 -        if (!tag)
   1.381 -            return NULL;
   1.382 -
   1.383 -        BoundName *type = NULL;
   1.384 -        if (tag)
   1.385 -            type = bindType(tag);
   1.386 -
   1.387 -        Expression *expr = unary();
   1.388 -        if (!expr)
   1.389 -            return NULL;
   1.390 -
   1.391 -        return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, type);
   1.392 -      }
   1.393 -
   1.394 -      default:
   1.395 -        break;
   1.396 -    }
   1.397 -
   1.398 -    Expression *expr = primary();
   1.399 -
   1.400 -    token = scanner_.peek();
   1.401 -    if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
   1.402 -        scanner_.scan();
   1.403 -        return new (pool_) IncDecExpression(pos, token, expr, true);
   1.404 -    }
   1.405 -
   1.406 -    return expr;
   1.407 -}
   1.408 -
   1.409 -Expression *
   1.410 -Parser::multiplication()
   1.411 -{
   1.412 -    Expression *left = unary();
   1.413 -    do {
   1.414 -        if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
   1.415 -            break;
   1.416 -        SourcePosition pos = scanner_.begin();
   1.417 -        TokenKind kind = scanner_.last();
   1.418 -        Expression *right = unary();
   1.419 -        if (!right)
   1.420 -            return NULL;
   1.421 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
   1.422 -    } while (left);
   1.423 -    return left;
   1.424 -}
   1.425 -
   1.426 -Expression *
   1.427 -Parser::addition()
   1.428 -{
   1.429 -    Expression *left = multiplication();
   1.430 -    while (left) {
   1.431 -        if (!match(TOK_PLUS) && !match(TOK_MINUS))
   1.432 -            break;
   1.433 -        SourcePosition pos = scanner_.begin();
   1.434 -        TokenKind kind = scanner_.last();
   1.435 -        Expression *right = multiplication();
   1.436 -        if (!right)
   1.437 -            return NULL;
   1.438 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
   1.439 -    }
   1.440 -    return left;
   1.441 -}
   1.442 -
   1.443 -Expression *
   1.444 -Parser::shift()
   1.445 -{
   1.446 -    Expression *left = addition();
   1.447 -    while (left) {
   1.448 -        if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
   1.449 -            break;
   1.450 -        SourcePosition pos = scanner_.begin();
   1.451 -        TokenKind kind = scanner_.last();
   1.452 -        Expression *right = addition();
   1.453 -        if (!right)
   1.454 -            return NULL;
   1.455 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
   1.456 -    }
   1.457 -    return left;
   1.458 -}
   1.459 -
   1.460 -Expression *
   1.461 -Parser::bitand_()
   1.462 -{
   1.463 -    Expression *left = shift();
   1.464 -    while (left) {
   1.465 -        if (!match(TOK_BITAND))
   1.466 -            break;
   1.467 -        SourcePosition pos = scanner_.begin();
   1.468 -        Expression *right = shift();
   1.469 -        if (!right)
   1.470 -            return NULL;
   1.471 -        left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
   1.472 -    }
   1.473 -    return left;
   1.474 -}
   1.475 -
   1.476 -Expression *
   1.477 -Parser::bitxor()
   1.478 -{
   1.479 -    Expression *left = bitand_();
   1.480 -    while (left) {
   1.481 -        if (!match(TOK_BITXOR))
   1.482 -            break;
   1.483 -        SourcePosition pos = scanner_.begin();
   1.484 -        Expression *right = shift();
   1.485 -        if (!right)
   1.486 -            return NULL;
   1.487 -        left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
   1.488 -    }
   1.489 -    return left;
   1.490 -}
   1.491 -
   1.492 -Expression *
   1.493 -Parser::bitor_()
   1.494 -{
   1.495 -    Expression *left = bitxor();
   1.496 -    while (left) {
   1.497 -        if (!match(TOK_BITOR))
   1.498 -            break;
   1.499 -        SourcePosition pos = scanner_.begin();
   1.500 -        Expression *right = bitxor();
   1.501 -        if (!right)
   1.502 -            return NULL;
   1.503 -        left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
   1.504 -    }
   1.505 -    return left;
   1.506 -}
   1.507 -
   1.508 -Expression *
   1.509 -Parser::relational()
   1.510 -{
   1.511 -    Expression *left = bitor_();
   1.512 -    while (left) {
   1.513 -        TokenKind kind = scanner_.peek();
   1.514 -        if (kind < TOK_LT || kind > TOK_GE)
   1.515 -            break;
   1.516 -        scanner_.scan();
   1.517 -        SourcePosition pos = scanner_.begin();
   1.518 -        Expression *right = shift();
   1.519 -        if (!right)
   1.520 -            return NULL;
   1.521 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
   1.522 -    }
   1.523 -    return left;
   1.524 -}
   1.525 -
   1.526 -Expression *
   1.527 -Parser::equals()
   1.528 -{
   1.529 -    Expression *left = relational();
   1.530 -    while (left) {
   1.531 -        if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
   1.532 -            break;
   1.533 -        TokenKind kind = scanner_.last();
   1.534 -        SourcePosition pos = scanner_.begin();
   1.535 -        Expression *right = relational();
   1.536 -        if (!right)
   1.537 -            return NULL;
   1.538 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
   1.539 -    }
   1.540 -    return left;
   1.541 -}
   1.542 -
   1.543 -Expression *
   1.544 -Parser::and_()
   1.545 -{
   1.546 -    Expression *left = equals();
   1.547 -    while (left) {
   1.548 -        if (!match(TOK_AND))
   1.549 -            break;
   1.550 -        SourcePosition pos = scanner_.begin();
   1.551 -        Expression *right = equals();
   1.552 -        if (!right)
   1.553 -            return NULL;
   1.554 -        left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
   1.555 -    }
   1.556 -    return left;
   1.557 -}
   1.558 -
   1.559 -Expression *
   1.560 -Parser::or_()
   1.561 -{
   1.562 -    Expression *left = and_();
   1.563 -    while (left) {
   1.564 -        if (!match(TOK_OR))
   1.565 -            break;
   1.566 -        SourcePosition pos = scanner_.begin();
   1.567 -        Expression *right = and_();
   1.568 -        if (!right)
   1.569 -            return NULL;
   1.570 -        left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
   1.571 -    }
   1.572 -    return left;
   1.573 -}
   1.574 -
   1.575 -Expression *
   1.576 -Parser::ternary()
   1.577 -{
   1.578 -    Expression *cond = or_();
   1.579 -    if (!cond)
   1.580 -        return NULL;
   1.581 -    
   1.582 -    if (!match(TOK_QMARK))
   1.583 -        return cond;
   1.584 -
   1.585 -    Expression *left;
   1.586 -    SourcePosition pos = scanner_.begin();
   1.587 -    AutoAllowTags<false> disableTags(scanner_);
   1.588 -    {
   1.589 -        if ((left = expression()) == NULL)
   1.590 -            return NULL;
   1.591 -    }
   1.592 -
   1.593 -    if (!expect(TOK_COLON))
   1.594 -        return NULL;
   1.595 -
   1.596 -    Expression *right = expression();
   1.597 -    if (!right)
   1.598 -        return NULL;
   1.599 -
   1.600 -    return new (pool_) TernaryExpression(pos, cond, left, right);
   1.601 -}
   1.602 -
   1.603 -Expression *
   1.604 -Parser::assignment()
   1.605 -{
   1.606 -    Expression *left = ternary();
   1.607 -    while (left) {
   1.608 -        TokenKind token = scanner_.peek();
   1.609 -        if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
   1.610 -            break;
   1.611 -        scanner_.scan();
   1.612 -        SourcePosition pos = scanner_.begin();
   1.613 -        Expression *expr = ternary();
   1.614 -        if (!expr)
   1.615 -            return NULL;
   1.616 -
   1.617 -        left = new (pool_) Assignment(pos, token, left, expr);
   1.618 -    }
   1.619 -    return left;
   1.620 -}
   1.621 -
   1.622 -Expression *
   1.623 -Parser::expression()
   1.624 -{
   1.625 -    return assignment();
   1.626 -}
   1.627 -
   1.628 -Statement *
   1.629 -Parser::while_()
   1.630 -{
   1.631 -    SourcePosition pos = scanner_.begin();
   1.632 -    scanner_.scan();
   1.633 -
   1.634 -    if (!expect(TOK_LPAREN))
   1.635 -        return NULL;
   1.636 -
   1.637 -    Expression *condition = expression();
   1.638 -    if (!condition)
   1.639 -        return NULL;
   1.640 -
   1.641 -    if (!expect(TOK_RPAREN))
   1.642 -        return NULL;
   1.643 -
   1.644 -    // Inside a loop, we force the creation of a scope object. Normally, we
   1.645 -    // will cull scopes if they have no variables. However inside a loop,
   1.646 -    // function calls that take references may compute a LIFO object, and to
   1.647 -    // avoid temporarily leaking many such objects, we ensure that a scope
   1.648 -    // is present so a LIFO slot can be allocated.
   1.649 -    if (!enterScope(Scope::BLOCK))
   1.650 -        return NULL;
   1.651 -
   1.652 -    Statement *body;
   1.653 -    if (scanner_.peek() == TOK_LBRACE)
   1.654 -        body = block(scope_);
   1.655 -    else
   1.656 -        body = localStatement();
   1.657 -    if (!body)
   1.658 -        return NULL;
   1.659 -
   1.660 -    scope_ = scope_->enclosing();
   1.661 -    return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
   1.662 -}
   1.663 -
   1.664 -Statement *
   1.665 -Parser::do_()
   1.666 -{
   1.667 -    SourcePosition pos = scanner_.begin();
   1.668 -    scanner_.scan();
   1.669 -
   1.670 -    // See the comment in ::while_() as to why we force a scope.
   1.671 -    if (!enterScope(Scope::BLOCK))
   1.672 -        return NULL;
   1.673 -
   1.674 -    Statement *body;
   1.675 -    if (scanner_.peek() == TOK_LBRACE)
   1.676 -        body = block(scope_);
   1.677 -    else
   1.678 -        body = localStatement();
   1.679 -    if (!body)
   1.680 -        return NULL;
   1.681 -
   1.682 -    scope_ = scope_->enclosing();
   1.683 -
   1.684 -    if (!expect(TOK_WHILE))
   1.685 -        return NULL;
   1.686 -
   1.687 -    if (!expect(TOK_LPAREN))
   1.688 -        return NULL;
   1.689 -    Expression *condition = expression();
   1.690 -    if (!condition)
   1.691 -        return NULL;
   1.692 -    if (!expect(TOK_RPAREN))
   1.693 -        return NULL;
   1.694 -
   1.695 -    return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
   1.696 -}
   1.697 -
   1.698 -Statement *
   1.699 -Parser::switch_()
   1.700 -{
   1.701 -    expect(TOK_SWITCH);
   1.702 -
   1.703 -    SourcePosition pos = scanner_.begin();
   1.704 -
   1.705 -    if (!expect(TOK_LPAREN))
   1.706 -        return NULL;
   1.707 -    Expression *expr = expression();
   1.708 -    if (!expr)
   1.709 -        return NULL;
   1.710 -    if (!expect(TOK_RPAREN))
   1.711 -        return NULL;
   1.712 -
   1.713 -    if (!expect(TOK_LBRACE))
   1.714 -        return NULL;
   1.715 -
   1.716 -    SourcePosition defaultPos;
   1.717 -    PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
   1.718 -
   1.719 -    Statement *defaultCase = NULL;
   1.720 -
   1.721 -    while (!peek(TOK_RBRACE)) {
   1.722 -        Expression *expr = NULL;
   1.723 -        ExpressionList *others = NULL;
   1.724 -        if (match(TOK_DEFAULT)) {
   1.725 -            if (defaultCase) {
   1.726 -                cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
   1.727 -                return NULL;
   1.728 -            }
   1.729 -
   1.730 -            defaultPos = scanner_.begin();
   1.731 -        } else {
   1.732 -            if (defaultCase) {
   1.733 -                cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
   1.734 -                return NULL;
   1.735 -            }
   1.736 -
   1.737 -            if (!expect(TOK_CASE))
   1.738 -                return NULL;
   1.739 -
   1.740 -            // A limitation in the grammar is that |case <NAME>:| will be
   1.741 -            // detected as a label.
   1.742 -            AutoAllowTags<false> disableTags(scanner_);
   1.743 -
   1.744 -            if ((expr = expression()) == NULL)
   1.745 -                return NULL;
   1.746 -
   1.747 -            if (peek(TOK_COMMA)) {
   1.748 -                others = new (pool_) ExpressionList();
   1.749 -                while (match(TOK_COMMA)) {
   1.750 -                    Expression *other = expression();
   1.751 -                    if (!other)
   1.752 -                        return NULL;
   1.753 -                    if (!others->append(other))
   1.754 -                        return NULL;
   1.755 -                }
   1.756 -            }
   1.757 -        }
   1.758 -
   1.759 -        if (!expect(TOK_COLON))
   1.760 -            return NULL;
   1.761 -
   1.762 -        Statement *statement = localStatement();
   1.763 -        if (!statement)
   1.764 -            return NULL;
   1.765 -
   1.766 -        if (!peek(TOK_CASE) &&
   1.767 -            !peek(TOK_DEFAULT) &&
   1.768 -            !peek(TOK_RBRACE))
   1.769 -        {
   1.770 -            cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
   1.771 -            return NULL;
   1.772 -        }
   1.773 -
   1.774 -        if (expr) {
   1.775 -            Case *caze = new (pool_) Case(expr, others, statement);
   1.776 -            if (!cases->append(caze))
   1.777 -                return NULL;
   1.778 -        } else {
   1.779 -            defaultCase = statement;
   1.780 -        }
   1.781 -    }
   1.782 -
   1.783 -    if (!expect(TOK_RBRACE))
   1.784 -        return NULL;
   1.785 -
   1.786 -    return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
   1.787 -}
   1.788 -
   1.789 -Statement *
   1.790 -Parser::forStatement()
   1.791 -{
   1.792 -    SourcePosition pos = scanner_.begin();
   1.793 -    scanner_.scan();
   1.794 -    if (!expect(TOK_LPAREN))
   1.795 -        return NULL;
   1.796 -
   1.797 -    Statement *decl = NULL;
   1.798 -    if (!match(TOK_SEMICOLON)) {
   1.799 -        if (match(TOK_NEW)) {
   1.800 -            if (!enterScope(Scope::BLOCK))
   1.801 -                return NULL;
   1.802 -            if ((decl = vars(TOK_STOCK, TOK_NEW)) == NULL)
   1.803 -                return NULL;
   1.804 -        } else {
   1.805 -            if ((decl = expressionStatement()) == NULL)
   1.806 -                return NULL;
   1.807 -        }
   1.808 -        if (!expect(TOK_SEMICOLON))
   1.809 -            return NULL;
   1.810 -    }
   1.811 -
   1.812 -    Expression *condition = NULL;
   1.813 -    if (!match(TOK_SEMICOLON)) {
   1.814 -        if ((condition = expression()) == NULL)
   1.815 -            return NULL;
   1.816 -        if (!expect(TOK_SEMICOLON))
   1.817 -            return NULL;
   1.818 -    }
   1.819 -
   1.820 -    Statement *update = NULL;
   1.821 -    if (!match(TOK_RPAREN)) {
   1.822 -        if ((update = expressionStatement()) == NULL)
   1.823 -            return NULL;
   1.824 -        if (!expect(TOK_RPAREN))
   1.825 -            return NULL;
   1.826 -    }
   1.827 -
   1.828 -    // See the comment in ::while_() as to why we force a scope.
   1.829 -    if (!enterScope(Scope::BLOCK))
   1.830 -        return NULL;
   1.831 -
   1.832 -    Statement *body;
   1.833 -    if (scanner_.peek() == TOK_LBRACE)
   1.834 -        body = block(scope_);
   1.835 -    else
   1.836 -        body = localStatement();
   1.837 -    if (!body)
   1.838 -        return NULL;
   1.839 -
   1.840 -    scope_ = scope_->enclosing();
   1.841 -
   1.842 -    Scope *declScope = NULL;
   1.843 -    if (decl && (decl->isVariableDeclaration() || decl->isBlockStatement())) {
   1.844 -        declScope = scope_->unlinkIfEmpty();
   1.845 -        scope_ = scope_->enclosing();
   1.846 -    }
   1.847 -    return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
   1.848 -}
   1.849 -
   1.850 -ExpressionList *
   1.851 -Parser::dimensions()
   1.852 -{
   1.853 -    ExpressionList *postDimensions = new (pool_) ExpressionList();
   1.854 -    while (match(TOK_LBRACKET)) {
   1.855 -        Expression *dim = NULL;
   1.856 -        if (!match(TOK_RBRACKET)) {
   1.857 -            if ((dim = expression()) == NULL)
   1.858 -                return NULL;
   1.859 -            if (!expect(TOK_RBRACKET))
   1.860 -                return NULL;
   1.861 -        }
   1.862 -
   1.863 -        if (!postDimensions->append(dim))
   1.864 -            return NULL;
   1.865 -    }
   1.866 -    return postDimensions;
   1.867 -}
   1.868 -
   1.869 -VariableDeclaration *
   1.870 -Parser::var(TokenKind scope, TokenKind kind)
   1.871 -{
   1.872 -    Local<String> tag(zone_);
   1.873 -    if (matchName(tag.ref(), TOK_LABEL) && !tag)
   1.874 -        return NULL;
   1.875 -
   1.876 -    BoundName *type = NULL;
   1.877 -    if (tag)
   1.878 -        type = bindType(tag);
   1.879 -
   1.880 -    Local<String> name(zone_, expectName());
   1.881 -    if (!name)
   1.882 -        return NULL;
   1.883 -
   1.884 -    SourcePosition pos = scanner_.begin();
   1.885 -
   1.886 -    if (BoundName *other = scope_->localLookup(name)) {
   1.887 -        redeclarationError(other);
   1.888 -        return NULL;
   1.889 -    }
   1.890 -
   1.891 -    ExpressionList *postDimensions = NULL;
   1.892 -    if (peek(TOK_LBRACKET)) {
   1.893 -        if ((postDimensions = dimensions()) == NULL)
   1.894 -            return NULL;
   1.895 -    }
   1.896 -    
   1.897 -    Expression *expr = NULL;
   1.898 -    if (match(TOK_ASSIGN)) {
   1.899 -        switch (scanner_.peek()) {
   1.900 -          // Note: we don't support [] literals yet.
   1.901 -          case TOK_LBRACE:
   1.902 -            if ((expr = arrayLiteral(scanner_.scan())) == NULL)
   1.903 -                return NULL;
   1.904 -            break;
   1.905 -
   1.906 -          default:
   1.907 -            if ((expr = expression()) == NULL)
   1.908 -                return NULL;
   1.909 -            break;
   1.910 -        }
   1.911 -    }
   1.912 -
   1.913 -    Variable *var = scope_->declareVariable(name, pos);
   1.914 -    if (!var)
   1.915 -        return NULL;
   1.916 -
   1.917 -    if (scope == TOK_PUBLIC)
   1.918 -        var->setPublic();
   1.919 -
   1.920 -    return new (pool_) VariableDeclaration(var->pos(), kind, var, type, postDimensions, expr);
   1.921 -}
   1.922 -
   1.923 -Statement *
   1.924 -Parser::vars(TokenKind scope, TokenKind kind)
   1.925 -{
   1.926 -    VariableDeclaration *decl = var(scope, kind);
   1.927 -    if (!decl)
   1.928 -        return NULL;
   1.929 -
   1.930 -    if (!peek(TOK_COMMA))
   1.931 -        return decl;
   1.932 -
   1.933 -    StatementList *statements = new (pool_) StatementList();
   1.934 -    if (!statements->append(decl))
   1.935 -        return NULL;
   1.936 -
   1.937 -    while (match(TOK_COMMA)) {
   1.938 -        Statement *decl = var(scope, kind);
   1.939 -        if (!decl)
   1.940 -            return NULL;
   1.941 -        if (!statements->append(decl))
   1.942 -            return NULL;
   1.943 -    }
   1.944 -
   1.945 -    // Create a fake-o block with no scope to create a statement list.
   1.946 -    return new (pool_) BlockStatement(decl->pos(), NULL, statements);
   1.947 -}
   1.948 -
   1.949 -Statement *
   1.950 -Parser::returnStatement()
   1.951 -{
   1.952 -    SourcePosition pos = scanner_.begin();
   1.953 -    if (!expect(TOK_RETURN))
   1.954 -        return NULL;
   1.955 -
   1.956 -    Expression *expr = NULL;
   1.957 -    if (scanner_.peek() != TOK_SEMICOLON) {
   1.958 -        if ((expr = expression()) == NULL)
   1.959 -            return NULL;
   1.960 -
   1.961 -        // We only care about non-void returns when determining whether a
   1.962 -        // tagless function is non-void.
   1.963 -        encounteredReturn_ = true;
   1.964 -    }
   1.965 -
   1.966 -    return new (pool_) ReturnStatement(pos, expr);
   1.967 -}
   1.968 -
   1.969 -Statement *
   1.970 -Parser::expressionStatement()
   1.971 -{
   1.972 -    Expression *left = assignment();
   1.973 -    if (!left)
   1.974 -        return NULL;
   1.975 -
   1.976 -    return new (pool_) ExpressionStatement(left);
   1.977 -}
   1.978 -
   1.979 -Statement *
   1.980 -Parser::block(Scope *scope)
   1.981 -{
   1.982 -    if (!expect(TOK_LBRACE))
   1.983 -        return NULL;
   1.984 -
   1.985 -    SourcePosition pos = scanner_.begin();
   1.986 -    if (!scope && !enterScope(Scope::BLOCK))
   1.987 -        return NULL;
   1.988 -
   1.989 -    StatementList *statements = new (pool_) StatementList();
   1.990 -    while (!match(TOK_RBRACE)) {
   1.991 -        Statement *statement = localStatement();
   1.992 -        if (statement == NULL)
   1.993 -            return NULL;
   1.994 -        if (!statements->append(statement))
   1.995 -            return NULL;
   1.996 -    }
   1.997 -
   1.998 -    if (!scope) {
   1.999 -    	scope = scope_->unlinkIfEmpty();
  1.1000 -        scope_ = scope_->enclosing();
  1.1001 -    }
  1.1002 -    BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
  1.1003 -    return block;
  1.1004 -}
  1.1005 -
  1.1006 -Statement *
  1.1007 -Parser::if_()
  1.1008 -{
  1.1009 -    expect(TOK_IF);
  1.1010 -    
  1.1011 -    SourcePosition pos = scanner_.begin();
  1.1012 -    if (!expect(TOK_LPAREN))
  1.1013 -        return NULL;
  1.1014 -
  1.1015 -    Expression *cond = expression();
  1.1016 -    if (!cond)
  1.1017 -        return NULL;
  1.1018 -
  1.1019 -    if (!expect(TOK_RPAREN))
  1.1020 -        return NULL;
  1.1021 -
  1.1022 -    Statement *ifTrue = localStatement();
  1.1023 -    if (!ifTrue)
  1.1024 -        return NULL;
  1.1025 -
  1.1026 -    IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
  1.1027 -
  1.1028 -    IfStatement *last = outer;
  1.1029 -    while (match(TOK_ELSE)) {
  1.1030 -        if (!match(TOK_IF)) {
  1.1031 -            Statement *ifFalse = localStatement();
  1.1032 -            if (!ifFalse)
  1.1033 -                return NULL;
  1.1034 -
  1.1035 -            last->setIfFalse(ifFalse);
  1.1036 -            break;
  1.1037 -        }
  1.1038 -
  1.1039 -        SourcePosition pos = scanner_.begin();
  1.1040 -        if (!expect(TOK_LPAREN))
  1.1041 -            return NULL;
  1.1042 -
  1.1043 -        Expression *otherCond = expression();
  1.1044 -        if (!otherCond)
  1.1045 -            return NULL;
  1.1046 -
  1.1047 -        if (!expect(TOK_RPAREN))
  1.1048 -            return NULL;
  1.1049 -
  1.1050 -        Statement *otherIfTrue = localStatement();
  1.1051 -        if (!otherIfTrue)
  1.1052 -            return NULL;
  1.1053 -
  1.1054 -        IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
  1.1055 -        last->setIfFalse(inner);
  1.1056 -        last = inner;
  1.1057 -    }
  1.1058 -
  1.1059 -    return outer;
  1.1060 -}
  1.1061 -
  1.1062 -Statement *
  1.1063 -Parser::localStatement()
  1.1064 -{
  1.1065 -    Statement *statement = NULL;
  1.1066 -
  1.1067 -    // Statements which must be followed by a semicolon will break out of the
  1.1068 -    // switch. If they may end in BlockStatements, they'll immediately return.
  1.1069 -
  1.1070 -    TokenKind kind = scanner_.peek();
  1.1071 -    switch (kind) {
  1.1072 -      case TOK_CONST:
  1.1073 -      case TOK_NEW:
  1.1074 -        scanner_.scan();
  1.1075 -        if ((statement = vars(TOK_STOCK, kind)) == NULL)
  1.1076 -          return NULL;
  1.1077 -        break;
  1.1078 -
  1.1079 -      case TOK_FOR:
  1.1080 -        return forStatement();
  1.1081 -
  1.1082 -      case TOK_WHILE:
  1.1083 -        return while_();
  1.1084 -
  1.1085 -      case TOK_BREAK:
  1.1086 -        scanner_.scan();
  1.1087 -        statement = new (pool_) BreakStatement(scanner_.begin());
  1.1088 -        break;
  1.1089 -
  1.1090 -      case TOK_CONTINUE:
  1.1091 -        scanner_.scan();
  1.1092 -        statement = new (pool_) ContinueStatement(scanner_.begin());
  1.1093 -        break;
  1.1094 -
  1.1095 -      case TOK_DO:
  1.1096 -        if ((statement = do_()) == NULL)
  1.1097 -            return NULL;
  1.1098 -        break;
  1.1099 -
  1.1100 -      case TOK_RETURN:
  1.1101 -        if ((statement = returnStatement()) == NULL)
  1.1102 -          return NULL;
  1.1103 -        break;
  1.1104 -
  1.1105 -      case TOK_ENUM:
  1.1106 -        if ((statement = enum_()) == NULL)
  1.1107 -          return NULL;
  1.1108 -        break;
  1.1109 -
  1.1110 -      case TOK_STRUCT:
  1.1111 -        if ((statement = struct_()) == NULL)
  1.1112 -          return NULL;
  1.1113 -        break;
  1.1114 -
  1.1115 -      case TOK_SWITCH:
  1.1116 -        return switch_();
  1.1117 -
  1.1118 -      case TOK_IF:
  1.1119 -        return if_();
  1.1120 -
  1.1121 -      case TOK_LBRACE:
  1.1122 -        return block();
  1.1123 -
  1.1124 -      default:
  1.1125 -        break;
  1.1126 -    }
  1.1127 -
  1.1128 -    if (!statement) {
  1.1129 -        if ((statement = expressionStatement()) == NULL)
  1.1130 -            return NULL;
  1.1131 -    }
  1.1132 -
  1.1133 -    if (!expect(TOK_SEMICOLON))
  1.1134 -        return NULL;
  1.1135 -
  1.1136 -    return statement;
  1.1137 -}
  1.1138 -
  1.1139 -Statement *
  1.1140 -Parser::struct_()
  1.1141 -{
  1.1142 -    expect(TOK_STRUCT);
  1.1143 -
  1.1144 -    Local<String> name(zone_, expectName());
  1.1145 -    if (!name)
  1.1146 -        return NULL;
  1.1147 -
  1.1148 -    SourcePosition pos = scanner_.begin();
  1.1149 -
  1.1150 -    if (BoundName *other = scope_->localLookup(name)) {
  1.1151 -        redeclarationError(other);
  1.1152 -        return NULL;
  1.1153 -    }
  1.1154 -
  1.1155 -    NamedType *type;
  1.1156 -    if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
  1.1157 -        return NULL;
  1.1158 -
  1.1159 -    if (!expect(TOK_LBRACE))
  1.1160 -        return NULL;
  1.1161 -
  1.1162 -    FieldList *fields = new (pool_) FieldList();
  1.1163 -
  1.1164 -    while (!peek(TOK_RBRACE)) {
  1.1165 -        if (matchName(name.ref(), TOK_LABEL) && !name)
  1.1166 -            return NULL;
  1.1167 -
  1.1168 -        BoundName *type = NULL;
  1.1169 -        if (name) {
  1.1170 -            if ((type = bindType(name)) == NULL)
  1.1171 -                return NULL;
  1.1172 -        }
  1.1173 -
  1.1174 -        name = expectName();
  1.1175 -        if (!name)
  1.1176 -            return NULL;
  1.1177 -
  1.1178 -        SourcePosition pos = scanner_.begin();
  1.1179 -
  1.1180 -        ExpressionList *postDimensions = NULL;
  1.1181 -        if (peek(TOK_LBRACKET)) {
  1.1182 -            if ((postDimensions = dimensions()) == NULL)
  1.1183 -                return NULL;
  1.1184 -        }
  1.1185 -
  1.1186 -        if (!matchSemicolon())
  1.1187 -            return NULL;
  1.1188 -
  1.1189 -        StructureStatement::Field *field =
  1.1190 -            new (pool_) StructureStatement::Field(pos, type, name, postDimensions);
  1.1191 -        if (!field || !fields->append(field))
  1.1192 -            return NULL;
  1.1193 -    }
  1.1194 -
  1.1195 -    if (!expect(TOK_RBRACE))
  1.1196 -        return NULL;
  1.1197 -
  1.1198 -    if (fields->empty()) {
  1.1199 -        cc_.reportError(pos, Message_StructCantBeEmpty);
  1.1200 -        return NULL;
  1.1201 -    }
  1.1202 -
  1.1203 -    return new (pool_) StructureStatement(pos, type, fields);
  1.1204 -}
  1.1205 -
  1.1206 -Statement *
  1.1207 -Parser::enum_()
  1.1208 -{
  1.1209 -    expect(TOK_ENUM);
  1.1210 -
  1.1211 -    NamedType *type = NULL;
  1.1212 -    SourcePosition pos = scanner_.begin();
  1.1213 -
  1.1214 -    Local<String> name(zone_);
  1.1215 -    if (matchName(name.ref())) {
  1.1216 -        if (!name)
  1.1217 -            return NULL;
  1.1218 -
  1.1219 -        if (BoundName *other = scope_->localLookup(name)) {
  1.1220 -            redeclarationError(other);
  1.1221 -            return NULL;
  1.1222 -        }
  1.1223 -
  1.1224 -        if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
  1.1225 -            return NULL;
  1.1226 -    }
  1.1227 -
  1.1228 -    EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
  1.1229 -
  1.1230 -    if (!expect(TOK_LBRACE))
  1.1231 -        return NULL;
  1.1232 -
  1.1233 -    do {
  1.1234 -        if (scanner_.peek() == TOK_RBRACE)
  1.1235 -            break;
  1.1236 -
  1.1237 -        Local<String> name(zone_, expectName());
  1.1238 -        if (!name)
  1.1239 -            return NULL;
  1.1240 -
  1.1241 -        if (BoundName *other = scope_->localLookup(name)) {
  1.1242 -            redeclarationError(other);
  1.1243 -            return NULL;
  1.1244 -        }
  1.1245 -
  1.1246 -        NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
  1.1247 -        if (!constant)
  1.1248 -            return NULL;
  1.1249 -
  1.1250 -        Expression *expr = NULL;
  1.1251 -        if (match(TOK_ASSIGN)) {
  1.1252 -            if ((expr = expression()) == NULL)
  1.1253 -                return NULL;
  1.1254 -        }
  1.1255 -
  1.1256 -        if (!entries->append(EnumStatement::Entry(constant, expr)))
  1.1257 -            return NULL;
  1.1258 -    } while (match(TOK_COMMA));
  1.1259 -    if (!expect(TOK_RBRACE))
  1.1260 -        return NULL;
  1.1261 -
  1.1262 -    return new (pool_) EnumStatement(pos, type, name, entries);
  1.1263 -}
  1.1264 -
  1.1265 -Statement *
  1.1266 -Parser::function(TokenKind token)
  1.1267 -{
  1.1268 -    Local<String> returnTag(zone_);
  1.1269 -    if (token == TOK_LABEL) {
  1.1270 -        returnTag = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
  1.1271 -        if (!returnTag)
  1.1272 -            return NULL;
  1.1273 -
  1.1274 -        token = TOK_STOCK;
  1.1275 -    } else {
  1.1276 -        if (peek(TOK_LABEL)) {
  1.1277 -            if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
  1.1278 -                return NULL;
  1.1279 -        } else if (peek(TOK_NAME)) {
  1.1280 -            // Peek for a type that has no :
  1.1281 -            returnTag = expectName();
  1.1282 -            if (!returnTag)
  1.1283 -                return NULL;
  1.1284 -        }
  1.1285 -    }
  1.1286 -
  1.1287 -    Local<String> name(zone_);
  1.1288 -    ExpressionList *returnDimensions = NULL;
  1.1289 -
  1.1290 -    bool allowArrayReturns = token != TOK_NATIVE &&
  1.1291 -                             token != TOK_PUBLIC &&
  1.1292 -                             token != TOK_FORWARD;
  1.1293 -
  1.1294 -    if (allowArrayReturns && peek(TOK_LBRACKET)) {
  1.1295 -        if ((returnDimensions = dimensions()) == NULL)
  1.1296 -            return NULL;
  1.1297 -        if ((name = expectName()) == NULL)
  1.1298 -            return NULL;
  1.1299 -    } else if (peek(TOK_NAME)) {
  1.1300 -        if ((name = expectName()) == NULL)
  1.1301 -            return NULL;
  1.1302 -    } else {
  1.1303 -        // We predicted |type name|, but just got |name| instead.
  1.1304 -        name = returnTag;
  1.1305 -        returnTag = NULL;
  1.1306 -    }
  1.1307 -
  1.1308 -    BoundName *returnType = NULL;
  1.1309 -    if (returnTag)
  1.1310 -        returnType = bindType(returnTag);
  1.1311 -
  1.1312 -    SourcePosition pos = scanner_.begin();
  1.1313 -
  1.1314 -    // The function name goes into the outer (global) scope.
  1.1315 -    assert(!scope_->enclosing());
  1.1316 -
  1.1317 -    NamedType *type = NULL;
  1.1318 -    NamedFunction *fun = NULL;
  1.1319 -    if (BoundName *other = scope_->localLookup(name)) {
  1.1320 -        // We allow a redeclaration if the new type is a public, and the old
  1.1321 -        // type was a forward. However, the forward must come first.
  1.1322 -        if (token == TOK_TYPEDEF || other->kind() != BoundName::FUNCTION) {
  1.1323 -            redeclarationError(other);
  1.1324 -            return NULL;
  1.1325 -        }
  1.1326 -
  1.1327 -        fun = other->toNamedFunction();
  1.1328 -        if (!fun->isForward() || token != TOK_PUBLIC) {
  1.1329 -            redeclarationError(other);
  1.1330 -            return NULL;
  1.1331 -        }
  1.1332 -        
  1.1333 -        // We've got the same name, but the original is a forward, so let it
  1.1334 -        // slide and re-use the original declaration.
  1.1335 -        fun->setImplemented(scanner_.begin());
  1.1336 -    } else if (token == TOK_TYPEDEF) {
  1.1337 -        type = scope_->declareType(name, scanner_.begin());
  1.1338 -        if (!type)
  1.1339 -            return NULL;
  1.1340 -    } else {
  1.1341 -        fun = scope_->declareFunction(name, scanner_.begin(), token);
  1.1342 -        if (!fun)
  1.1343 -            return NULL;
  1.1344 -    }
  1.1345 -
  1.1346 -    if (fun && fun->isPublic())
  1.1347 -        fun->setUsed();
  1.1348 -
  1.1349 -    Scope *scope = enterScope(Scope::FUNCTION);
  1.1350 -    if (!scope)
  1.1351 -        return NULL;
  1.1352 -
  1.1353 -    ParameterList *parameters = new (pool_) ParameterList();
  1.1354 -
  1.1355 -    if (!expect(TOK_LPAREN))
  1.1356 -        return NULL;
  1.1357 -
  1.1358 -    if (!match(TOK_RPAREN)) {
  1.1359 -        while (true) {
  1.1360 -            bool isConst = match(TOK_CONST);
  1.1361 -            bool ref = match(TOK_AMPERSAND);
  1.1362 -
  1.1363 -            SourcePosition begin = scanner_.begin();
  1.1364 -            Local<String> tag(zone_);
  1.1365 -            if (matchName(tag.ref(), TOK_LABEL) && !tag)
  1.1366 -                return NULL;
  1.1367 -
  1.1368 -            BoundName *type = NULL;
  1.1369 -            if (tag)
  1.1370 -                type = bindType(tag);
  1.1371 -
  1.1372 -            if (match(TOK_ELLIPSES)) {
  1.1373 -                if (isConst || ref) {
  1.1374 -                    cc_.reportError(begin, Message_InvalidVarArgs);
  1.1375 -                    return NULL;
  1.1376 -                }
  1.1377 -
  1.1378 -                if (token != TOK_NATIVE) {
  1.1379 -                    cc_.reportError(begin, Message_VarArgsOutsideNative);
  1.1380 -                    return NULL;
  1.1381 -                }
  1.1382 -
  1.1383 -                fun->markNativeVariadic();
  1.1384 -                break;
  1.1385 -            }
  1.1386 -
  1.1387 -            Local<String> name(zone_, expectName());
  1.1388 -            if (!name)
  1.1389 -                return NULL;
  1.1390 -
  1.1391 -            if (BoundName *other = scope_->localLookup(name)) {
  1.1392 -                redeclarationError(other);
  1.1393 -                return NULL;
  1.1394 -            }
  1.1395 -            Variable *arg = scope_->declareArgument(name, scanner_.begin());
  1.1396 -            if (!arg)
  1.1397 -                return NULL;
  1.1398 -
  1.1399 -            // Look for dimensions.
  1.1400 -            ExpressionList *postDimensions = NULL;
  1.1401 -            if (peek(TOK_LBRACKET)) {
  1.1402 -                if ((postDimensions = dimensions()) == NULL)
  1.1403 -                    return NULL;
  1.1404 -            }
  1.1405 -
  1.1406 -            Expression *expr = NULL;
  1.1407 -            if (match(TOK_ASSIGN)) {
  1.1408 -                if ((expr = expression()) == NULL)
  1.1409 -                    return NULL;
  1.1410 -            }
  1.1411 -
  1.1412 -            Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions,
  1.1413 -                                                         expr);
  1.1414 -            if (!parameters->append(parameter))
  1.1415 -                return NULL;
  1.1416 -
  1.1417 -            if (!match(TOK_COMMA))
  1.1418 -                break;
  1.1419 -        }
  1.1420 -        if (!expect(TOK_RPAREN))
  1.1421 -            return NULL;
  1.1422 -    }
  1.1423 -
  1.1424 -    encounteredReturn_ = false;
  1.1425 -
  1.1426 -    Statement *body = NULL;
  1.1427 -    if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
  1.1428 -        body = block();
  1.1429 -        if (!body)
  1.1430 -            return NULL;
  1.1431 -    }
  1.1432 -
  1.1433 -    scope_ = scope_->enclosing();
  1.1434 -
  1.1435 -    FunctionSignature signature(returnType, returnDimensions, parameters);
  1.1436 -    if (token == TOK_TYPEDEF)
  1.1437 -        return new (pool_) FunctionTypeStatement(pos, type, signature);
  1.1438 -
  1.1439 -    return new (pool_) FunctionStatement(pos, scope, fun, body, signature, encounteredReturn_);
  1.1440 -}
  1.1441 -
  1.1442 -static inline bool
  1.1443 -DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
  1.1444 -{
  1.1445 -    Local<String> tag(zone, zone->makeSymbol(name));
  1.1446 -    if (!tag)
  1.1447 -        return false;
  1.1448 -
  1.1449 -    return !!scope->declareType(tag, type);
  1.1450 -}
  1.1451 -
  1.1452 -static inline bool
  1.1453 -DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
  1.1454 -{
  1.1455 -    Local<Type> primitive(zone, zone->types()->getPrimitive(type));
  1.1456 -    assert(primitive);
  1.1457 -    return DeclareIntrinsicType(zone, scope, name, primitive);
  1.1458 -}
  1.1459 -
  1.1460 -bool
  1.1461 -Parser::setupIntrinsics()
  1.1462 -{
  1.1463 -    if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
  1.1464 -        return false;
  1.1465 -    if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
  1.1466 -        return false;
  1.1467 -    if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
  1.1468 -        return false;
  1.1469 -    if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
  1.1470 -        return false;
  1.1471 -
  1.1472 -    Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
  1.1473 -    if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
  1.1474 -        return false;
  1.1475 -
  1.1476 -    Local<Type> voidType(zone_, zone_->types()->getVoid());
  1.1477 -    if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
  1.1478 -        return false;
  1.1479 -
  1.1480 -    Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
  1.1481 -    if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
  1.1482 -        return false;
  1.1483 -
  1.1484 -    return true;
  1.1485 -}
  1.1486 -
  1.1487 -ParseTree *
  1.1488 -Parser::parse()
  1.1489 -{
  1.1490 -    StatementList *statements = new (pool_) StatementList();
  1.1491 -
  1.1492 -    if (!enterScope(Scope::GLOBAL))
  1.1493 -        return NULL;
  1.1494 -
  1.1495 -    if (!setupIntrinsics())
  1.1496 -        return NULL;
  1.1497 -
  1.1498 -    for (;;) {
  1.1499 -        Statement *statement = NULL;
  1.1500 -
  1.1501 -        TokenKind kind = scanner_.peek();
  1.1502 -        switch (kind) {
  1.1503 -          case TOK_ERROR:
  1.1504 -            return NULL;
  1.1505 -
  1.1506 -          case TOK_EOF:
  1.1507 -            break;
  1.1508 -
  1.1509 -          case TOK_NAME:
  1.1510 -            if ((statement = function(TOK_NAME)) == NULL)
  1.1511 -                return NULL;
  1.1512 -            break;
  1.1513 -
  1.1514 -          case TOK_FORWARD:
  1.1515 -          case TOK_PUBLIC:
  1.1516 -          case TOK_NATIVE:
  1.1517 -          case TOK_STOCK:
  1.1518 -          case TOK_LABEL:
  1.1519 -          case TOK_TYPEDEF:
  1.1520 -          {
  1.1521 -            scanner_.scan();
  1.1522 -            if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
  1.1523 -                if ((statement = var(TOK_PUBLIC, scanner_.scan())) == NULL)
  1.1524 -                    return NULL;
  1.1525 -                if (!matchSemicolon())
  1.1526 -                    return NULL;
  1.1527 -            } else {
  1.1528 -                if ((statement = function(kind)) == NULL)
  1.1529 -                    return NULL;
  1.1530 -                if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
  1.1531 -                    return NULL;
  1.1532 -            }
  1.1533 -            break;
  1.1534 -          }
  1.1535 -
  1.1536 -          case TOK_CONST:
  1.1537 -          case TOK_NEW:
  1.1538 -          {
  1.1539 -            // Note: at global scope, we don't accept comma-delimited
  1.1540 -            // declarations yet, to see if we can get away with forcing
  1.1541 -            // a nicer top-level style.
  1.1542 -            scanner_.scan();
  1.1543 -            if ((statement = var(TOK_STOCK, kind)) == NULL)
  1.1544 -                return NULL;
  1.1545 -            if (!matchSemicolon())
  1.1546 -                return NULL;
  1.1547 -            break;
  1.1548 -          }
  1.1549 -
  1.1550 -          case TOK_ENUM:
  1.1551 -            if ((statement = enum_()) == NULL)
  1.1552 -                return NULL;
  1.1553 -            if (!matchSemicolon())
  1.1554 -                return NULL;
  1.1555 -            break;
  1.1556 -
  1.1557 -          case TOK_STRUCT:
  1.1558 -            if ((statement = struct_()) == NULL)
  1.1559 -                return NULL;
  1.1560 -            if (!matchSemicolon())
  1.1561 -                return NULL;
  1.1562 -            break;
  1.1563 -
  1.1564 -          default:
  1.1565 -            cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
  1.1566 -            return NULL;
  1.1567 -        }
  1.1568 -
  1.1569 -        if (!statement)
  1.1570 -            break;
  1.1571 -
  1.1572 -        if (!statements->append(statement))
  1.1573 -            return NULL;
  1.1574 -    }
  1.1575 -
  1.1576 -    return new (pool_) ParseTree(scope_, statements, unbound_);
  1.1577 -}
  1.1578 -
  1.1579 -class AstPrinter : public AstVisitor
  1.1580 -{
  1.1581 -    FILE *fp_;
  1.1582 -    size_t level_;
  1.1583 -
  1.1584 -  private:
  1.1585 -    void prefix() {
  1.1586 -        for (size_t i = 0; i < level_; i++)
  1.1587 -            fprintf(fp_, "  ");
  1.1588 -    }
  1.1589 -    void indent() {
  1.1590 -        level_++;
  1.1591 -    }
  1.1592 -    void unindent() {
  1.1593 -        level_--;
  1.1594 -    }
  1.1595 -
  1.1596 -  public:
  1.1597 -    AstPrinter(FILE *fp)
  1.1598 -      : fp_(fp),
  1.1599 -        level_(0)
  1.1600 -    {
  1.1601 -    }
  1.1602 -
  1.1603 -    void dump(const FunctionSignature &sig) {
  1.1604 -        prefix();
  1.1605 -        fprintf(fp_, "%s", sig.returnType()
  1.1606 -                           ? sig.returnType()->name()->chars()
  1.1607 -                           : "_");
  1.1608 -        if (sig.returnDimensions()) {
  1.1609 -            for (size_t i = 0; i < sig.returnDimensions()->length(); i++)
  1.1610 -                fprintf(fp_, "[]");
  1.1611 -        }
  1.1612 -        fprintf(fp_, "()\n");
  1.1613 -    }
  1.1614 -    void visit(NameProxy *name) {
  1.1615 -        prefix();
  1.1616 -        fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
  1.1617 -                (name->binding() ? "" : " unbound"));
  1.1618 -    }
  1.1619 -    void visit(CallExpression *node) {
  1.1620 -        prefix();
  1.1621 -        fprintf(fp_, "[ CallExpression\n");
  1.1622 -        indent();
  1.1623 -        node->callee()->accept(this);
  1.1624 -        for (size_t i = 0; i < node->arguments()->length(); i++)
  1.1625 -            node->arguments()->at(i)->accept(this);
  1.1626 -        unindent();
  1.1627 -    }
  1.1628 -    void visit(FunctionTypeStatement *node) {
  1.1629 -        prefix();
  1.1630 -        fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->decl()->name()->chars());
  1.1631 -        indent();
  1.1632 -        dump(node->signature());
  1.1633 -        unindent();
  1.1634 -    }
  1.1635 -    void visit(FunctionStatement *node) {
  1.1636 -        prefix();
  1.1637 -        fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
  1.1638 -        indent();
  1.1639 -        dump(node->signature());
  1.1640 -        if (node->body())
  1.1641 -            node->body()->accept(this);
  1.1642 -        unindent();
  1.1643 -    }
  1.1644 -    void visit(ExpressionStatement *node) {
  1.1645 -        prefix();
  1.1646 -        fprintf(fp_, "[ ExpressionStatement\n");
  1.1647 -        indent();
  1.1648 -        node->expression()->accept(this);
  1.1649 -        unindent();
  1.1650 -    }
  1.1651 -    void visit(Assignment *node) {
  1.1652 -        prefix();
  1.1653 -        fprintf(fp_, "[ Assignment\n");
  1.1654 -        indent();
  1.1655 -        node->lvalue()->accept(this);
  1.1656 -        node->expression()->accept(this);
  1.1657 -        unindent();
  1.1658 -    }
  1.1659 -    void visit(TernaryExpression *node) {
  1.1660 -        prefix();
  1.1661 -        fprintf(fp_, "[ TernaryExpression\n");
  1.1662 -        indent();
  1.1663 -        node->condition()->accept(this);
  1.1664 -        node->left()->accept(this);
  1.1665 -        node->right()->accept(this);
  1.1666 -        unindent();
  1.1667 -    }
  1.1668 -    void visit(BinaryExpression *node) {
  1.1669 -        prefix();
  1.1670 -        fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
  1.1671 -        indent();
  1.1672 -        node->left()->accept(this);
  1.1673 -        node->right()->accept(this);
  1.1674 -        unindent();
  1.1675 -    }
  1.1676 -    void visit(UnaryExpression *node) {
  1.1677 -        prefix();
  1.1678 -        fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
  1.1679 -        indent();
  1.1680 -        node->expression()->accept(this);
  1.1681 -        unindent();
  1.1682 -    }
  1.1683 -    void visit(ReturnStatement *node) {
  1.1684 -        prefix();
  1.1685 -        fprintf(fp_, "[ ReturnStatement\n");
  1.1686 -        indent();
  1.1687 -        if (node->expression())
  1.1688 -            node->expression()->accept(this);
  1.1689 -        unindent();
  1.1690 -    }
  1.1691 -    void visit(ForStatement *node) {
  1.1692 -        prefix();
  1.1693 -        fprintf(fp_, "[ ForStatement\n");
  1.1694 -        indent();
  1.1695 -        if (node->initialization())
  1.1696 -            node->initialization()->accept(this);
  1.1697 -        if (node->condition())
  1.1698 -            node->condition()->accept(this);
  1.1699 -        if (node->update())
  1.1700 -            node->update()->accept(this);
  1.1701 -        node->body()->accept(this);
  1.1702 -        unindent();
  1.1703 -    }
  1.1704 -    void visit(BlockStatement *node) {
  1.1705 -        prefix();
  1.1706 -        fprintf(fp_, "[ BlockStatement\n");
  1.1707 -        indent();
  1.1708 -        for (size_t i = 0; i < node->statements()->length(); i++)
  1.1709 -            node->statements()->at(i)->accept(this);
  1.1710 -        unindent();
  1.1711 -    }
  1.1712 -    void visit(VariableDeclaration *node) {
  1.1713 -        prefix();
  1.1714 -        fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
  1.1715 -        indent();
  1.1716 -        if (node->initialization())
  1.1717 -            node->initialization()->accept(this);
  1.1718 -        unindent();
  1.1719 -    }
  1.1720 -    void visit(IntegerLiteral *node) {
  1.1721 -        prefix();
  1.1722 -        fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
  1.1723 -    }
  1.1724 -    void visit(BooleanLiteral *node) {
  1.1725 -        prefix();
  1.1726 -        fprintf(fp_, "[ BooleanLiteral (%s)\n",
  1.1727 -                (node->token() == TOK_TRUE) ? "true" : "false");
  1.1728 -    }
  1.1729 -    void visit(FloatLiteral *node) {
  1.1730 -        prefix();
  1.1731 -        fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
  1.1732 -    }
  1.1733 -    void visit(IfStatement *node) {
  1.1734 -        prefix();
  1.1735 -        fprintf(fp_, "[ IfStatement\n");
  1.1736 -        indent();
  1.1737 -        node->ifTrue()->accept(this);
  1.1738 -        if (node->ifFalse())
  1.1739 -            node->ifFalse()->accept(this);
  1.1740 -        unindent();
  1.1741 -    }
  1.1742 -    void visit(IndexExpression *node) {
  1.1743 -        prefix();
  1.1744 -        fprintf(fp_, "[ IndexExpression\n");
  1.1745 -        indent();
  1.1746 -        node->left()->accept(this);
  1.1747 -        node->right()->accept(this);
  1.1748 -        unindent();
  1.1749 -    }
  1.1750 -    void visit(EnumStatement *node) {
  1.1751 -        prefix();
  1.1752 -        fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
  1.1753 -        indent();
  1.1754 -        for (size_t i = 0; i < node->entries()->length(); i++) {
  1.1755 -            prefix();
  1.1756 -            fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
  1.1757 -            if (node->entries()->at(i).expr) {
  1.1758 -                indent();
  1.1759 -                node->entries()->at(i).expr->accept(this);
  1.1760 -                unindent();
  1.1761 -            }
  1.1762 -        }
  1.1763 -        unindent();
  1.1764 -    }
  1.1765 -    void visit(WhileStatement *node) {
  1.1766 -        prefix();
  1.1767 -        fprintf(fp_, "[ WhileStatement (%s)\n",
  1.1768 -                (node->token() == TOK_DO) ? "do" : "while");
  1.1769 -        indent();
  1.1770 -        if (node->token() == TOK_DO) {
  1.1771 -            node->condition()->accept(this);
  1.1772 -            node->body()->accept(this);
  1.1773 -        } else {
  1.1774 -            node->condition()->accept(this);
  1.1775 -            node->body()->accept(this);
  1.1776 -        }
  1.1777 -        unindent();
  1.1778 -    }
  1.1779 -    void visit(BreakStatement *node) {
  1.1780 -        prefix();
  1.1781 -        fprintf(fp_, "[ BreakStatement\n");
  1.1782 -    }
  1.1783 -    void visit(ContinueStatement *node) {
  1.1784 -        prefix();
  1.1785 -        fprintf(fp_, "[ ContinueStatement\n");
  1.1786 -    }
  1.1787 -    void visit(StringLiteral *node) {
  1.1788 -        prefix();
  1.1789 -        fprintf(fp_, "[ StringLiteral\n");
  1.1790 -    }
  1.1791 -    void visit(IncDecExpression *node) {
  1.1792 -        prefix();
  1.1793 -        fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
  1.1794 -        indent();
  1.1795 -        node->expression()->accept(this);
  1.1796 -        unindent();
  1.1797 -    }
  1.1798 -    void visit(StructureStatement *node) {
  1.1799 -        prefix();
  1.1800 -        fprintf(fp_, "[ StructureStatement %s\n", node->decl()->name()->chars());
  1.1801 -    }
  1.1802 -    void visit(FieldExpression *node) {
  1.1803 -        prefix();
  1.1804 -        fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
  1.1805 -        indent();
  1.1806 -        node->left()->accept(this);
  1.1807 -        unindent();
  1.1808 -    }
  1.1809 -    void visit(SwitchStatement *node) {
  1.1810 -        prefix();
  1.1811 -        fprintf(fp_, "[ SwitchStatement\n");
  1.1812 -        indent();
  1.1813 -        node->expression()->accept(this);
  1.1814 -        for (size_t i = 0; i < node->cases()->length(); i++) {
  1.1815 -            Case *c = node->cases()->at(i);
  1.1816 -            c->expression()->accept(this);
  1.1817 -            if (c->others()) {
  1.1818 -                for (size_t j = 0; j < c->others()->length(); j++)
  1.1819 -                    c->others()->at(j)->accept(this);
  1.1820 -            }
  1.1821 -            indent();
  1.1822 -            c->statement()->accept(this);
  1.1823 -            unindent();
  1.1824 -        }
  1.1825 -        if (node->defaultCase())
  1.1826 -            node->defaultCase()->accept(this);
  1.1827 -        unindent();
  1.1828 -    }
  1.1829 -    void visit(ArrayLiteral *node) {
  1.1830 -        prefix();
  1.1831 -        fprintf(fp_, "[ ArrayLiteral\n");
  1.1832 -        indent();
  1.1833 -        for (size_t i = 0; i < node->expressions()->length(); i++) {
  1.1834 -            Expression *expr = node->expressions()->at(i);
  1.1835 -            indent();
  1.1836 -            expr->accept(this);
  1.1837 -            unindent();
  1.1838 -        }
  1.1839 -    }
  1.1840 -};
  1.1841 -
  1.1842 -void
  1.1843 -ParseTree::dump(FILE *fp)
  1.1844 -{
  1.1845 -    AstPrinter printer(fp);
  1.1846 -
  1.1847 -    for (size_t i = 0; i < statements_->length(); i++)
  1.1848 -        statements_->at(i)->accept(&printer);
  1.1849 -}