1.1 --- a/src/compiler/Parser.cpp Mon Jun 10 00:46:29 2013 +0100
1.2 +++ b/src/compiler/Parser.cpp Mon Jun 10 01:04:43 2013 +0100
1.3 @@ -1,1787 +1,1787 @@
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 "../FixedArray.h"
1.25 -#include "../Heap.h"
1.26 -#include "../Strings.h"
1.27 -#include "../TypeManager.h"
1.28 -#include "Parser.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 - unbound_(NULL)
1.39 -{
1.40 - unbound_ = new (pool_) PoolList<NameProxy *>();
1.41 - imports_ = new (pool_) PoolList<ImportStatement *>();
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 -bool
1.76 -Parser::matchName(String **name, TokenKind kind)
1.77 -{
1.78 - assert(kind == TOK_NAME || kind == TOK_LABEL);
1.79 - *name = NULL;
1.80 - if (!match(kind))
1.81 - return false;
1.82 - *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1.83 - return true;
1.84 -}
1.85 -
1.86 -String *
1.87 -Parser::expectName()
1.88 -{
1.89 - if (!expect(TOK_NAME))
1.90 - return NULL;
1.91 - return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1.92 -}
1.93 -
1.94 -Expression *
1.95 -Parser::primitive()
1.96 -{
1.97 - TokenKind kind = scanner_.peek();
1.98 - switch (kind) {
1.99 - case TOK_FLOAT_LITERAL:
1.100 - {
1.101 - scanner_.scan();
1.102 - double value = Scanner::ParseDouble(scanner_.literal());
1.103 - return new (pool_) FloatLiteral(scanner_.begin(), value);
1.104 - }
1.105 -
1.106 - case TOK_HEX_LITERAL:
1.107 - {
1.108 - scanner_.scan();
1.109 - int value = strtol(scanner_.literal(), NULL, 16);
1.110 - return new (pool_) IntegerLiteral(scanner_.begin(), value);
1.111 - }
1.112 -
1.113 - case TOK_INTEGER_LITERAL:
1.114 - {
1.115 - scanner_.scan();
1.116 - int value = atoi(scanner_.literal());
1.117 - return new (pool_) IntegerLiteral(scanner_.begin(), value);
1.118 - }
1.119 -
1.120 - case TOK_TRUE:
1.121 - case TOK_FALSE:
1.122 - scanner_.scan();
1.123 - return new (pool_) BooleanLiteral(scanner_.begin(), kind);
1.124 -
1.125 - case TOK_STRING_LITERAL:
1.126 - {
1.127 - scanner_.scan();
1.128 - Local<String> string(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.129 - return new (pool_) StringLiteral(scanner_.begin(), string);
1.130 - }
1.131 -
1.132 - default:
1.133 - {
1.134 - if (kind != TOK_ERROR)
1.135 - cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
1.136 - return NULL;
1.137 - }
1.138 - }
1.139 -}
1.140 -
1.141 -Expression *
1.142 -Parser::fixedArrayLiteral()
1.143 -{
1.144 - SourcePosition pos = scanner_.begin();
1.145 -
1.146 - ExpressionList *list = new (pool_) ExpressionList();
1.147 - do {
1.148 - // { } is an illegal array literal.
1.149 - if (list->length() > 0 && match(TOK_LBRACE))
1.150 - break;
1.151 -
1.152 - Expression *expr = NULL;
1.153 - if (peek(TOK_LBRACE))
1.154 - expr = fixedArrayLiteral();
1.155 - else
1.156 - expr = primitive();
1.157 - if (!expr)
1.158 - return NULL;
1.159 -
1.160 - if (!list->append(expr))
1.161 - return NULL;
1.162 -
1.163 - if (!match(TOK_COMMA)) {
1.164 - if (!expect(TOK_RBRACE))
1.165 - return NULL;
1.166 - break;
1.167 - }
1.168 - } while (true);
1.169 -
1.170 - return new (pool_) ArrayLiteral(pos, TOK_LBRACE, list);
1.171 -}
1.172 -
1.173 -Expression *
1.174 -Parser::prefix()
1.175 -{
1.176 - switch (scanner_.peek()) {
1.177 - case TOK_LPAREN:
1.178 - {
1.179 - scanner_.scan();
1.180 - Expression *expr = expression();
1.181 - if (!expr)
1.182 - return NULL;
1.183 - if (!expect(TOK_RPAREN))
1.184 - return NULL;
1.185 - return expr;
1.186 - }
1.187 -
1.188 - case TOK_NAME:
1.189 - {
1.190 - Local<String> name(zone_, expectName());
1.191 - if (!name)
1.192 - return NULL;
1.193 - return new (pool_) NameProxy(scanner_.begin(), name);
1.194 - }
1.195 -
1.196 - default:
1.197 - return primitive();
1.198 - }
1.199 -}
1.200 -
1.201 -// Parses only old-style declarations.
1.202 -bool
1.203 -Parser::typeAndName(Expression **type, String **namep)
1.204 -{
1.205 - if (match(TOK_LABEL)) {
1.206 - // Old-style declaration:
1.207 - // new X:type
1.208 - Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.209 - if (!name)
1.210 - return false;
1.211 -
1.212 - *type = new (pool_) NameProxy(scanner_.begin(), name);
1.213 - *namep = expectName();
1.214 - return !!*namep;
1.215 - }
1.216 -
1.217 - *type = NULL;
1.218 - *namep = expectName();
1.219 -
1.220 - return !!*namep;
1.221 -}
1.222 -
1.223 -// Parses both old and new style declarations.
1.224 -bool
1.225 -Parser::fullTypeAndName(Expression **type, String **namep, DeclKind kind)
1.226 -{
1.227 - // decl ::= newdecl | olddecl
1.228 - // newdecl ::= Type Ident
1.229 - // olddecl ::= Label? (Ident | "...")
1.230 - // type ::= Ident
1.231 - // label ::= Ident ":"
1.232 - //
1.233 - if (match(TOK_LABEL)) {
1.234 - // We something of the form:
1.235 - // Label Ident
1.236 - // or: Label "..."
1.237 - Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.238 - if (!name)
1.239 - return false;
1.240 -
1.241 - *type = new (pool_) NameProxy(scanner_.begin(), name);
1.242 - if (kind == DeclArg && match(TOK_ELLIPSES)) {
1.243 - *namep = NULL;
1.244 - } else {
1.245 - if ((*namep = expectName()) == NULL)
1.246 - return false;
1.247 - }
1.248 - return true;
1.249 - }
1.250 -
1.251 - Local<String> name(zone_, expectName());
1.252 - if (!name)
1.253 - return false;
1.254 -
1.255 - if (peek(TOK_NAME) || (kind == DeclArg && peek(TOK_ELLIPSES))) {
1.256 - // We got something of the form:
1.257 - // Ident Ident
1.258 - *type = new (pool_) NameProxy(scanner_.begin(), name);
1.259 - if (peek(TOK_NAME)) {
1.260 - if ((*namep = expectName()) == NULL)
1.261 - return false;
1.262 - } else {
1.263 - *namep = NULL;
1.264 - }
1.265 - return true;
1.266 - }
1.267 -
1.268 - // We got something of the form:
1.269 - // Ident
1.270 - *type = NULL;
1.271 - *namep = name;
1.272 - return true;
1.273 -}
1.274 -
1.275 -Expression *
1.276 -Parser::call(Expression *callee)
1.277 -{
1.278 - ExpressionList *arguments = new (pool_) ExpressionList();
1.279 -
1.280 - SourcePosition pos = scanner_.begin();
1.281 - expect(TOK_LPAREN);
1.282 -
1.283 - if (!match(TOK_RPAREN)) {
1.284 - while (true) {
1.285 - Expression *expr = expression();
1.286 - if (!expr)
1.287 - return NULL;
1.288 -
1.289 - if (!arguments->append(expr))
1.290 - return NULL;
1.291 -
1.292 - if (!match(TOK_COMMA))
1.293 - break;
1.294 - }
1.295 -
1.296 - if (!expect(TOK_RPAREN))
1.297 - return NULL;
1.298 - }
1.299 -
1.300 - return new (pool_) CallExpression(pos, callee, arguments);
1.301 -}
1.302 -
1.303 -Expression *
1.304 -Parser::index(Expression *left)
1.305 -{
1.306 - expect(TOK_LBRACKET);
1.307 -
1.308 - SourcePosition pos = scanner_.begin();
1.309 - Expression *expr = expression();
1.310 - if (!expr)
1.311 - return NULL;
1.312 -
1.313 - if (!expect(TOK_RBRACKET))
1.314 - return NULL;
1.315 -
1.316 - return new (pool_) IndexExpression(pos, left, expr);
1.317 -}
1.318 -
1.319 -Expression *
1.320 -Parser::field(Expression *left)
1.321 -{
1.322 - expect(TOK_DOT);
1.323 -
1.324 - SourcePosition pos = scanner_.begin();
1.325 - Local<String> name(zone_, expectName());
1.326 - if (!name)
1.327 - return NULL;
1.328 -
1.329 - return new (pool_) FieldExpression(pos, left, name);
1.330 -}
1.331 -
1.332 -Expression *
1.333 -Parser::primary()
1.334 -{
1.335 - Expression *expr = prefix();
1.336 - if (!expr)
1.337 - return NULL;
1.338 -
1.339 - for (;;) {
1.340 - switch (scanner_.peek()) {
1.341 - case TOK_LPAREN:
1.342 - if ((expr = call(expr)) == NULL)
1.343 - return NULL;
1.344 - break;
1.345 -
1.346 - case TOK_LBRACKET:
1.347 - if ((expr = index(expr)) == NULL)
1.348 - return NULL;
1.349 - break;
1.350 -
1.351 - case TOK_DOT:
1.352 - if ((expr = field(expr)) == NULL)
1.353 - return NULL;
1.354 - break;
1.355 -
1.356 - default:
1.357 - return expr;
1.358 - }
1.359 - }
1.360 -}
1.361 -
1.362 -Expression *
1.363 -Parser::unary()
1.364 -{
1.365 - TokenKind token = scanner_.peek();
1.366 -
1.367 - SourcePosition pos = scanner_.begin();
1.368 - switch (token) {
1.369 - case TOK_INCREMENT:
1.370 - case TOK_DECREMENT:
1.371 - {
1.372 - scanner_.scan();
1.373 - Expression *expr = unary();
1.374 - if (!expr)
1.375 - return NULL;
1.376 - return new (pool_) IncDecExpression(pos, token, expr, false);
1.377 - }
1.378 -
1.379 - case TOK_MINUS:
1.380 - case TOK_NOT:
1.381 - case TOK_TILDE:
1.382 - {
1.383 - scanner_.scan();
1.384 - Expression *expr = unary();
1.385 - if (!expr)
1.386 - return NULL;
1.387 - return new (pool_) UnaryExpression(pos, token, expr);
1.388 - }
1.389 -
1.390 - case TOK_SIZEOF:
1.391 - {
1.392 - scanner_.scan();
1.393 - if (!expect(TOK_LPAREN))
1.394 - return NULL;
1.395 - Expression *expr = unary();
1.396 - if (!expr)
1.397 - return NULL;
1.398 - if (!expect(TOK_RPAREN))
1.399 - return NULL;
1.400 - return new (pool_) UnaryExpression(pos, token, expr);
1.401 - }
1.402 -
1.403 - case TOK_LABEL:
1.404 - {
1.405 - scanner_.scan();
1.406 - Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.407 - if (!tag)
1.408 - return NULL;
1.409 -
1.410 - NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), tag);
1.411 -
1.412 - Expression *expr = unary();
1.413 - if (!expr)
1.414 - return NULL;
1.415 -
1.416 - return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, proxy);
1.417 - }
1.418 -
1.419 - default:
1.420 - break;
1.421 - }
1.422 -
1.423 - Expression *expr = primary();
1.424 -
1.425 - token = scanner_.peek();
1.426 - if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
1.427 - scanner_.scan();
1.428 - return new (pool_) IncDecExpression(pos, token, expr, true);
1.429 - }
1.430 -
1.431 - return expr;
1.432 -}
1.433 -
1.434 -Expression *
1.435 -Parser::multiplication()
1.436 -{
1.437 - Expression *left = unary();
1.438 - do {
1.439 - if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
1.440 - break;
1.441 - SourcePosition pos = scanner_.begin();
1.442 - TokenKind kind = scanner_.last();
1.443 - Expression *right = unary();
1.444 - if (!right)
1.445 - return NULL;
1.446 - left = new (pool_) BinaryExpression(pos, kind, left, right);
1.447 - } while (left);
1.448 - return left;
1.449 -}
1.450 -
1.451 -Expression *
1.452 -Parser::addition()
1.453 -{
1.454 - Expression *left = multiplication();
1.455 - while (left) {
1.456 - if (!match(TOK_PLUS) && !match(TOK_MINUS))
1.457 - break;
1.458 - SourcePosition pos = scanner_.begin();
1.459 - TokenKind kind = scanner_.last();
1.460 - Expression *right = multiplication();
1.461 - if (!right)
1.462 - return NULL;
1.463 - left = new (pool_) BinaryExpression(pos, kind, left, right);
1.464 - }
1.465 - return left;
1.466 -}
1.467 -
1.468 -Expression *
1.469 -Parser::shift()
1.470 -{
1.471 - Expression *left = addition();
1.472 - while (left) {
1.473 - if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
1.474 - break;
1.475 - SourcePosition pos = scanner_.begin();
1.476 - TokenKind kind = scanner_.last();
1.477 - Expression *right = addition();
1.478 - if (!right)
1.479 - return NULL;
1.480 - left = new (pool_) BinaryExpression(pos, kind, left, right);
1.481 - }
1.482 - return left;
1.483 -}
1.484 -
1.485 -Expression *
1.486 -Parser::bitand_()
1.487 -{
1.488 - Expression *left = shift();
1.489 - while (left) {
1.490 - if (!match(TOK_BITAND))
1.491 - break;
1.492 - SourcePosition pos = scanner_.begin();
1.493 - Expression *right = shift();
1.494 - if (!right)
1.495 - return NULL;
1.496 - left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
1.497 - }
1.498 - return left;
1.499 -}
1.500 -
1.501 -Expression *
1.502 -Parser::bitxor()
1.503 -{
1.504 - Expression *left = bitand_();
1.505 - while (left) {
1.506 - if (!match(TOK_BITXOR))
1.507 - break;
1.508 - SourcePosition pos = scanner_.begin();
1.509 - Expression *right = shift();
1.510 - if (!right)
1.511 - return NULL;
1.512 - left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
1.513 - }
1.514 - return left;
1.515 -}
1.516 -
1.517 -Expression *
1.518 -Parser::bitor_()
1.519 -{
1.520 - Expression *left = bitxor();
1.521 - while (left) {
1.522 - if (!match(TOK_BITOR))
1.523 - break;
1.524 - SourcePosition pos = scanner_.begin();
1.525 - Expression *right = bitxor();
1.526 - if (!right)
1.527 - return NULL;
1.528 - left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
1.529 - }
1.530 - return left;
1.531 -}
1.532 -
1.533 -Expression *
1.534 -Parser::relational()
1.535 -{
1.536 - Expression *left = bitor_();
1.537 - while (left) {
1.538 - TokenKind kind = scanner_.peek();
1.539 - if (kind < TOK_LT || kind > TOK_GE)
1.540 - break;
1.541 - scanner_.scan();
1.542 - SourcePosition pos = scanner_.begin();
1.543 - Expression *right = shift();
1.544 - if (!right)
1.545 - return NULL;
1.546 - left = new (pool_) BinaryExpression(pos, kind, left, right);
1.547 - }
1.548 - return left;
1.549 -}
1.550 -
1.551 -Expression *
1.552 -Parser::equals()
1.553 -{
1.554 - Expression *left = relational();
1.555 - while (left) {
1.556 - if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
1.557 - break;
1.558 - TokenKind kind = scanner_.last();
1.559 - SourcePosition pos = scanner_.begin();
1.560 - Expression *right = relational();
1.561 - if (!right)
1.562 - return NULL;
1.563 - left = new (pool_) BinaryExpression(pos, kind, left, right);
1.564 - }
1.565 - return left;
1.566 -}
1.567 -
1.568 -Expression *
1.569 -Parser::and_()
1.570 -{
1.571 - Expression *left = equals();
1.572 - while (left) {
1.573 - if (!match(TOK_AND))
1.574 - break;
1.575 - SourcePosition pos = scanner_.begin();
1.576 - Expression *right = equals();
1.577 - if (!right)
1.578 - return NULL;
1.579 - left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
1.580 - }
1.581 - return left;
1.582 -}
1.583 -
1.584 -Expression *
1.585 -Parser::or_()
1.586 -{
1.587 - Expression *left = and_();
1.588 - while (left) {
1.589 - if (!match(TOK_OR))
1.590 - break;
1.591 - SourcePosition pos = scanner_.begin();
1.592 - Expression *right = and_();
1.593 - if (!right)
1.594 - return NULL;
1.595 - left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
1.596 - }
1.597 - return left;
1.598 -}
1.599 -
1.600 -Expression *
1.601 -Parser::ternary()
1.602 -{
1.603 - Expression *cond = or_();
1.604 - if (!cond)
1.605 - return NULL;
1.606 -
1.607 - if (!match(TOK_QMARK))
1.608 - return cond;
1.609 -
1.610 - Expression *left;
1.611 - SourcePosition pos = scanner_.begin();
1.612 - AutoAllowTags<false> disableTags(scanner_);
1.613 - {
1.614 - if ((left = expression()) == NULL)
1.615 - return NULL;
1.616 - }
1.617 -
1.618 - if (!expect(TOK_COLON))
1.619 - return NULL;
1.620 -
1.621 - Expression *right = expression();
1.622 - if (!right)
1.623 - return NULL;
1.624 -
1.625 - return new (pool_) TernaryExpression(pos, cond, left, right);
1.626 -}
1.627 -
1.628 -Expression *
1.629 -Parser::assignment()
1.630 -{
1.631 - Expression *left = ternary();
1.632 - while (left) {
1.633 - TokenKind token = scanner_.peek();
1.634 - if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
1.635 - break;
1.636 - scanner_.scan();
1.637 - SourcePosition pos = scanner_.begin();
1.638 - Expression *expr = ternary();
1.639 - if (!expr)
1.640 - return NULL;
1.641 -
1.642 - left = new (pool_) Assignment(pos, token, left, expr);
1.643 - }
1.644 - return left;
1.645 -}
1.646 -
1.647 -Expression *
1.648 -Parser::expression()
1.649 -{
1.650 - return assignment();
1.651 -}
1.652 -
1.653 -Statement *
1.654 -Parser::while_()
1.655 -{
1.656 - // while ::= "while" "(" expr ")" statement
1.657 - SourcePosition pos = scanner_.begin();
1.658 - scanner_.scan();
1.659 -
1.660 - if (!expect(TOK_LPAREN))
1.661 - return NULL;
1.662 -
1.663 - Expression *condition = expression();
1.664 - if (!condition)
1.665 - return NULL;
1.666 -
1.667 - if (!expect(TOK_RPAREN))
1.668 - return NULL;
1.669 -
1.670 - Statement *body;
1.671 - if (scanner_.peek() == TOK_LBRACE)
1.672 - body = block();
1.673 - else
1.674 - body = localStatement();
1.675 - if (!body)
1.676 - return NULL;
1.677 -
1.678 - return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
1.679 -}
1.680 -
1.681 -Statement *
1.682 -Parser::do_()
1.683 -{
1.684 - // do ::= "do" block "while" "(" expr ")"
1.685 - SourcePosition pos = scanner_.begin();
1.686 - scanner_.scan();
1.687 -
1.688 - Statement *body = block();
1.689 - if (!body)
1.690 - return NULL;
1.691 -
1.692 - if (!expect(TOK_WHILE))
1.693 - return NULL;
1.694 -
1.695 - if (!expect(TOK_LPAREN))
1.696 - return NULL;
1.697 - Expression *condition = expression();
1.698 - if (!condition)
1.699 - return NULL;
1.700 - if (!expect(TOK_RPAREN))
1.701 - return NULL;
1.702 -
1.703 - return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
1.704 -}
1.705 -
1.706 -Statement *
1.707 -Parser::switch_()
1.708 -{
1.709 - // switch ::= "switch" "(" expr ")" "{" case* defaultcase? "}"
1.710 - // case ::= "case" casevals ":" statement
1.711 - // defaultcase ::= "default" ":" statement
1.712 - //
1.713 - expect(TOK_SWITCH);
1.714 -
1.715 - SourcePosition pos = scanner_.begin();
1.716 -
1.717 - if (!expect(TOK_LPAREN))
1.718 - return NULL;
1.719 - Expression *expr = expression();
1.720 - if (!expr)
1.721 - return NULL;
1.722 - if (!expect(TOK_RPAREN))
1.723 - return NULL;
1.724 -
1.725 - if (!expect(TOK_LBRACE))
1.726 - return NULL;
1.727 -
1.728 - SourcePosition defaultPos;
1.729 - PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
1.730 -
1.731 - Statement *defaultCase = NULL;
1.732 -
1.733 - while (!peek(TOK_RBRACE)) {
1.734 - Expression *expr = NULL;
1.735 - ExpressionList *others = NULL;
1.736 - if (match(TOK_DEFAULT)) {
1.737 - if (defaultCase) {
1.738 - cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
1.739 - return NULL;
1.740 - }
1.741 -
1.742 - defaultPos = scanner_.begin();
1.743 - } else {
1.744 - if (defaultCase) {
1.745 - cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
1.746 - return NULL;
1.747 - }
1.748 -
1.749 - if (!expect(TOK_CASE))
1.750 - return NULL;
1.751 -
1.752 - // A limitation in the grammar is that |case <NAME>:| will be
1.753 - // detected as a label.
1.754 - AutoAllowTags<false> disableTags(scanner_);
1.755 -
1.756 - if ((expr = expression()) == NULL)
1.757 - return NULL;
1.758 -
1.759 - if (peek(TOK_COMMA)) {
1.760 - others = new (pool_) ExpressionList();
1.761 - while (match(TOK_COMMA)) {
1.762 - Expression *other = expression();
1.763 - if (!other)
1.764 - return NULL;
1.765 - if (!others->append(other))
1.766 - return NULL;
1.767 - }
1.768 - }
1.769 - }
1.770 -
1.771 - if (!expect(TOK_COLON))
1.772 - return NULL;
1.773 -
1.774 - Statement *statement = localStatement();
1.775 - if (!statement)
1.776 - return NULL;
1.777 -
1.778 - if (!peek(TOK_CASE) &&
1.779 - !peek(TOK_DEFAULT) &&
1.780 - !peek(TOK_RBRACE))
1.781 - {
1.782 - cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
1.783 - return NULL;
1.784 - }
1.785 -
1.786 - if (expr) {
1.787 - Case *caze = new (pool_) Case(expr, others, statement);
1.788 - if (!cases->append(caze))
1.789 - return NULL;
1.790 - } else {
1.791 - defaultCase = statement;
1.792 - }
1.793 - }
1.794 -
1.795 - if (!expect(TOK_RBRACE))
1.796 - return NULL;
1.797 -
1.798 - return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
1.799 -}
1.800 -
1.801 -Statement *
1.802 -Parser::forStatement()
1.803 -{
1.804 - // for ::= "for" "(" forinit? ";" forcond? ";" forstep ")" statement
1.805 - // forint ::= "new" vardecl |
1.806 - // exprstmt
1.807 - // forcond ::= expr
1.808 - // forstep ::= exprstmt
1.809 - //
1.810 - SourcePosition pos = scanner_.begin();
1.811 - scanner_.scan();
1.812 - if (!expect(TOK_LPAREN))
1.813 - return NULL;
1.814 -
1.815 - Statement *decl = NULL;
1.816 - if (!match(TOK_SEMICOLON)) {
1.817 - if (match(TOK_NEW)) {
1.818 - if ((decl = vars(TypeQual_None)) == NULL)
1.819 - return NULL;
1.820 - } else {
1.821 - if ((decl = expressionStatement()) == NULL)
1.822 - return NULL;
1.823 - }
1.824 - if (!expect(TOK_SEMICOLON))
1.825 - return NULL;
1.826 - }
1.827 -
1.828 - Expression *condition = NULL;
1.829 - if (!match(TOK_SEMICOLON)) {
1.830 - if ((condition = expression()) == NULL)
1.831 - return NULL;
1.832 - if (!expect(TOK_SEMICOLON))
1.833 - return NULL;
1.834 - }
1.835 -
1.836 - Statement *update = NULL;
1.837 - if (!match(TOK_RPAREN)) {
1.838 - if ((update = expressionStatement()) == NULL)
1.839 - return NULL;
1.840 - if (!expect(TOK_RPAREN))
1.841 - return NULL;
1.842 - }
1.843 -
1.844 - Statement *body;
1.845 - if (scanner_.peek() == TOK_LBRACE)
1.846 - body = block();
1.847 - else
1.848 - body = localStatement();
1.849 - if (!body)
1.850 - return NULL;
1.851 -
1.852 - return new (pool_) ForStatement(pos, decl, condition, update, body);
1.853 -}
1.854 -
1.855 -ExpressionList *
1.856 -Parser::dimensions()
1.857 -{
1.858 - // dimensions ::= ("[" expr? "]")*
1.859 -
1.860 - ExpressionList *postDimensions = new (pool_) ExpressionList();
1.861 - while (match(TOK_LBRACKET)) {
1.862 - Expression *dim = NULL;
1.863 - if (!match(TOK_RBRACKET)) {
1.864 - if ((dim = expression()) == NULL)
1.865 - return NULL;
1.866 - if (!expect(TOK_RBRACKET))
1.867 - return NULL;
1.868 - }
1.869 -
1.870 - if (!postDimensions->append(dim))
1.871 - return NULL;
1.872 - }
1.873 - return postDimensions;
1.874 -}
1.875 -
1.876 -VariableDeclaration *
1.877 -Parser::var(TypeQualifiers qual)
1.878 -{
1.879 - // vardecl ::= decl ("=" expr)?
1.880 -
1.881 - Expression *type;
1.882 - Local<String> name(zone_);
1.883 -
1.884 - if (!typeAndName(&type, name.ref()))
1.885 - return NULL;
1.886 -
1.887 - ExpressionList *dims = NULL;
1.888 - if (peek(TOK_LBRACKET)) {
1.889 - if ((dims = dimensions()) == NULL)
1.890 - return NULL;;
1.891 - }
1.892 -
1.893 - SourcePosition pos = scanner_.begin();
1.894 -
1.895 - Expression *expr = NULL;
1.896 - if (match(TOK_ASSIGN)) {
1.897 - switch (scanner_.peek()) {
1.898 - // Note: we don't support [] literals yet.
1.899 - case TOK_LBRACE:
1.900 - scanner_.scan();
1.901 - if ((expr = fixedArrayLiteral()) == NULL)
1.902 - return NULL;
1.903 - break;
1.904 -
1.905 - default:
1.906 - if ((expr = expression()) == NULL)
1.907 - return NULL;
1.908 - break;
1.909 - }
1.910 - }
1.911 -
1.912 - return new (pool_) VariableDeclaration(pos, qual, name, type, dims, expr);
1.913 -}
1.914 -
1.915 -Statement *
1.916 -Parser::vars(TypeQualifiers qual)
1.917 -{
1.918 - // localvars ::= ("new" | "const" | "decl") vardecl ("," vardecl)*
1.919 - // globalvars ::= ("public" | "const" | "new" | "public" "const") vardecl
1.920 - VariableDeclaration *decl = var(qual);
1.921 - if (!decl)
1.922 - return NULL;
1.923 -
1.924 - if (!peek(TOK_COMMA))
1.925 - return decl;
1.926 -
1.927 - StatementList *statements = new (pool_) StatementList();
1.928 - if (!statements->append(decl))
1.929 - return NULL;
1.930 -
1.931 - while (match(TOK_COMMA)) {
1.932 - Statement *decl = var(qual);
1.933 - if (!decl)
1.934 - return NULL;
1.935 - if (!statements->append(decl))
1.936 - return NULL;
1.937 - }
1.938 -
1.939 - // Create a fake-o block with no scope to create a statement list.
1.940 - return new (pool_) BlockStatement(decl->pos(), statements, TOK_NEW);
1.941 -}
1.942 -
1.943 -Statement *
1.944 -Parser::returnStatement()
1.945 -{
1.946 - // return ::= "return" term |
1.947 - // "return" "expr"
1.948 -
1.949 - SourcePosition pos = scanner_.begin();
1.950 - if (!expect(TOK_RETURN))
1.951 - return NULL;
1.952 -
1.953 - Expression *expr = NULL;
1.954 - if (scanner_.peek() != TOK_SEMICOLON) {
1.955 - if ((expr = expression()) == NULL)
1.956 - return NULL;
1.957 -
1.958 - // We only care about non-void returns when determining whether a
1.959 - // tagless function is non-void.
1.960 - encounteredReturn_ = true;
1.961 - }
1.962 -
1.963 - return new (pool_) ReturnStatement(pos, expr);
1.964 -}
1.965 -
1.966 -Statement *
1.967 -Parser::expressionStatement()
1.968 -{
1.969 - // exprstmt ::= expr
1.970 - Expression *left = assignment();
1.971 - if (!left)
1.972 - return NULL;
1.973 -
1.974 - return new (pool_) ExpressionStatement(left);
1.975 -}
1.976 -
1.977 -Statement *
1.978 -Parser::block()
1.979 -{
1.980 - // block ::= "{" statement* "}"
1.981 -
1.982 - if (!expect(TOK_LBRACE))
1.983 - return NULL;
1.984 -
1.985 - SourcePosition pos = scanner_.begin();
1.986 -
1.987 - StatementList *statements = new (pool_) StatementList();
1.988 - while (!match(TOK_RBRACE)) {
1.989 - Statement *statement = localStatement();
1.990 - if (statement == NULL)
1.991 - return NULL;
1.992 - if (!statements->append(statement))
1.993 - return NULL;
1.994 - }
1.995 -
1.996 - BlockStatement *block = new (pool_) BlockStatement(pos, statements, TOK_LBRACE);
1.997 - return block;
1.998 -}
1.999 -
1.1000 -Statement *
1.1001 -Parser::if_()
1.1002 -{
1.1003 - // if ::= "if" "(" expr ")" statement elseif* else?
1.1004 - // elseif ::= "elseif" "(" expr ")" statement
1.1005 - // else ::= "else" statement
1.1006 - expect(TOK_IF);
1.1007 -
1.1008 - SourcePosition pos = scanner_.begin();
1.1009 - if (!expect(TOK_LPAREN))
1.1010 - return NULL;
1.1011 -
1.1012 - Expression *cond = expression();
1.1013 - if (!cond)
1.1014 - return NULL;
1.1015 -
1.1016 - if (!expect(TOK_RPAREN))
1.1017 - return NULL;
1.1018 -
1.1019 - Statement *ifTrue = localStatement();
1.1020 - if (!ifTrue)
1.1021 - return NULL;
1.1022 -
1.1023 - IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1.1024 -
1.1025 - IfStatement *last = outer;
1.1026 - while (match(TOK_ELSE)) {
1.1027 - if (!match(TOK_IF)) {
1.1028 - Statement *ifFalse = localStatement();
1.1029 - if (!ifFalse)
1.1030 - return NULL;
1.1031 -
1.1032 - last->setIfFalse(ifFalse);
1.1033 - break;
1.1034 - }
1.1035 -
1.1036 - SourcePosition pos = scanner_.begin();
1.1037 - if (!expect(TOK_LPAREN))
1.1038 - return NULL;
1.1039 -
1.1040 - Expression *otherCond = expression();
1.1041 - if (!otherCond)
1.1042 - return NULL;
1.1043 -
1.1044 - if (!expect(TOK_RPAREN))
1.1045 - return NULL;
1.1046 -
1.1047 - Statement *otherIfTrue = localStatement();
1.1048 - if (!otherIfTrue)
1.1049 - return NULL;
1.1050 -
1.1051 - IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1.1052 - last->setIfFalse(inner);
1.1053 - last = inner;
1.1054 - }
1.1055 -
1.1056 - return outer;
1.1057 -}
1.1058 -
1.1059 -Statement *
1.1060 -Parser::localStatement()
1.1061 -{
1.1062 - // statement ::= stmt term
1.1063 - // stmt ::= do | for | if | while | struct | enum |
1.1064 - // localvars | return | switch | break | continue
1.1065 -
1.1066 - Statement *statement = NULL;
1.1067 -
1.1068 - // Statements which must be followed by a semicolon will break out of the
1.1069 - // switch. If they may end in BlockStatements, they'll immediately return.
1.1070 -
1.1071 - TokenKind kind = scanner_.peek();
1.1072 - switch (kind) {
1.1073 - case TOK_CONST:
1.1074 - case TOK_NEW:
1.1075 - {
1.1076 - TypeQualifiers quals = (kind == TOK_CONST)
1.1077 - ? TypeQual_Const
1.1078 - : TypeQual_None;
1.1079 - scanner_.scan();
1.1080 - if ((statement = vars(quals)) == NULL)
1.1081 - return NULL;
1.1082 - break;
1.1083 - }
1.1084 -
1.1085 - case TOK_FOR:
1.1086 - return forStatement();
1.1087 -
1.1088 - case TOK_WHILE:
1.1089 - return while_();
1.1090 -
1.1091 - case TOK_BREAK:
1.1092 - scanner_.scan();
1.1093 - statement = new (pool_) BreakStatement(scanner_.begin());
1.1094 - break;
1.1095 -
1.1096 - case TOK_CONTINUE:
1.1097 - scanner_.scan();
1.1098 - statement = new (pool_) ContinueStatement(scanner_.begin());
1.1099 - break;
1.1100 -
1.1101 - case TOK_DO:
1.1102 - if ((statement = do_()) == NULL)
1.1103 - return NULL;
1.1104 - break;
1.1105 -
1.1106 - case TOK_RETURN:
1.1107 - if ((statement = returnStatement()) == NULL)
1.1108 - return NULL;
1.1109 - break;
1.1110 -
1.1111 - case TOK_ENUM:
1.1112 - if ((statement = enum_(TOK_NONE)) == NULL)
1.1113 - return NULL;
1.1114 - break;
1.1115 -
1.1116 - case TOK_STRUCT:
1.1117 - if ((statement = struct_()) == NULL)
1.1118 - return NULL;
1.1119 - break;
1.1120 -
1.1121 - case TOK_SWITCH:
1.1122 - return switch_();
1.1123 -
1.1124 - case TOK_IF:
1.1125 - return if_();
1.1126 -
1.1127 - case TOK_LBRACE:
1.1128 - return block();
1.1129 -
1.1130 - default:
1.1131 - break;
1.1132 - }
1.1133 -
1.1134 - if (!statement) {
1.1135 - if ((statement = expressionStatement()) == NULL)
1.1136 - return NULL;
1.1137 - }
1.1138 -
1.1139 - if (!expect(TOK_SEMICOLON))
1.1140 - return NULL;
1.1141 -
1.1142 - return statement;
1.1143 -}
1.1144 -
1.1145 -Statement *
1.1146 -Parser::struct_()
1.1147 -{
1.1148 - // struct ::= "struct" name { struct_fields }
1.1149 - // struct_fields ::= struct_field |
1.1150 - // struct_field struct_fields
1.1151 - // struct_field ::= label? name term
1.1152 - expect(TOK_STRUCT);
1.1153 -
1.1154 - Local<String> name(zone_, expectName());
1.1155 - if (!name)
1.1156 - return NULL;
1.1157 -
1.1158 - SourcePosition pos = scanner_.begin();
1.1159 -
1.1160 - if (!expect(TOK_LBRACE))
1.1161 - return NULL;
1.1162 -
1.1163 - FieldList *fields = new (pool_) FieldList();
1.1164 -
1.1165 - while (!peek(TOK_RBRACE)) {
1.1166 - Expression *type;
1.1167 - Local<String> fieldName(zone_);
1.1168 -
1.1169 - if (!fullTypeAndName(&type, fieldName.ref(), DeclField))
1.1170 - return NULL;
1.1171 -
1.1172 - SourcePosition pos = scanner_.begin();
1.1173 -
1.1174 - if (!matchSemicolon())
1.1175 - return NULL;
1.1176 -
1.1177 - StructureStatement::Field *field =
1.1178 - new (pool_) StructureStatement::Field(pos, type, fieldName);
1.1179 - if (!field || !fields->append(field))
1.1180 - return NULL;
1.1181 - }
1.1182 -
1.1183 - if (!expect(TOK_RBRACE))
1.1184 - return NULL;
1.1185 -
1.1186 - if (fields->empty()) {
1.1187 - cc_.reportError(pos, Message_StructCantBeEmpty);
1.1188 - return NULL;
1.1189 - }
1.1190 -
1.1191 - return new (pool_) StructureStatement(pos, name, fields);
1.1192 -}
1.1193 -
1.1194 -Statement *
1.1195 -Parser::enum_(TokenKind kind)
1.1196 -{
1.1197 - // enum ::= "enum" name? { enum_members? }
1.1198 - // enum_members ::= enum_member ","? |
1.1199 - // enum_member "," enum_members
1.1200 - // enum_member ::= ident ("=" constexpr)?
1.1201 - expect(TOK_ENUM);
1.1202 -
1.1203 - SourcePosition pos = scanner_.begin();
1.1204 -
1.1205 - Local<String> name(zone_);
1.1206 - if (matchName(name.ref()) && !name)
1.1207 - return NULL;
1.1208 -
1.1209 - EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1.1210 -
1.1211 - if (!expect(TOK_LBRACE))
1.1212 - return NULL;
1.1213 -
1.1214 - do {
1.1215 - if (scanner_.peek() == TOK_RBRACE)
1.1216 - break;
1.1217 -
1.1218 - SourcePosition pos = scanner_.begin();
1.1219 - Local<String> name(zone_, expectName());
1.1220 - if (!name)
1.1221 - return NULL;
1.1222 -
1.1223 - Expression *expr = NULL;
1.1224 - if (match(TOK_ASSIGN)) {
1.1225 - if ((expr = expression()) == NULL)
1.1226 - return NULL;
1.1227 - }
1.1228 -
1.1229 - if (!entries->append(EnumStatement::Entry(name, expr, pos)))
1.1230 - return NULL;
1.1231 - } while (match(TOK_COMMA));
1.1232 - if (!expect(TOK_RBRACE))
1.1233 - return NULL;
1.1234 -
1.1235 - return new (pool_) EnumStatement(pos, kind, name, entries);
1.1236 -}
1.1237 -
1.1238 -template <class T>
1.1239 -static inline ScopedRoot<T> *
1.1240 -NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
1.1241 -{
1.1242 - return new (pool) ScopedRoot<T>(obj);
1.1243 -}
1.1244 -
1.1245 -ImportStatement *
1.1246 -Parser::import(TokenKind kind)
1.1247 -{
1.1248 - SourcePosition pos = scanner_.begin();
1.1249 -
1.1250 - // import ::= "from" import_path "import" import_names
1.1251 - // | "import" import_path
1.1252 - // | "import" import_path ".*"
1.1253 - // import_path ::= name
1.1254 - // | name "." import_path
1.1255 - // import_names ::= "*"
1.1256 - // | import_name_list
1.1257 - // import_name_list ::= name
1.1258 - // | name "," import_name_list
1.1259 -
1.1260 - Local<String> name(zone_, expectName());
1.1261 - if (!name)
1.1262 - return NULL;
1.1263 -
1.1264 - PathComponent *root = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
1.1265 - PathComponent *current = root;
1.1266 -
1.1267 - // NULL namelist means that we do not import any names. An empty namelist
1.1268 - // means we import all names.
1.1269 - NameList *names = NULL;
1.1270 -
1.1271 - while (match(TOK_DOT)) {
1.1272 - if (kind == TOK_IMPORT && match(TOK_STAR)) {
1.1273 - names = new (pool_) NameList();
1.1274 - break;
1.1275 - }
1.1276 -
1.1277 - if ((name = expectName()) == NULL)
1.1278 - return NULL;
1.1279 -
1.1280 - current->next = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
1.1281 - current = current->next;
1.1282 - }
1.1283 -
1.1284 - if (kind == TOK_FROM) {
1.1285 - if (!expect(TOK_IMPORT))
1.1286 - return NULL;
1.1287 -
1.1288 - names = new (pool_) NameList();
1.1289 -
1.1290 - if (!match(TOK_STAR)) {
1.1291 - if (!matchName(name.address())) {
1.1292 - cc_.reportError(scanner_.begin(), Message_BadImportFrom);
1.1293 - return NULL;
1.1294 - }
1.1295 -
1.1296 - if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
1.1297 - return NULL;
1.1298 -
1.1299 - while (match(TOK_COMMA)) {
1.1300 - if ((name = expectName()) == NULL)
1.1301 - return NULL;
1.1302 - if (!names->append(NewScopedRoot<String>(pool_, name)))
1.1303 - return NULL;
1.1304 - }
1.1305 - }
1.1306 - }
1.1307 -
1.1308 - return new (pool_) ImportStatement(pos, root, names);
1.1309 -}
1.1310 -
1.1311 -Statement *
1.1312 -Parser::function(TokenKind token)
1.1313 -{
1.1314 - Expression *returnType;
1.1315 - Local<String> name(zone_);
1.1316 -
1.1317 - if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
1.1318 - return NULL;
1.1319 -
1.1320 - SourcePosition pos = scanner_.begin();
1.1321 - ParameterList *parameters = new (pool_) ParameterList();
1.1322 -
1.1323 - if (!expect(TOK_LPAREN))
1.1324 - return NULL;
1.1325 -
1.1326 - bool variadic = false;
1.1327 -
1.1328 - if (!match(TOK_RPAREN)) {
1.1329 - while (true) {
1.1330 - TypeQualifiers quals = TypeQual_None;
1.1331 - if (match(TOK_CONST))
1.1332 - quals = TypeQualifiers(quals | TypeQual_Const);
1.1333 -
1.1334 - bool ref = match(TOK_AMPERSAND);
1.1335 -
1.1336 - SourcePosition begin = scanner_.begin();
1.1337 - Expression *type;
1.1338 - Local<String> name(zone_);
1.1339 - if (!fullTypeAndName(&type, name.ref(), DeclArg))
1.1340 - return NULL;
1.1341 -
1.1342 - if (!name) {
1.1343 - if ((quals & TypeQual_Const) || ref) {
1.1344 - cc_.reportError(begin, Message_InvalidVarArgs);
1.1345 - return NULL;
1.1346 - }
1.1347 -
1.1348 - if (token != TOK_NATIVE) {
1.1349 - cc_.reportError(begin, Message_VarArgsOutsideNative);
1.1350 - return NULL;
1.1351 - }
1.1352 -
1.1353 - variadic = true;
1.1354 - break;
1.1355 - }
1.1356 -
1.1357 - ExpressionList *dims = NULL;
1.1358 - if (peek(TOK_LBRACKET)) {
1.1359 - if ((dims = dimensions()) == NULL)
1.1360 - return NULL;
1.1361 - }
1.1362 -
1.1363 - Expression *expr = NULL;
1.1364 - if (match(TOK_ASSIGN)) {
1.1365 - if ((expr = expression()) == NULL)
1.1366 - return NULL;
1.1367 - }
1.1368 -
1.1369 - Parameter *parameter = new (pool_) Parameter(name, type, ref, quals, dims, expr, begin);
1.1370 - if (!parameters->append(parameter))
1.1371 - return NULL;
1.1372 -
1.1373 - if (!match(TOK_COMMA))
1.1374 - break;
1.1375 - }
1.1376 - if (!expect(TOK_RPAREN))
1.1377 - return NULL;
1.1378 - }
1.1379 -
1.1380 - encounteredReturn_ = false;
1.1381 -
1.1382 - Statement *body = NULL;
1.1383 - if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1.1384 - body = block();
1.1385 - if (!body)
1.1386 - return NULL;
1.1387 - }
1.1388 -
1.1389 - FunctionSignature signature(returnType, parameters, variadic);
1.1390 - if (token == TOK_TYPEDEF)
1.1391 - return new (pool_) FunctionTypeStatement(pos, name, signature);
1.1392 -
1.1393 - return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
1.1394 -}
1.1395 -
1.1396 -static inline bool
1.1397 -DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1.1398 -{
1.1399 - Local<String> tag(zone, zone->makeSymbol(name));
1.1400 - if (!tag)
1.1401 - return false;
1.1402 -
1.1403 - assert(false);
1.1404 - return false; //return !!scope->declareType(tag, type);
1.1405 -}
1.1406 -
1.1407 -static inline bool
1.1408 -DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1.1409 -{
1.1410 - Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1.1411 - assert(primitive);
1.1412 - return DeclareIntrinsicType(zone, scope, name, primitive);
1.1413 -}
1.1414 -
1.1415 -ParseTree *
1.1416 -Parser::parse()
1.1417 -{
1.1418 - StatementList *statements = new (pool_) StatementList();
1.1419 -
1.1420 - for (;;) {
1.1421 - Statement *statement = NULL;
1.1422 -
1.1423 - TokenKind kind = scanner_.peek();
1.1424 - switch (kind) {
1.1425 - case TOK_ERROR:
1.1426 - return NULL;
1.1427 -
1.1428 - case TOK_EOF:
1.1429 - break;
1.1430 -
1.1431 - case TOK_NAME:
1.1432 - if ((statement = function(TOK_NAME)) == NULL)
1.1433 - return NULL;
1.1434 - break;
1.1435 -
1.1436 - case TOK_FROM:
1.1437 - case TOK_IMPORT:
1.1438 - {
1.1439 - scanner_.scan();
1.1440 - if (statements->length())
1.1441 - cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
1.1442 - ImportStatement *stmt = import(kind);
1.1443 - if (!stmt)
1.1444 - return NULL;
1.1445 - if (!imports_->append(stmt))
1.1446 - return NULL;
1.1447 - if (!matchSemicolon())
1.1448 - return NULL;
1.1449 - continue;
1.1450 - }
1.1451 -
1.1452 - case TOK_FORWARD:
1.1453 - case TOK_PUBLIC:
1.1454 - case TOK_NATIVE:
1.1455 - case TOK_STOCK:
1.1456 - case TOK_LABEL:
1.1457 - case TOK_TYPEDEF:
1.1458 - {
1.1459 - if (kind != TOK_LABEL)
1.1460 - scanner_.scan();
1.1461 - if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1.1462 - if ((statement = var(TypeQual_Const)) == NULL)
1.1463 - return NULL;
1.1464 - if (!matchSemicolon())
1.1465 - return NULL;
1.1466 - } else if (kind == TOK_PUBLIC && peek(TOK_ENUM)) {
1.1467 - if ((statement = enum_(kind)) == NULL)
1.1468 - return NULL;
1.1469 - if (!matchSemicolon())
1.1470 - return NULL;
1.1471 - } else {
1.1472 - if ((statement = function(kind)) == NULL)
1.1473 - return NULL;
1.1474 - if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1.1475 - return NULL;
1.1476 - }
1.1477 - break;
1.1478 - }
1.1479 -
1.1480 - case TOK_CONST:
1.1481 - case TOK_NEW:
1.1482 - {
1.1483 - TypeQualifiers quals = (kind == TOK_CONST) ? TypeQual_Const : TypeQual_None;
1.1484 - // Note: at global scope, we don't accept comma-delimited
1.1485 - // declarations yet, to see if we can get away with forcing
1.1486 - // a nicer top-level style.
1.1487 - scanner_.scan();
1.1488 - if ((statement = var(quals)) == NULL)
1.1489 - return NULL;
1.1490 - if (!matchSemicolon())
1.1491 - return NULL;
1.1492 - break;
1.1493 - }
1.1494 -
1.1495 - case TOK_ENUM:
1.1496 - if ((statement = enum_(TOK_NONE)) == NULL)
1.1497 - return NULL;
1.1498 - if (!matchSemicolon())
1.1499 - return NULL;
1.1500 - break;
1.1501 -
1.1502 - case TOK_STRUCT:
1.1503 - if ((statement = struct_()) == NULL)
1.1504 - return NULL;
1.1505 - if (!matchSemicolon())
1.1506 - return NULL;
1.1507 - break;
1.1508 -
1.1509 - default:
1.1510 - cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1.1511 - return NULL;
1.1512 - }
1.1513 -
1.1514 - if (!statement)
1.1515 - break;
1.1516 -
1.1517 - if (!statements->append(statement))
1.1518 - return NULL;
1.1519 - }
1.1520 -
1.1521 - return new (pool_) ParseTree(statements, unbound_, imports_);
1.1522 -}
1.1523 -
1.1524 -class AstPrinter : public AstVisitor
1.1525 -{
1.1526 - FILE *fp_;
1.1527 - size_t level_;
1.1528 -
1.1529 - private:
1.1530 - void prefix() {
1.1531 - for (size_t i = 0; i < level_; i++)
1.1532 - fprintf(fp_, " ");
1.1533 - }
1.1534 - void indent() {
1.1535 - level_++;
1.1536 - }
1.1537 - void unindent() {
1.1538 - level_--;
1.1539 - }
1.1540 -
1.1541 - public:
1.1542 - AstPrinter(FILE *fp)
1.1543 - : fp_(fp),
1.1544 - level_(0)
1.1545 - {
1.1546 - }
1.1547 -
1.1548 - void dump(const FunctionSignature &sig) {
1.1549 - prefix();
1.1550 - fprintf(fp_, "()\n");
1.1551 - }
1.1552 - void visitNameProxy(NameProxy *name) {
1.1553 - prefix();
1.1554 - fprintf(fp_, "[ NameProxy (%s)\n", name->name()->chars());
1.1555 - }
1.1556 - void visitCallExpression(CallExpression *node) {
1.1557 - prefix();
1.1558 - fprintf(fp_, "[ CallExpression\n");
1.1559 - indent();
1.1560 - node->callee()->accept(this);
1.1561 - for (size_t i = 0; i < node->arguments()->length(); i++)
1.1562 - node->arguments()->at(i)->accept(this);
1.1563 - unindent();
1.1564 - }
1.1565 - void visitFunctionTypeStatement(FunctionTypeStatement *node) {
1.1566 - prefix();
1.1567 - fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->name()->chars());
1.1568 - indent();
1.1569 - dump(node->signature());
1.1570 - unindent();
1.1571 - }
1.1572 - void visitFunctionStatement(FunctionStatement *node) {
1.1573 - prefix();
1.1574 - fprintf(fp_, "[ FunctionStatement (%s)\n", node->name()->chars());
1.1575 - indent();
1.1576 - dump(node->signature());
1.1577 - if (node->body())
1.1578 - node->body()->accept(this);
1.1579 - unindent();
1.1580 - }
1.1581 - void visitExpressionStatement(ExpressionStatement *node) {
1.1582 - prefix();
1.1583 - fprintf(fp_, "[ ExpressionStatement\n");
1.1584 - indent();
1.1585 - node->expression()->accept(this);
1.1586 - unindent();
1.1587 - }
1.1588 - void visitAssignment(Assignment *node) {
1.1589 - prefix();
1.1590 - fprintf(fp_, "[ Assignment\n");
1.1591 - indent();
1.1592 - node->lvalue()->accept(this);
1.1593 - node->expression()->accept(this);
1.1594 - unindent();
1.1595 - }
1.1596 - void visitTernaryExpression(TernaryExpression *node) {
1.1597 - prefix();
1.1598 - fprintf(fp_, "[ TernaryExpression\n");
1.1599 - indent();
1.1600 - node->condition()->accept(this);
1.1601 - node->left()->accept(this);
1.1602 - node->right()->accept(this);
1.1603 - unindent();
1.1604 - }
1.1605 - void visitBinaryExpression(BinaryExpression *node) {
1.1606 - prefix();
1.1607 - fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1.1608 - indent();
1.1609 - node->left()->accept(this);
1.1610 - node->right()->accept(this);
1.1611 - unindent();
1.1612 - }
1.1613 - void visitUnaryExpression(UnaryExpression *node) {
1.1614 - prefix();
1.1615 - fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1.1616 - indent();
1.1617 - node->expression()->accept(this);
1.1618 - unindent();
1.1619 - }
1.1620 - void visitReturnStatement(ReturnStatement *node) {
1.1621 - prefix();
1.1622 - fprintf(fp_, "[ ReturnStatement\n");
1.1623 - indent();
1.1624 - if (node->expression())
1.1625 - node->expression()->accept(this);
1.1626 - unindent();
1.1627 - }
1.1628 - void visitForStatement(ForStatement *node) {
1.1629 - prefix();
1.1630 - fprintf(fp_, "[ ForStatement\n");
1.1631 - indent();
1.1632 - if (node->initialization())
1.1633 - node->initialization()->accept(this);
1.1634 - if (node->condition())
1.1635 - node->condition()->accept(this);
1.1636 - if (node->update())
1.1637 - node->update()->accept(this);
1.1638 - node->body()->accept(this);
1.1639 - unindent();
1.1640 - }
1.1641 - void visitBlockStatement(BlockStatement *node) {
1.1642 - prefix();
1.1643 - fprintf(fp_, "[ BlockStatement\n");
1.1644 - indent();
1.1645 - for (size_t i = 0; i < node->statements()->length(); i++)
1.1646 - node->statements()->at(i)->accept(this);
1.1647 - unindent();
1.1648 - }
1.1649 - void visitVariableDeclaration(VariableDeclaration *node) {
1.1650 - prefix();
1.1651 - fprintf(fp_, "[ VariableDeclaration (%s)\n", node->name()->chars());
1.1652 - indent();
1.1653 - if (node->initialization())
1.1654 - node->initialization()->accept(this);
1.1655 - unindent();
1.1656 - }
1.1657 - void visitIntegerLiteral(IntegerLiteral *node) {
1.1658 - prefix();
1.1659 - fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1.1660 - }
1.1661 - void visitBooleanLiteral(BooleanLiteral *node) {
1.1662 - prefix();
1.1663 - fprintf(fp_, "[ BooleanLiteral (%s)\n",
1.1664 - (node->token() == TOK_TRUE) ? "true" : "false");
1.1665 - }
1.1666 - void visitFloatLiteral(FloatLiteral *node) {
1.1667 - prefix();
1.1668 - fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1.1669 - }
1.1670 - void visitIfStatement(IfStatement *node) {
1.1671 - prefix();
1.1672 - fprintf(fp_, "[ IfStatement\n");
1.1673 - indent();
1.1674 - node->ifTrue()->accept(this);
1.1675 - if (node->ifFalse())
1.1676 - node->ifFalse()->accept(this);
1.1677 - unindent();
1.1678 - }
1.1679 - void visitIndexExpression(IndexExpression *node) {
1.1680 - prefix();
1.1681 - fprintf(fp_, "[ IndexExpression\n");
1.1682 - indent();
1.1683 - node->left()->accept(this);
1.1684 - node->right()->accept(this);
1.1685 - unindent();
1.1686 - }
1.1687 - void visitEnumStatement(EnumStatement *node) {
1.1688 - prefix();
1.1689 - fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1.1690 - indent();
1.1691 - for (size_t i = 0; i < node->entries()->length(); i++) {
1.1692 - prefix();
1.1693 - fprintf(fp_, "%s =\n", node->entries()->at(i).name->chars());
1.1694 - if (node->entries()->at(i).expr) {
1.1695 - indent();
1.1696 - node->entries()->at(i).expr->accept(this);
1.1697 - unindent();
1.1698 - }
1.1699 - }
1.1700 - unindent();
1.1701 - }
1.1702 - void visitWhileStatement(WhileStatement *node) {
1.1703 - prefix();
1.1704 - fprintf(fp_, "[ WhileStatement (%s)\n",
1.1705 - (node->token() == TOK_DO) ? "do" : "while");
1.1706 - indent();
1.1707 - if (node->token() == TOK_DO) {
1.1708 - node->condition()->accept(this);
1.1709 - node->body()->accept(this);
1.1710 - } else {
1.1711 - node->condition()->accept(this);
1.1712 - node->body()->accept(this);
1.1713 - }
1.1714 - unindent();
1.1715 - }
1.1716 - void visitBreakStatement(BreakStatement *node) {
1.1717 - prefix();
1.1718 - fprintf(fp_, "[ BreakStatement\n");
1.1719 - }
1.1720 - void visitContinueStatement(ContinueStatement *node) {
1.1721 - prefix();
1.1722 - fprintf(fp_, "[ ContinueStatement\n");
1.1723 - }
1.1724 - void visitStringLiteral(StringLiteral *node) {
1.1725 - prefix();
1.1726 - fprintf(fp_, "[ StringLiteral\n");
1.1727 - }
1.1728 - void visitIncDecExpression(IncDecExpression *node) {
1.1729 - prefix();
1.1730 - fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1.1731 - indent();
1.1732 - node->expression()->accept(this);
1.1733 - unindent();
1.1734 - }
1.1735 - void visitStructureStatement(StructureStatement *node) {
1.1736 - prefix();
1.1737 - fprintf(fp_, "[ StructureStatement %s\n", node->name()->chars());
1.1738 - }
1.1739 - void visitFieldExpression(FieldExpression *node) {
1.1740 - prefix();
1.1741 - fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1.1742 - indent();
1.1743 - node->left()->accept(this);
1.1744 - unindent();
1.1745 - }
1.1746 - void visitSwitchStatement(SwitchStatement *node) {
1.1747 - prefix();
1.1748 - fprintf(fp_, "[ SwitchStatement\n");
1.1749 - indent();
1.1750 - node->expression()->accept(this);
1.1751 - for (size_t i = 0; i < node->cases()->length(); i++) {
1.1752 - Case *c = node->cases()->at(i);
1.1753 - c->expression()->accept(this);
1.1754 - if (c->others()) {
1.1755 - for (size_t j = 0; j < c->others()->length(); j++)
1.1756 - c->others()->at(j)->accept(this);
1.1757 - }
1.1758 - indent();
1.1759 - c->statement()->accept(this);
1.1760 - unindent();
1.1761 - }
1.1762 - if (node->defaultCase())
1.1763 - node->defaultCase()->accept(this);
1.1764 - unindent();
1.1765 - }
1.1766 - void visitArrayLiteral(ArrayLiteral *node) {
1.1767 - prefix();
1.1768 - fprintf(fp_, "[ ArrayLiteral\n");
1.1769 - indent();
1.1770 - for (size_t i = 0; i < node->expressions()->length(); i++) {
1.1771 - Expression *expr = node->expressions()->at(i);
1.1772 - indent();
1.1773 - expr->accept(this);
1.1774 - unindent();
1.1775 - }
1.1776 - }
1.1777 - void visitImportStatement(ImportStatement *node) {
1.1778 - prefix();
1.1779 - fprintf(fp_, "[ ImportStatement\n");
1.1780 - }
1.1781 -};
1.1782 -
1.1783 -void
1.1784 -ParseTree::dump(FILE *fp)
1.1785 -{
1.1786 - AstPrinter printer(fp);
1.1787 -
1.1788 - for (size_t i = 0; i < statements_->length(); i++)
1.1789 - statements_->at(i)->accept(&printer);
1.1790 -}
1.1791 +/* vim: set ts=4 sw=4 tw=99 et:
1.1792 + *
1.1793 + * Copyright (C) 2012 David Anderson
1.1794 + *
1.1795 + * This file is part of SourcePawn.
1.1796 + *
1.1797 + * SourcePawn is free software: you can redistribute it and/or modify it under
1.1798 + * the terms of the GNU General Public License as published by the Free
1.1799 + * Software Foundation, either version 3 of the License, or (at your option)
1.1800 + * any later version.
1.1801 + *
1.1802 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
1.1803 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.1804 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.1805 + *
1.1806 + * You should have received a copy of the GNU General Public License along with
1.1807 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.1808 + */
1.1809 +#include <string.h>
1.1810 +#include "../Zone.h"
1.1811 +#include "../FixedArray.h"
1.1812 +#include "../Heap.h"
1.1813 +#include "../Strings.h"
1.1814 +#include "../TypeManager.h"
1.1815 +#include "Parser.h"
1.1816 +#include "../Heap-inl.h"
1.1817 +
1.1818 +using namespace ke;
1.1819 +
1.1820 +Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
1.1821 + : zone_(zone),
1.1822 + cc_(cc),
1.1823 + pool_(zone_->pool()),
1.1824 + scanner_(cc, stream, length),
1.1825 + unbound_(NULL)
1.1826 +{
1.1827 + unbound_ = new (pool_) PoolList<NameProxy *>();
1.1828 + imports_ = new (pool_) PoolList<ImportStatement *>();
1.1829 +}
1.1830 +
1.1831 +bool
1.1832 +Parser::peek(TokenKind kind)
1.1833 +{
1.1834 + return scanner_.peek() == kind;
1.1835 +}
1.1836 +
1.1837 +bool
1.1838 +Parser::match(TokenKind kind)
1.1839 +{
1.1840 + if (!peek(kind))
1.1841 + return false;
1.1842 + scanner_.scan();
1.1843 + return true;
1.1844 +}
1.1845 +
1.1846 +bool
1.1847 +Parser::matchSemicolon()
1.1848 +{
1.1849 + return expect(TOK_SEMICOLON);
1.1850 +}
1.1851 +
1.1852 +bool
1.1853 +Parser::expect(TokenKind kind)
1.1854 +{
1.1855 + TokenKind got = scanner_.scan();
1.1856 + if (got == kind)
1.1857 + return true;
1.1858 + cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
1.1859 + return false;
1.1860 +}
1.1861 +
1.1862 +bool
1.1863 +Parser::matchName(String **name, TokenKind kind)
1.1864 +{
1.1865 + assert(kind == TOK_NAME || kind == TOK_LABEL);
1.1866 + *name = NULL;
1.1867 + if (!match(kind))
1.1868 + return false;
1.1869 + *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1.1870 + return true;
1.1871 +}
1.1872 +
1.1873 +String *
1.1874 +Parser::expectName()
1.1875 +{
1.1876 + if (!expect(TOK_NAME))
1.1877 + return NULL;
1.1878 + return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1.1879 +}
1.1880 +
1.1881 +Expression *
1.1882 +Parser::primitive()
1.1883 +{
1.1884 + TokenKind kind = scanner_.peek();
1.1885 + switch (kind) {
1.1886 + case TOK_FLOAT_LITERAL:
1.1887 + {
1.1888 + scanner_.scan();
1.1889 + double value = Scanner::ParseDouble(scanner_.literal());
1.1890 + return new (pool_) FloatLiteral(scanner_.begin(), value);
1.1891 + }
1.1892 +
1.1893 + case TOK_HEX_LITERAL:
1.1894 + {
1.1895 + scanner_.scan();
1.1896 + int value = strtol(scanner_.literal(), NULL, 16);
1.1897 + return new (pool_) IntegerLiteral(scanner_.begin(), value);
1.1898 + }
1.1899 +
1.1900 + case TOK_INTEGER_LITERAL:
1.1901 + {
1.1902 + scanner_.scan();
1.1903 + int value = atoi(scanner_.literal());
1.1904 + return new (pool_) IntegerLiteral(scanner_.begin(), value);
1.1905 + }
1.1906 +
1.1907 + case TOK_TRUE:
1.1908 + case TOK_FALSE:
1.1909 + scanner_.scan();
1.1910 + return new (pool_) BooleanLiteral(scanner_.begin(), kind);
1.1911 +
1.1912 + case TOK_STRING_LITERAL:
1.1913 + {
1.1914 + scanner_.scan();
1.1915 + Local<String> string(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.1916 + return new (pool_) StringLiteral(scanner_.begin(), string);
1.1917 + }
1.1918 +
1.1919 + default:
1.1920 + {
1.1921 + if (kind != TOK_ERROR)
1.1922 + cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
1.1923 + return NULL;
1.1924 + }
1.1925 + }
1.1926 +}
1.1927 +
1.1928 +Expression *
1.1929 +Parser::fixedArrayLiteral()
1.1930 +{
1.1931 + SourcePosition pos = scanner_.begin();
1.1932 +
1.1933 + ExpressionList *list = new (pool_) ExpressionList();
1.1934 + do {
1.1935 + // { } is an illegal array literal.
1.1936 + if (list->length() > 0 && match(TOK_LBRACE))
1.1937 + break;
1.1938 +
1.1939 + Expression *expr = NULL;
1.1940 + if (peek(TOK_LBRACE))
1.1941 + expr = fixedArrayLiteral();
1.1942 + else
1.1943 + expr = primitive();
1.1944 + if (!expr)
1.1945 + return NULL;
1.1946 +
1.1947 + if (!list->append(expr))
1.1948 + return NULL;
1.1949 +
1.1950 + if (!match(TOK_COMMA)) {
1.1951 + if (!expect(TOK_RBRACE))
1.1952 + return NULL;
1.1953 + break;
1.1954 + }
1.1955 + } while (true);
1.1956 +
1.1957 + return new (pool_) ArrayLiteral(pos, TOK_LBRACE, list);
1.1958 +}
1.1959 +
1.1960 +Expression *
1.1961 +Parser::prefix()
1.1962 +{
1.1963 + switch (scanner_.peek()) {
1.1964 + case TOK_LPAREN:
1.1965 + {
1.1966 + scanner_.scan();
1.1967 + Expression *expr = expression();
1.1968 + if (!expr)
1.1969 + return NULL;
1.1970 + if (!expect(TOK_RPAREN))
1.1971 + return NULL;
1.1972 + return expr;
1.1973 + }
1.1974 +
1.1975 + case TOK_NAME:
1.1976 + {
1.1977 + Local<String> name(zone_, expectName());
1.1978 + if (!name)
1.1979 + return NULL;
1.1980 + return new (pool_) NameProxy(scanner_.begin(), name);
1.1981 + }
1.1982 +
1.1983 + default:
1.1984 + return primitive();
1.1985 + }
1.1986 +}
1.1987 +
1.1988 +// Parses only old-style declarations.
1.1989 +bool
1.1990 +Parser::typeAndName(Expression **type, String **namep)
1.1991 +{
1.1992 + if (match(TOK_LABEL)) {
1.1993 + // Old-style declaration:
1.1994 + // new X:type
1.1995 + Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.1996 + if (!name)
1.1997 + return false;
1.1998 +
1.1999 + *type = new (pool_) NameProxy(scanner_.begin(), name);
1.2000 + *namep = expectName();
1.2001 + return !!*namep;
1.2002 + }
1.2003 +
1.2004 + *type = NULL;
1.2005 + *namep = expectName();
1.2006 +
1.2007 + return !!*namep;
1.2008 +}
1.2009 +
1.2010 +// Parses both old and new style declarations.
1.2011 +bool
1.2012 +Parser::fullTypeAndName(Expression **type, String **namep, DeclKind kind)
1.2013 +{
1.2014 + // decl ::= newdecl | olddecl
1.2015 + // newdecl ::= Type Ident
1.2016 + // olddecl ::= Label? (Ident | "...")
1.2017 + // type ::= Ident
1.2018 + // label ::= Ident ":"
1.2019 + //
1.2020 + if (match(TOK_LABEL)) {
1.2021 + // We something of the form:
1.2022 + // Label Ident
1.2023 + // or: Label "..."
1.2024 + Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.2025 + if (!name)
1.2026 + return false;
1.2027 +
1.2028 + *type = new (pool_) NameProxy(scanner_.begin(), name);
1.2029 + if (kind == DeclArg && match(TOK_ELLIPSES)) {
1.2030 + *namep = NULL;
1.2031 + } else {
1.2032 + if ((*namep = expectName()) == NULL)
1.2033 + return false;
1.2034 + }
1.2035 + return true;
1.2036 + }
1.2037 +
1.2038 + Local<String> name(zone_, expectName());
1.2039 + if (!name)
1.2040 + return false;
1.2041 +
1.2042 + if (peek(TOK_NAME) || (kind == DeclArg && peek(TOK_ELLIPSES))) {
1.2043 + // We got something of the form:
1.2044 + // Ident Ident
1.2045 + *type = new (pool_) NameProxy(scanner_.begin(), name);
1.2046 + if (peek(TOK_NAME)) {
1.2047 + if ((*namep = expectName()) == NULL)
1.2048 + return false;
1.2049 + } else {
1.2050 + *namep = NULL;
1.2051 + }
1.2052 + return true;
1.2053 + }
1.2054 +
1.2055 + // We got something of the form:
1.2056 + // Ident
1.2057 + *type = NULL;
1.2058 + *namep = name;
1.2059 + return true;
1.2060 +}
1.2061 +
1.2062 +Expression *
1.2063 +Parser::call(Expression *callee)
1.2064 +{
1.2065 + ExpressionList *arguments = new (pool_) ExpressionList();
1.2066 +
1.2067 + SourcePosition pos = scanner_.begin();
1.2068 + expect(TOK_LPAREN);
1.2069 +
1.2070 + if (!match(TOK_RPAREN)) {
1.2071 + while (true) {
1.2072 + Expression *expr = expression();
1.2073 + if (!expr)
1.2074 + return NULL;
1.2075 +
1.2076 + if (!arguments->append(expr))
1.2077 + return NULL;
1.2078 +
1.2079 + if (!match(TOK_COMMA))
1.2080 + break;
1.2081 + }
1.2082 +
1.2083 + if (!expect(TOK_RPAREN))
1.2084 + return NULL;
1.2085 + }
1.2086 +
1.2087 + return new (pool_) CallExpression(pos, callee, arguments);
1.2088 +}
1.2089 +
1.2090 +Expression *
1.2091 +Parser::index(Expression *left)
1.2092 +{
1.2093 + expect(TOK_LBRACKET);
1.2094 +
1.2095 + SourcePosition pos = scanner_.begin();
1.2096 + Expression *expr = expression();
1.2097 + if (!expr)
1.2098 + return NULL;
1.2099 +
1.2100 + if (!expect(TOK_RBRACKET))
1.2101 + return NULL;
1.2102 +
1.2103 + return new (pool_) IndexExpression(pos, left, expr);
1.2104 +}
1.2105 +
1.2106 +Expression *
1.2107 +Parser::field(Expression *left)
1.2108 +{
1.2109 + expect(TOK_DOT);
1.2110 +
1.2111 + SourcePosition pos = scanner_.begin();
1.2112 + Local<String> name(zone_, expectName());
1.2113 + if (!name)
1.2114 + return NULL;
1.2115 +
1.2116 + return new (pool_) FieldExpression(pos, left, name);
1.2117 +}
1.2118 +
1.2119 +Expression *
1.2120 +Parser::primary()
1.2121 +{
1.2122 + Expression *expr = prefix();
1.2123 + if (!expr)
1.2124 + return NULL;
1.2125 +
1.2126 + for (;;) {
1.2127 + switch (scanner_.peek()) {
1.2128 + case TOK_LPAREN:
1.2129 + if ((expr = call(expr)) == NULL)
1.2130 + return NULL;
1.2131 + break;
1.2132 +
1.2133 + case TOK_LBRACKET:
1.2134 + if ((expr = index(expr)) == NULL)
1.2135 + return NULL;
1.2136 + break;
1.2137 +
1.2138 + case TOK_DOT:
1.2139 + if ((expr = field(expr)) == NULL)
1.2140 + return NULL;
1.2141 + break;
1.2142 +
1.2143 + default:
1.2144 + return expr;
1.2145 + }
1.2146 + }
1.2147 +}
1.2148 +
1.2149 +Expression *
1.2150 +Parser::unary()
1.2151 +{
1.2152 + TokenKind token = scanner_.peek();
1.2153 +
1.2154 + SourcePosition pos = scanner_.begin();
1.2155 + switch (token) {
1.2156 + case TOK_INCREMENT:
1.2157 + case TOK_DECREMENT:
1.2158 + {
1.2159 + scanner_.scan();
1.2160 + Expression *expr = unary();
1.2161 + if (!expr)
1.2162 + return NULL;
1.2163 + return new (pool_) IncDecExpression(pos, token, expr, false);
1.2164 + }
1.2165 +
1.2166 + case TOK_MINUS:
1.2167 + case TOK_NOT:
1.2168 + case TOK_TILDE:
1.2169 + {
1.2170 + scanner_.scan();
1.2171 + Expression *expr = unary();
1.2172 + if (!expr)
1.2173 + return NULL;
1.2174 + return new (pool_) UnaryExpression(pos, token, expr);
1.2175 + }
1.2176 +
1.2177 + case TOK_SIZEOF:
1.2178 + {
1.2179 + scanner_.scan();
1.2180 + if (!expect(TOK_LPAREN))
1.2181 + return NULL;
1.2182 + Expression *expr = unary();
1.2183 + if (!expr)
1.2184 + return NULL;
1.2185 + if (!expect(TOK_RPAREN))
1.2186 + return NULL;
1.2187 + return new (pool_) UnaryExpression(pos, token, expr);
1.2188 + }
1.2189 +
1.2190 + case TOK_LABEL:
1.2191 + {
1.2192 + scanner_.scan();
1.2193 + Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.2194 + if (!tag)
1.2195 + return NULL;
1.2196 +
1.2197 + NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), tag);
1.2198 +
1.2199 + Expression *expr = unary();
1.2200 + if (!expr)
1.2201 + return NULL;
1.2202 +
1.2203 + return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, proxy);
1.2204 + }
1.2205 +
1.2206 + default:
1.2207 + break;
1.2208 + }
1.2209 +
1.2210 + Expression *expr = primary();
1.2211 +
1.2212 + token = scanner_.peek();
1.2213 + if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
1.2214 + scanner_.scan();
1.2215 + return new (pool_) IncDecExpression(pos, token, expr, true);
1.2216 + }
1.2217 +
1.2218 + return expr;
1.2219 +}
1.2220 +
1.2221 +Expression *
1.2222 +Parser::multiplication()
1.2223 +{
1.2224 + Expression *left = unary();
1.2225 + do {
1.2226 + if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
1.2227 + break;
1.2228 + SourcePosition pos = scanner_.begin();
1.2229 + TokenKind kind = scanner_.last();
1.2230 + Expression *right = unary();
1.2231 + if (!right)
1.2232 + return NULL;
1.2233 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.2234 + } while (left);
1.2235 + return left;
1.2236 +}
1.2237 +
1.2238 +Expression *
1.2239 +Parser::addition()
1.2240 +{
1.2241 + Expression *left = multiplication();
1.2242 + while (left) {
1.2243 + if (!match(TOK_PLUS) && !match(TOK_MINUS))
1.2244 + break;
1.2245 + SourcePosition pos = scanner_.begin();
1.2246 + TokenKind kind = scanner_.last();
1.2247 + Expression *right = multiplication();
1.2248 + if (!right)
1.2249 + return NULL;
1.2250 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.2251 + }
1.2252 + return left;
1.2253 +}
1.2254 +
1.2255 +Expression *
1.2256 +Parser::shift()
1.2257 +{
1.2258 + Expression *left = addition();
1.2259 + while (left) {
1.2260 + if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
1.2261 + break;
1.2262 + SourcePosition pos = scanner_.begin();
1.2263 + TokenKind kind = scanner_.last();
1.2264 + Expression *right = addition();
1.2265 + if (!right)
1.2266 + return NULL;
1.2267 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.2268 + }
1.2269 + return left;
1.2270 +}
1.2271 +
1.2272 +Expression *
1.2273 +Parser::bitand_()
1.2274 +{
1.2275 + Expression *left = shift();
1.2276 + while (left) {
1.2277 + if (!match(TOK_BITAND))
1.2278 + break;
1.2279 + SourcePosition pos = scanner_.begin();
1.2280 + Expression *right = shift();
1.2281 + if (!right)
1.2282 + return NULL;
1.2283 + left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
1.2284 + }
1.2285 + return left;
1.2286 +}
1.2287 +
1.2288 +Expression *
1.2289 +Parser::bitxor()
1.2290 +{
1.2291 + Expression *left = bitand_();
1.2292 + while (left) {
1.2293 + if (!match(TOK_BITXOR))
1.2294 + break;
1.2295 + SourcePosition pos = scanner_.begin();
1.2296 + Expression *right = shift();
1.2297 + if (!right)
1.2298 + return NULL;
1.2299 + left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
1.2300 + }
1.2301 + return left;
1.2302 +}
1.2303 +
1.2304 +Expression *
1.2305 +Parser::bitor_()
1.2306 +{
1.2307 + Expression *left = bitxor();
1.2308 + while (left) {
1.2309 + if (!match(TOK_BITOR))
1.2310 + break;
1.2311 + SourcePosition pos = scanner_.begin();
1.2312 + Expression *right = bitxor();
1.2313 + if (!right)
1.2314 + return NULL;
1.2315 + left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
1.2316 + }
1.2317 + return left;
1.2318 +}
1.2319 +
1.2320 +Expression *
1.2321 +Parser::relational()
1.2322 +{
1.2323 + Expression *left = bitor_();
1.2324 + while (left) {
1.2325 + TokenKind kind = scanner_.peek();
1.2326 + if (kind < TOK_LT || kind > TOK_GE)
1.2327 + break;
1.2328 + scanner_.scan();
1.2329 + SourcePosition pos = scanner_.begin();
1.2330 + Expression *right = shift();
1.2331 + if (!right)
1.2332 + return NULL;
1.2333 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.2334 + }
1.2335 + return left;
1.2336 +}
1.2337 +
1.2338 +Expression *
1.2339 +Parser::equals()
1.2340 +{
1.2341 + Expression *left = relational();
1.2342 + while (left) {
1.2343 + if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
1.2344 + break;
1.2345 + TokenKind kind = scanner_.last();
1.2346 + SourcePosition pos = scanner_.begin();
1.2347 + Expression *right = relational();
1.2348 + if (!right)
1.2349 + return NULL;
1.2350 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.2351 + }
1.2352 + return left;
1.2353 +}
1.2354 +
1.2355 +Expression *
1.2356 +Parser::and_()
1.2357 +{
1.2358 + Expression *left = equals();
1.2359 + while (left) {
1.2360 + if (!match(TOK_AND))
1.2361 + break;
1.2362 + SourcePosition pos = scanner_.begin();
1.2363 + Expression *right = equals();
1.2364 + if (!right)
1.2365 + return NULL;
1.2366 + left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
1.2367 + }
1.2368 + return left;
1.2369 +}
1.2370 +
1.2371 +Expression *
1.2372 +Parser::or_()
1.2373 +{
1.2374 + Expression *left = and_();
1.2375 + while (left) {
1.2376 + if (!match(TOK_OR))
1.2377 + break;
1.2378 + SourcePosition pos = scanner_.begin();
1.2379 + Expression *right = and_();
1.2380 + if (!right)
1.2381 + return NULL;
1.2382 + left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
1.2383 + }
1.2384 + return left;
1.2385 +}
1.2386 +
1.2387 +Expression *
1.2388 +Parser::ternary()
1.2389 +{
1.2390 + Expression *cond = or_();
1.2391 + if (!cond)
1.2392 + return NULL;
1.2393 +
1.2394 + if (!match(TOK_QMARK))
1.2395 + return cond;
1.2396 +
1.2397 + Expression *left;
1.2398 + SourcePosition pos = scanner_.begin();
1.2399 + AutoAllowTags<false> disableTags(scanner_);
1.2400 + {
1.2401 + if ((left = expression()) == NULL)
1.2402 + return NULL;
1.2403 + }
1.2404 +
1.2405 + if (!expect(TOK_COLON))
1.2406 + return NULL;
1.2407 +
1.2408 + Expression *right = expression();
1.2409 + if (!right)
1.2410 + return NULL;
1.2411 +
1.2412 + return new (pool_) TernaryExpression(pos, cond, left, right);
1.2413 +}
1.2414 +
1.2415 +Expression *
1.2416 +Parser::assignment()
1.2417 +{
1.2418 + Expression *left = ternary();
1.2419 + while (left) {
1.2420 + TokenKind token = scanner_.peek();
1.2421 + if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
1.2422 + break;
1.2423 + scanner_.scan();
1.2424 + SourcePosition pos = scanner_.begin();
1.2425 + Expression *expr = ternary();
1.2426 + if (!expr)
1.2427 + return NULL;
1.2428 +
1.2429 + left = new (pool_) Assignment(pos, token, left, expr);
1.2430 + }
1.2431 + return left;
1.2432 +}
1.2433 +
1.2434 +Expression *
1.2435 +Parser::expression()
1.2436 +{
1.2437 + return assignment();
1.2438 +}
1.2439 +
1.2440 +Statement *
1.2441 +Parser::while_()
1.2442 +{
1.2443 + // while ::= "while" "(" expr ")" statement
1.2444 + SourcePosition pos = scanner_.begin();
1.2445 + scanner_.scan();
1.2446 +
1.2447 + if (!expect(TOK_LPAREN))
1.2448 + return NULL;
1.2449 +
1.2450 + Expression *condition = expression();
1.2451 + if (!condition)
1.2452 + return NULL;
1.2453 +
1.2454 + if (!expect(TOK_RPAREN))
1.2455 + return NULL;
1.2456 +
1.2457 + Statement *body;
1.2458 + if (scanner_.peek() == TOK_LBRACE)
1.2459 + body = block();
1.2460 + else
1.2461 + body = localStatement();
1.2462 + if (!body)
1.2463 + return NULL;
1.2464 +
1.2465 + return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
1.2466 +}
1.2467 +
1.2468 +Statement *
1.2469 +Parser::do_()
1.2470 +{
1.2471 + // do ::= "do" block "while" "(" expr ")"
1.2472 + SourcePosition pos = scanner_.begin();
1.2473 + scanner_.scan();
1.2474 +
1.2475 + Statement *body = block();
1.2476 + if (!body)
1.2477 + return NULL;
1.2478 +
1.2479 + if (!expect(TOK_WHILE))
1.2480 + return NULL;
1.2481 +
1.2482 + if (!expect(TOK_LPAREN))
1.2483 + return NULL;
1.2484 + Expression *condition = expression();
1.2485 + if (!condition)
1.2486 + return NULL;
1.2487 + if (!expect(TOK_RPAREN))
1.2488 + return NULL;
1.2489 +
1.2490 + return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
1.2491 +}
1.2492 +
1.2493 +Statement *
1.2494 +Parser::switch_()
1.2495 +{
1.2496 + // switch ::= "switch" "(" expr ")" "{" case* defaultcase? "}"
1.2497 + // case ::= "case" casevals ":" statement
1.2498 + // defaultcase ::= "default" ":" statement
1.2499 + //
1.2500 + expect(TOK_SWITCH);
1.2501 +
1.2502 + SourcePosition pos = scanner_.begin();
1.2503 +
1.2504 + if (!expect(TOK_LPAREN))
1.2505 + return NULL;
1.2506 + Expression *expr = expression();
1.2507 + if (!expr)
1.2508 + return NULL;
1.2509 + if (!expect(TOK_RPAREN))
1.2510 + return NULL;
1.2511 +
1.2512 + if (!expect(TOK_LBRACE))
1.2513 + return NULL;
1.2514 +
1.2515 + SourcePosition defaultPos;
1.2516 + PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
1.2517 +
1.2518 + Statement *defaultCase = NULL;
1.2519 +
1.2520 + while (!peek(TOK_RBRACE)) {
1.2521 + Expression *expr = NULL;
1.2522 + ExpressionList *others = NULL;
1.2523 + if (match(TOK_DEFAULT)) {
1.2524 + if (defaultCase) {
1.2525 + cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
1.2526 + return NULL;
1.2527 + }
1.2528 +
1.2529 + defaultPos = scanner_.begin();
1.2530 + } else {
1.2531 + if (defaultCase) {
1.2532 + cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
1.2533 + return NULL;
1.2534 + }
1.2535 +
1.2536 + if (!expect(TOK_CASE))
1.2537 + return NULL;
1.2538 +
1.2539 + // A limitation in the grammar is that |case <NAME>:| will be
1.2540 + // detected as a label.
1.2541 + AutoAllowTags<false> disableTags(scanner_);
1.2542 +
1.2543 + if ((expr = expression()) == NULL)
1.2544 + return NULL;
1.2545 +
1.2546 + if (peek(TOK_COMMA)) {
1.2547 + others = new (pool_) ExpressionList();
1.2548 + while (match(TOK_COMMA)) {
1.2549 + Expression *other = expression();
1.2550 + if (!other)
1.2551 + return NULL;
1.2552 + if (!others->append(other))
1.2553 + return NULL;
1.2554 + }
1.2555 + }
1.2556 + }
1.2557 +
1.2558 + if (!expect(TOK_COLON))
1.2559 + return NULL;
1.2560 +
1.2561 + Statement *statement = localStatement();
1.2562 + if (!statement)
1.2563 + return NULL;
1.2564 +
1.2565 + if (!peek(TOK_CASE) &&
1.2566 + !peek(TOK_DEFAULT) &&
1.2567 + !peek(TOK_RBRACE))
1.2568 + {
1.2569 + cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
1.2570 + return NULL;
1.2571 + }
1.2572 +
1.2573 + if (expr) {
1.2574 + Case *caze = new (pool_) Case(expr, others, statement);
1.2575 + if (!cases->append(caze))
1.2576 + return NULL;
1.2577 + } else {
1.2578 + defaultCase = statement;
1.2579 + }
1.2580 + }
1.2581 +
1.2582 + if (!expect(TOK_RBRACE))
1.2583 + return NULL;
1.2584 +
1.2585 + return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
1.2586 +}
1.2587 +
1.2588 +Statement *
1.2589 +Parser::forStatement()
1.2590 +{
1.2591 + // for ::= "for" "(" forinit? ";" forcond? ";" forstep ")" statement
1.2592 + // forint ::= "new" vardecl |
1.2593 + // exprstmt
1.2594 + // forcond ::= expr
1.2595 + // forstep ::= exprstmt
1.2596 + //
1.2597 + SourcePosition pos = scanner_.begin();
1.2598 + scanner_.scan();
1.2599 + if (!expect(TOK_LPAREN))
1.2600 + return NULL;
1.2601 +
1.2602 + Statement *decl = NULL;
1.2603 + if (!match(TOK_SEMICOLON)) {
1.2604 + if (match(TOK_NEW)) {
1.2605 + if ((decl = vars(TypeQual_None)) == NULL)
1.2606 + return NULL;
1.2607 + } else {
1.2608 + if ((decl = expressionStatement()) == NULL)
1.2609 + return NULL;
1.2610 + }
1.2611 + if (!expect(TOK_SEMICOLON))
1.2612 + return NULL;
1.2613 + }
1.2614 +
1.2615 + Expression *condition = NULL;
1.2616 + if (!match(TOK_SEMICOLON)) {
1.2617 + if ((condition = expression()) == NULL)
1.2618 + return NULL;
1.2619 + if (!expect(TOK_SEMICOLON))
1.2620 + return NULL;
1.2621 + }
1.2622 +
1.2623 + Statement *update = NULL;
1.2624 + if (!match(TOK_RPAREN)) {
1.2625 + if ((update = expressionStatement()) == NULL)
1.2626 + return NULL;
1.2627 + if (!expect(TOK_RPAREN))
1.2628 + return NULL;
1.2629 + }
1.2630 +
1.2631 + Statement *body;
1.2632 + if (scanner_.peek() == TOK_LBRACE)
1.2633 + body = block();
1.2634 + else
1.2635 + body = localStatement();
1.2636 + if (!body)
1.2637 + return NULL;
1.2638 +
1.2639 + return new (pool_) ForStatement(pos, decl, condition, update, body);
1.2640 +}
1.2641 +
1.2642 +ExpressionList *
1.2643 +Parser::dimensions()
1.2644 +{
1.2645 + // dimensions ::= ("[" expr? "]")*
1.2646 +
1.2647 + ExpressionList *postDimensions = new (pool_) ExpressionList();
1.2648 + while (match(TOK_LBRACKET)) {
1.2649 + Expression *dim = NULL;
1.2650 + if (!match(TOK_RBRACKET)) {
1.2651 + if ((dim = expression()) == NULL)
1.2652 + return NULL;
1.2653 + if (!expect(TOK_RBRACKET))
1.2654 + return NULL;
1.2655 + }
1.2656 +
1.2657 + if (!postDimensions->append(dim))
1.2658 + return NULL;
1.2659 + }
1.2660 + return postDimensions;
1.2661 +}
1.2662 +
1.2663 +VariableDeclaration *
1.2664 +Parser::var(TypeQualifiers qual)
1.2665 +{
1.2666 + // vardecl ::= decl ("=" expr)?
1.2667 +
1.2668 + Expression *type;
1.2669 + Local<String> name(zone_);
1.2670 +
1.2671 + if (!typeAndName(&type, name.ref()))
1.2672 + return NULL;
1.2673 +
1.2674 + ExpressionList *dims = NULL;
1.2675 + if (peek(TOK_LBRACKET)) {
1.2676 + if ((dims = dimensions()) == NULL)
1.2677 + return NULL;;
1.2678 + }
1.2679 +
1.2680 + SourcePosition pos = scanner_.begin();
1.2681 +
1.2682 + Expression *expr = NULL;
1.2683 + if (match(TOK_ASSIGN)) {
1.2684 + switch (scanner_.peek()) {
1.2685 + // Note: we don't support [] literals yet.
1.2686 + case TOK_LBRACE:
1.2687 + scanner_.scan();
1.2688 + if ((expr = fixedArrayLiteral()) == NULL)
1.2689 + return NULL;
1.2690 + break;
1.2691 +
1.2692 + default:
1.2693 + if ((expr = expression()) == NULL)
1.2694 + return NULL;
1.2695 + break;
1.2696 + }
1.2697 + }
1.2698 +
1.2699 + return new (pool_) VariableDeclaration(pos, qual, name, type, dims, expr);
1.2700 +}
1.2701 +
1.2702 +Statement *
1.2703 +Parser::vars(TypeQualifiers qual)
1.2704 +{
1.2705 + // localvars ::= ("new" | "const" | "decl") vardecl ("," vardecl)*
1.2706 + // globalvars ::= ("public" | "const" | "new" | "public" "const") vardecl
1.2707 + VariableDeclaration *decl = var(qual);
1.2708 + if (!decl)
1.2709 + return NULL;
1.2710 +
1.2711 + if (!peek(TOK_COMMA))
1.2712 + return decl;
1.2713 +
1.2714 + StatementList *statements = new (pool_) StatementList();
1.2715 + if (!statements->append(decl))
1.2716 + return NULL;
1.2717 +
1.2718 + while (match(TOK_COMMA)) {
1.2719 + Statement *decl = var(qual);
1.2720 + if (!decl)
1.2721 + return NULL;
1.2722 + if (!statements->append(decl))
1.2723 + return NULL;
1.2724 + }
1.2725 +
1.2726 + // Create a fake-o block with no scope to create a statement list.
1.2727 + return new (pool_) BlockStatement(decl->pos(), statements, TOK_NEW);
1.2728 +}
1.2729 +
1.2730 +Statement *
1.2731 +Parser::returnStatement()
1.2732 +{
1.2733 + // return ::= "return" term |
1.2734 + // "return" "expr"
1.2735 +
1.2736 + SourcePosition pos = scanner_.begin();
1.2737 + if (!expect(TOK_RETURN))
1.2738 + return NULL;
1.2739 +
1.2740 + Expression *expr = NULL;
1.2741 + if (scanner_.peek() != TOK_SEMICOLON) {
1.2742 + if ((expr = expression()) == NULL)
1.2743 + return NULL;
1.2744 +
1.2745 + // We only care about non-void returns when determining whether a
1.2746 + // tagless function is non-void.
1.2747 + encounteredReturn_ = true;
1.2748 + }
1.2749 +
1.2750 + return new (pool_) ReturnStatement(pos, expr);
1.2751 +}
1.2752 +
1.2753 +Statement *
1.2754 +Parser::expressionStatement()
1.2755 +{
1.2756 + // exprstmt ::= expr
1.2757 + Expression *left = assignment();
1.2758 + if (!left)
1.2759 + return NULL;
1.2760 +
1.2761 + return new (pool_) ExpressionStatement(left);
1.2762 +}
1.2763 +
1.2764 +Statement *
1.2765 +Parser::block()
1.2766 +{
1.2767 + // block ::= "{" statement* "}"
1.2768 +
1.2769 + if (!expect(TOK_LBRACE))
1.2770 + return NULL;
1.2771 +
1.2772 + SourcePosition pos = scanner_.begin();
1.2773 +
1.2774 + StatementList *statements = new (pool_) StatementList();
1.2775 + while (!match(TOK_RBRACE)) {
1.2776 + Statement *statement = localStatement();
1.2777 + if (statement == NULL)
1.2778 + return NULL;
1.2779 + if (!statements->append(statement))
1.2780 + return NULL;
1.2781 + }
1.2782 +
1.2783 + BlockStatement *block = new (pool_) BlockStatement(pos, statements, TOK_LBRACE);
1.2784 + return block;
1.2785 +}
1.2786 +
1.2787 +Statement *
1.2788 +Parser::if_()
1.2789 +{
1.2790 + // if ::= "if" "(" expr ")" statement elseif* else?
1.2791 + // elseif ::= "elseif" "(" expr ")" statement
1.2792 + // else ::= "else" statement
1.2793 + expect(TOK_IF);
1.2794 +
1.2795 + SourcePosition pos = scanner_.begin();
1.2796 + if (!expect(TOK_LPAREN))
1.2797 + return NULL;
1.2798 +
1.2799 + Expression *cond = expression();
1.2800 + if (!cond)
1.2801 + return NULL;
1.2802 +
1.2803 + if (!expect(TOK_RPAREN))
1.2804 + return NULL;
1.2805 +
1.2806 + Statement *ifTrue = localStatement();
1.2807 + if (!ifTrue)
1.2808 + return NULL;
1.2809 +
1.2810 + IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1.2811 +
1.2812 + IfStatement *last = outer;
1.2813 + while (match(TOK_ELSE)) {
1.2814 + if (!match(TOK_IF)) {
1.2815 + Statement *ifFalse = localStatement();
1.2816 + if (!ifFalse)
1.2817 + return NULL;
1.2818 +
1.2819 + last->setIfFalse(ifFalse);
1.2820 + break;
1.2821 + }
1.2822 +
1.2823 + SourcePosition pos = scanner_.begin();
1.2824 + if (!expect(TOK_LPAREN))
1.2825 + return NULL;
1.2826 +
1.2827 + Expression *otherCond = expression();
1.2828 + if (!otherCond)
1.2829 + return NULL;
1.2830 +
1.2831 + if (!expect(TOK_RPAREN))
1.2832 + return NULL;
1.2833 +
1.2834 + Statement *otherIfTrue = localStatement();
1.2835 + if (!otherIfTrue)
1.2836 + return NULL;
1.2837 +
1.2838 + IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1.2839 + last->setIfFalse(inner);
1.2840 + last = inner;
1.2841 + }
1.2842 +
1.2843 + return outer;
1.2844 +}
1.2845 +
1.2846 +Statement *
1.2847 +Parser::localStatement()
1.2848 +{
1.2849 + // statement ::= stmt term
1.2850 + // stmt ::= do | for | if | while | struct | enum |
1.2851 + // localvars | return | switch | break | continue
1.2852 +
1.2853 + Statement *statement = NULL;
1.2854 +
1.2855 + // Statements which must be followed by a semicolon will break out of the
1.2856 + // switch. If they may end in BlockStatements, they'll immediately return.
1.2857 +
1.2858 + TokenKind kind = scanner_.peek();
1.2859 + switch (kind) {
1.2860 + case TOK_CONST:
1.2861 + case TOK_NEW:
1.2862 + {
1.2863 + TypeQualifiers quals = (kind == TOK_CONST)
1.2864 + ? TypeQual_Const
1.2865 + : TypeQual_None;
1.2866 + scanner_.scan();
1.2867 + if ((statement = vars(quals)) == NULL)
1.2868 + return NULL;
1.2869 + break;
1.2870 + }
1.2871 +
1.2872 + case TOK_FOR:
1.2873 + return forStatement();
1.2874 +
1.2875 + case TOK_WHILE:
1.2876 + return while_();
1.2877 +
1.2878 + case TOK_BREAK:
1.2879 + scanner_.scan();
1.2880 + statement = new (pool_) BreakStatement(scanner_.begin());
1.2881 + break;
1.2882 +
1.2883 + case TOK_CONTINUE:
1.2884 + scanner_.scan();
1.2885 + statement = new (pool_) ContinueStatement(scanner_.begin());
1.2886 + break;
1.2887 +
1.2888 + case TOK_DO:
1.2889 + if ((statement = do_()) == NULL)
1.2890 + return NULL;
1.2891 + break;
1.2892 +
1.2893 + case TOK_RETURN:
1.2894 + if ((statement = returnStatement()) == NULL)
1.2895 + return NULL;
1.2896 + break;
1.2897 +
1.2898 + case TOK_ENUM:
1.2899 + if ((statement = enum_(TOK_NONE)) == NULL)
1.2900 + return NULL;
1.2901 + break;
1.2902 +
1.2903 + case TOK_STRUCT:
1.2904 + if ((statement = struct_()) == NULL)
1.2905 + return NULL;
1.2906 + break;
1.2907 +
1.2908 + case TOK_SWITCH:
1.2909 + return switch_();
1.2910 +
1.2911 + case TOK_IF:
1.2912 + return if_();
1.2913 +
1.2914 + case TOK_LBRACE:
1.2915 + return block();
1.2916 +
1.2917 + default:
1.2918 + break;
1.2919 + }
1.2920 +
1.2921 + if (!statement) {
1.2922 + if ((statement = expressionStatement()) == NULL)
1.2923 + return NULL;
1.2924 + }
1.2925 +
1.2926 + if (!expect(TOK_SEMICOLON))
1.2927 + return NULL;
1.2928 +
1.2929 + return statement;
1.2930 +}
1.2931 +
1.2932 +Statement *
1.2933 +Parser::struct_()
1.2934 +{
1.2935 + // struct ::= "struct" name { struct_fields }
1.2936 + // struct_fields ::= struct_field |
1.2937 + // struct_field struct_fields
1.2938 + // struct_field ::= label? name term
1.2939 + expect(TOK_STRUCT);
1.2940 +
1.2941 + Local<String> name(zone_, expectName());
1.2942 + if (!name)
1.2943 + return NULL;
1.2944 +
1.2945 + SourcePosition pos = scanner_.begin();
1.2946 +
1.2947 + if (!expect(TOK_LBRACE))
1.2948 + return NULL;
1.2949 +
1.2950 + FieldList *fields = new (pool_) FieldList();
1.2951 +
1.2952 + while (!peek(TOK_RBRACE)) {
1.2953 + Expression *type;
1.2954 + Local<String> fieldName(zone_);
1.2955 +
1.2956 + if (!fullTypeAndName(&type, fieldName.ref(), DeclField))
1.2957 + return NULL;
1.2958 +
1.2959 + SourcePosition pos = scanner_.begin();
1.2960 +
1.2961 + if (!matchSemicolon())
1.2962 + return NULL;
1.2963 +
1.2964 + StructureStatement::Field *field =
1.2965 + new (pool_) StructureStatement::Field(pos, type, fieldName);
1.2966 + if (!field || !fields->append(field))
1.2967 + return NULL;
1.2968 + }
1.2969 +
1.2970 + if (!expect(TOK_RBRACE))
1.2971 + return NULL;
1.2972 +
1.2973 + if (fields->empty()) {
1.2974 + cc_.reportError(pos, Message_StructCantBeEmpty);
1.2975 + return NULL;
1.2976 + }
1.2977 +
1.2978 + return new (pool_) StructureStatement(pos, name, fields);
1.2979 +}
1.2980 +
1.2981 +Statement *
1.2982 +Parser::enum_(TokenKind kind)
1.2983 +{
1.2984 + // enum ::= "enum" name? { enum_members? }
1.2985 + // enum_members ::= enum_member ","? |
1.2986 + // enum_member "," enum_members
1.2987 + // enum_member ::= ident ("=" constexpr)?
1.2988 + expect(TOK_ENUM);
1.2989 +
1.2990 + SourcePosition pos = scanner_.begin();
1.2991 +
1.2992 + Local<String> name(zone_);
1.2993 + if (matchName(name.ref()) && !name)
1.2994 + return NULL;
1.2995 +
1.2996 + EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1.2997 +
1.2998 + if (!expect(TOK_LBRACE))
1.2999 + return NULL;
1.3000 +
1.3001 + do {
1.3002 + if (scanner_.peek() == TOK_RBRACE)
1.3003 + break;
1.3004 +
1.3005 + SourcePosition pos = scanner_.begin();
1.3006 + Local<String> name(zone_, expectName());
1.3007 + if (!name)
1.3008 + return NULL;
1.3009 +
1.3010 + Expression *expr = NULL;
1.3011 + if (match(TOK_ASSIGN)) {
1.3012 + if ((expr = expression()) == NULL)
1.3013 + return NULL;
1.3014 + }
1.3015 +
1.3016 + if (!entries->append(EnumStatement::Entry(name, expr, pos)))
1.3017 + return NULL;
1.3018 + } while (match(TOK_COMMA));
1.3019 + if (!expect(TOK_RBRACE))
1.3020 + return NULL;
1.3021 +
1.3022 + return new (pool_) EnumStatement(pos, kind, name, entries);
1.3023 +}
1.3024 +
1.3025 +template <class T>
1.3026 +static inline ScopedRoot<T> *
1.3027 +NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
1.3028 +{
1.3029 + return new (pool) ScopedRoot<T>(obj);
1.3030 +}
1.3031 +
1.3032 +ImportStatement *
1.3033 +Parser::import(TokenKind kind)
1.3034 +{
1.3035 + SourcePosition pos = scanner_.begin();
1.3036 +
1.3037 + // import ::= "from" import_path "import" import_names
1.3038 + // | "import" import_path
1.3039 + // | "import" import_path ".*"
1.3040 + // import_path ::= name
1.3041 + // | name "." import_path
1.3042 + // import_names ::= "*"
1.3043 + // | import_name_list
1.3044 + // import_name_list ::= name
1.3045 + // | name "," import_name_list
1.3046 +
1.3047 + Local<String> name(zone_, expectName());
1.3048 + if (!name)
1.3049 + return NULL;
1.3050 +
1.3051 + PathComponent *root = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
1.3052 + PathComponent *current = root;
1.3053 +
1.3054 + // NULL namelist means that we do not import any names. An empty namelist
1.3055 + // means we import all names.
1.3056 + NameList *names = NULL;
1.3057 +
1.3058 + while (match(TOK_DOT)) {
1.3059 + if (kind == TOK_IMPORT && match(TOK_STAR)) {
1.3060 + names = new (pool_) NameList();
1.3061 + break;
1.3062 + }
1.3063 +
1.3064 + if ((name = expectName()) == NULL)
1.3065 + return NULL;
1.3066 +
1.3067 + current->next = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
1.3068 + current = current->next;
1.3069 + }
1.3070 +
1.3071 + if (kind == TOK_FROM) {
1.3072 + if (!expect(TOK_IMPORT))
1.3073 + return NULL;
1.3074 +
1.3075 + names = new (pool_) NameList();
1.3076 +
1.3077 + if (!match(TOK_STAR)) {
1.3078 + if (!matchName(name.address())) {
1.3079 + cc_.reportError(scanner_.begin(), Message_BadImportFrom);
1.3080 + return NULL;
1.3081 + }
1.3082 +
1.3083 + if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
1.3084 + return NULL;
1.3085 +
1.3086 + while (match(TOK_COMMA)) {
1.3087 + if ((name = expectName()) == NULL)
1.3088 + return NULL;
1.3089 + if (!names->append(NewScopedRoot<String>(pool_, name)))
1.3090 + return NULL;
1.3091 + }
1.3092 + }
1.3093 + }
1.3094 +
1.3095 + return new (pool_) ImportStatement(pos, root, names);
1.3096 +}
1.3097 +
1.3098 +Statement *
1.3099 +Parser::function(TokenKind token)
1.3100 +{
1.3101 + Expression *returnType;
1.3102 + Local<String> name(zone_);
1.3103 +
1.3104 + if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
1.3105 + return NULL;
1.3106 +
1.3107 + SourcePosition pos = scanner_.begin();
1.3108 + ParameterList *parameters = new (pool_) ParameterList();
1.3109 +
1.3110 + if (!expect(TOK_LPAREN))
1.3111 + return NULL;
1.3112 +
1.3113 + bool variadic = false;
1.3114 +
1.3115 + if (!match(TOK_RPAREN)) {
1.3116 + while (true) {
1.3117 + TypeQualifiers quals = TypeQual_None;
1.3118 + if (match(TOK_CONST))
1.3119 + quals = TypeQualifiers(quals | TypeQual_Const);
1.3120 +
1.3121 + bool ref = match(TOK_AMPERSAND);
1.3122 +
1.3123 + SourcePosition begin = scanner_.begin();
1.3124 + Expression *type;
1.3125 + Local<String> name(zone_);
1.3126 + if (!fullTypeAndName(&type, name.ref(), DeclArg))
1.3127 + return NULL;
1.3128 +
1.3129 + if (!name) {
1.3130 + if ((quals & TypeQual_Const) || ref) {
1.3131 + cc_.reportError(begin, Message_InvalidVarArgs);
1.3132 + return NULL;
1.3133 + }
1.3134 +
1.3135 + if (token != TOK_NATIVE) {
1.3136 + cc_.reportError(begin, Message_VarArgsOutsideNative);
1.3137 + return NULL;
1.3138 + }
1.3139 +
1.3140 + variadic = true;
1.3141 + break;
1.3142 + }
1.3143 +
1.3144 + ExpressionList *dims = NULL;
1.3145 + if (peek(TOK_LBRACKET)) {
1.3146 + if ((dims = dimensions()) == NULL)
1.3147 + return NULL;
1.3148 + }
1.3149 +
1.3150 + Expression *expr = NULL;
1.3151 + if (match(TOK_ASSIGN)) {
1.3152 + if ((expr = expression()) == NULL)
1.3153 + return NULL;
1.3154 + }
1.3155 +
1.3156 + Parameter *parameter = new (pool_) Parameter(name, type, ref, quals, dims, expr, begin);
1.3157 + if (!parameters->append(parameter))
1.3158 + return NULL;
1.3159 +
1.3160 + if (!match(TOK_COMMA))
1.3161 + break;
1.3162 + }
1.3163 + if (!expect(TOK_RPAREN))
1.3164 + return NULL;
1.3165 + }
1.3166 +
1.3167 + encounteredReturn_ = false;
1.3168 +
1.3169 + Statement *body = NULL;
1.3170 + if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1.3171 + body = block();
1.3172 + if (!body)
1.3173 + return NULL;
1.3174 + }
1.3175 +
1.3176 + FunctionSignature signature(returnType, parameters, variadic);
1.3177 + if (token == TOK_TYPEDEF)
1.3178 + return new (pool_) FunctionTypeStatement(pos, name, signature);
1.3179 +
1.3180 + return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
1.3181 +}
1.3182 +
1.3183 +static inline bool
1.3184 +DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1.3185 +{
1.3186 + Local<String> tag(zone, zone->makeSymbol(name));
1.3187 + if (!tag)
1.3188 + return false;
1.3189 +
1.3190 + assert(false);
1.3191 + return false; //return !!scope->declareType(tag, type);
1.3192 +}
1.3193 +
1.3194 +static inline bool
1.3195 +DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1.3196 +{
1.3197 + Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1.3198 + assert(primitive);
1.3199 + return DeclareIntrinsicType(zone, scope, name, primitive);
1.3200 +}
1.3201 +
1.3202 +ParseTree *
1.3203 +Parser::parse()
1.3204 +{
1.3205 + StatementList *statements = new (pool_) StatementList();
1.3206 +
1.3207 + for (;;) {
1.3208 + Statement *statement = NULL;
1.3209 +
1.3210 + TokenKind kind = scanner_.peek();
1.3211 + switch (kind) {
1.3212 + case TOK_ERROR:
1.3213 + return NULL;
1.3214 +
1.3215 + case TOK_EOF:
1.3216 + break;
1.3217 +
1.3218 + case TOK_NAME:
1.3219 + if ((statement = function(TOK_NAME)) == NULL)
1.3220 + return NULL;
1.3221 + break;
1.3222 +
1.3223 + case TOK_FROM:
1.3224 + case TOK_IMPORT:
1.3225 + {
1.3226 + scanner_.scan();
1.3227 + if (statements->length())
1.3228 + cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
1.3229 + ImportStatement *stmt = import(kind);
1.3230 + if (!stmt)
1.3231 + return NULL;
1.3232 + if (!imports_->append(stmt))
1.3233 + return NULL;
1.3234 + if (!matchSemicolon())
1.3235 + return NULL;
1.3236 + continue;
1.3237 + }
1.3238 +
1.3239 + case TOK_FORWARD:
1.3240 + case TOK_PUBLIC:
1.3241 + case TOK_NATIVE:
1.3242 + case TOK_STOCK:
1.3243 + case TOK_LABEL:
1.3244 + case TOK_TYPEDEF:
1.3245 + {
1.3246 + if (kind != TOK_LABEL)
1.3247 + scanner_.scan();
1.3248 + if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1.3249 + if ((statement = var(TypeQual_Const)) == NULL)
1.3250 + return NULL;
1.3251 + if (!matchSemicolon())
1.3252 + return NULL;
1.3253 + } else if (kind == TOK_PUBLIC && peek(TOK_ENUM)) {
1.3254 + if ((statement = enum_(kind)) == NULL)
1.3255 + return NULL;
1.3256 + if (!matchSemicolon())
1.3257 + return NULL;
1.3258 + } else {
1.3259 + if ((statement = function(kind)) == NULL)
1.3260 + return NULL;
1.3261 + if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1.3262 + return NULL;
1.3263 + }
1.3264 + break;
1.3265 + }
1.3266 +
1.3267 + case TOK_CONST:
1.3268 + case TOK_NEW:
1.3269 + {
1.3270 + TypeQualifiers quals = (kind == TOK_CONST) ? TypeQual_Const : TypeQual_None;
1.3271 + // Note: at global scope, we don't accept comma-delimited
1.3272 + // declarations yet, to see if we can get away with forcing
1.3273 + // a nicer top-level style.
1.3274 + scanner_.scan();
1.3275 + if ((statement = var(quals)) == NULL)
1.3276 + return NULL;
1.3277 + if (!matchSemicolon())
1.3278 + return NULL;
1.3279 + break;
1.3280 + }
1.3281 +
1.3282 + case TOK_ENUM:
1.3283 + if ((statement = enum_(TOK_NONE)) == NULL)
1.3284 + return NULL;
1.3285 + if (!matchSemicolon())
1.3286 + return NULL;
1.3287 + break;
1.3288 +
1.3289 + case TOK_STRUCT:
1.3290 + if ((statement = struct_()) == NULL)
1.3291 + return NULL;
1.3292 + if (!matchSemicolon())
1.3293 + return NULL;
1.3294 + break;
1.3295 +
1.3296 + default:
1.3297 + cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1.3298 + return NULL;
1.3299 + }
1.3300 +
1.3301 + if (!statement)
1.3302 + break;
1.3303 +
1.3304 + if (!statements->append(statement))
1.3305 + return NULL;
1.3306 + }
1.3307 +
1.3308 + return new (pool_) ParseTree(statements, unbound_, imports_);
1.3309 +}
1.3310 +
1.3311 +class AstPrinter : public AstVisitor
1.3312 +{
1.3313 + FILE *fp_;
1.3314 + size_t level_;
1.3315 +
1.3316 + private:
1.3317 + void prefix() {
1.3318 + for (size_t i = 0; i < level_; i++)
1.3319 + fprintf(fp_, " ");
1.3320 + }
1.3321 + void indent() {
1.3322 + level_++;
1.3323 + }
1.3324 + void unindent() {
1.3325 + level_--;
1.3326 + }
1.3327 +
1.3328 + public:
1.3329 + AstPrinter(FILE *fp)
1.3330 + : fp_(fp),
1.3331 + level_(0)
1.3332 + {
1.3333 + }
1.3334 +
1.3335 + void dump(const FunctionSignature &sig) {
1.3336 + prefix();
1.3337 + fprintf(fp_, "()\n");
1.3338 + }
1.3339 + void visitNameProxy(NameProxy *name) {
1.3340 + prefix();
1.3341 + fprintf(fp_, "[ NameProxy (%s)\n", name->name()->chars());
1.3342 + }
1.3343 + void visitCallExpression(CallExpression *node) {
1.3344 + prefix();
1.3345 + fprintf(fp_, "[ CallExpression\n");
1.3346 + indent();
1.3347 + node->callee()->accept(this);
1.3348 + for (size_t i = 0; i < node->arguments()->length(); i++)
1.3349 + node->arguments()->at(i)->accept(this);
1.3350 + unindent();
1.3351 + }
1.3352 + void visitFunctionTypeStatement(FunctionTypeStatement *node) {
1.3353 + prefix();
1.3354 + fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->name()->chars());
1.3355 + indent();
1.3356 + dump(node->signature());
1.3357 + unindent();
1.3358 + }
1.3359 + void visitFunctionStatement(FunctionStatement *node) {
1.3360 + prefix();
1.3361 + fprintf(fp_, "[ FunctionStatement (%s)\n", node->name()->chars());
1.3362 + indent();
1.3363 + dump(node->signature());
1.3364 + if (node->body())
1.3365 + node->body()->accept(this);
1.3366 + unindent();
1.3367 + }
1.3368 + void visitExpressionStatement(ExpressionStatement *node) {
1.3369 + prefix();
1.3370 + fprintf(fp_, "[ ExpressionStatement\n");
1.3371 + indent();
1.3372 + node->expression()->accept(this);
1.3373 + unindent();
1.3374 + }
1.3375 + void visitAssignment(Assignment *node) {
1.3376 + prefix();
1.3377 + fprintf(fp_, "[ Assignment\n");
1.3378 + indent();
1.3379 + node->lvalue()->accept(this);
1.3380 + node->expression()->accept(this);
1.3381 + unindent();
1.3382 + }
1.3383 + void visitTernaryExpression(TernaryExpression *node) {
1.3384 + prefix();
1.3385 + fprintf(fp_, "[ TernaryExpression\n");
1.3386 + indent();
1.3387 + node->condition()->accept(this);
1.3388 + node->left()->accept(this);
1.3389 + node->right()->accept(this);
1.3390 + unindent();
1.3391 + }
1.3392 + void visitBinaryExpression(BinaryExpression *node) {
1.3393 + prefix();
1.3394 + fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1.3395 + indent();
1.3396 + node->left()->accept(this);
1.3397 + node->right()->accept(this);
1.3398 + unindent();
1.3399 + }
1.3400 + void visitUnaryExpression(UnaryExpression *node) {
1.3401 + prefix();
1.3402 + fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1.3403 + indent();
1.3404 + node->expression()->accept(this);
1.3405 + unindent();
1.3406 + }
1.3407 + void visitReturnStatement(ReturnStatement *node) {
1.3408 + prefix();
1.3409 + fprintf(fp_, "[ ReturnStatement\n");
1.3410 + indent();
1.3411 + if (node->expression())
1.3412 + node->expression()->accept(this);
1.3413 + unindent();
1.3414 + }
1.3415 + void visitForStatement(ForStatement *node) {
1.3416 + prefix();
1.3417 + fprintf(fp_, "[ ForStatement\n");
1.3418 + indent();
1.3419 + if (node->initialization())
1.3420 + node->initialization()->accept(this);
1.3421 + if (node->condition())
1.3422 + node->condition()->accept(this);
1.3423 + if (node->update())
1.3424 + node->update()->accept(this);
1.3425 + node->body()->accept(this);
1.3426 + unindent();
1.3427 + }
1.3428 + void visitBlockStatement(BlockStatement *node) {
1.3429 + prefix();
1.3430 + fprintf(fp_, "[ BlockStatement\n");
1.3431 + indent();
1.3432 + for (size_t i = 0; i < node->statements()->length(); i++)
1.3433 + node->statements()->at(i)->accept(this);
1.3434 + unindent();
1.3435 + }
1.3436 + void visitVariableDeclaration(VariableDeclaration *node) {
1.3437 + prefix();
1.3438 + fprintf(fp_, "[ VariableDeclaration (%s)\n", node->name()->chars());
1.3439 + indent();
1.3440 + if (node->initialization())
1.3441 + node->initialization()->accept(this);
1.3442 + unindent();
1.3443 + }
1.3444 + void visitIntegerLiteral(IntegerLiteral *node) {
1.3445 + prefix();
1.3446 + fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1.3447 + }
1.3448 + void visitBooleanLiteral(BooleanLiteral *node) {
1.3449 + prefix();
1.3450 + fprintf(fp_, "[ BooleanLiteral (%s)\n",
1.3451 + (node->token() == TOK_TRUE) ? "true" : "false");
1.3452 + }
1.3453 + void visitFloatLiteral(FloatLiteral *node) {
1.3454 + prefix();
1.3455 + fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1.3456 + }
1.3457 + void visitIfStatement(IfStatement *node) {
1.3458 + prefix();
1.3459 + fprintf(fp_, "[ IfStatement\n");
1.3460 + indent();
1.3461 + node->ifTrue()->accept(this);
1.3462 + if (node->ifFalse())
1.3463 + node->ifFalse()->accept(this);
1.3464 + unindent();
1.3465 + }
1.3466 + void visitIndexExpression(IndexExpression *node) {
1.3467 + prefix();
1.3468 + fprintf(fp_, "[ IndexExpression\n");
1.3469 + indent();
1.3470 + node->left()->accept(this);
1.3471 + node->right()->accept(this);
1.3472 + unindent();
1.3473 + }
1.3474 + void visitEnumStatement(EnumStatement *node) {
1.3475 + prefix();
1.3476 + fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1.3477 + indent();
1.3478 + for (size_t i = 0; i < node->entries()->length(); i++) {
1.3479 + prefix();
1.3480 + fprintf(fp_, "%s =\n", node->entries()->at(i).name->chars());
1.3481 + if (node->entries()->at(i).expr) {
1.3482 + indent();
1.3483 + node->entries()->at(i).expr->accept(this);
1.3484 + unindent();
1.3485 + }
1.3486 + }
1.3487 + unindent();
1.3488 + }
1.3489 + void visitWhileStatement(WhileStatement *node) {
1.3490 + prefix();
1.3491 + fprintf(fp_, "[ WhileStatement (%s)\n",
1.3492 + (node->token() == TOK_DO) ? "do" : "while");
1.3493 + indent();
1.3494 + if (node->token() == TOK_DO) {
1.3495 + node->condition()->accept(this);
1.3496 + node->body()->accept(this);
1.3497 + } else {
1.3498 + node->condition()->accept(this);
1.3499 + node->body()->accept(this);
1.3500 + }
1.3501 + unindent();
1.3502 + }
1.3503 + void visitBreakStatement(BreakStatement *node) {
1.3504 + prefix();
1.3505 + fprintf(fp_, "[ BreakStatement\n");
1.3506 + }
1.3507 + void visitContinueStatement(ContinueStatement *node) {
1.3508 + prefix();
1.3509 + fprintf(fp_, "[ ContinueStatement\n");
1.3510 + }
1.3511 + void visitStringLiteral(StringLiteral *node) {
1.3512 + prefix();
1.3513 + fprintf(fp_, "[ StringLiteral\n");
1.3514 + }
1.3515 + void visitIncDecExpression(IncDecExpression *node) {
1.3516 + prefix();
1.3517 + fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1.3518 + indent();
1.3519 + node->expression()->accept(this);
1.3520 + unindent();
1.3521 + }
1.3522 + void visitStructureStatement(StructureStatement *node) {
1.3523 + prefix();
1.3524 + fprintf(fp_, "[ StructureStatement %s\n", node->name()->chars());
1.3525 + }
1.3526 + void visitFieldExpression(FieldExpression *node) {
1.3527 + prefix();
1.3528 + fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1.3529 + indent();
1.3530 + node->left()->accept(this);
1.3531 + unindent();
1.3532 + }
1.3533 + void visitSwitchStatement(SwitchStatement *node) {
1.3534 + prefix();
1.3535 + fprintf(fp_, "[ SwitchStatement\n");
1.3536 + indent();
1.3537 + node->expression()->accept(this);
1.3538 + for (size_t i = 0; i < node->cases()->length(); i++) {
1.3539 + Case *c = node->cases()->at(i);
1.3540 + c->expression()->accept(this);
1.3541 + if (c->others()) {
1.3542 + for (size_t j = 0; j < c->others()->length(); j++)
1.3543 + c->others()->at(j)->accept(this);
1.3544 + }
1.3545 + indent();
1.3546 + c->statement()->accept(this);
1.3547 + unindent();
1.3548 + }
1.3549 + if (node->defaultCase())
1.3550 + node->defaultCase()->accept(this);
1.3551 + unindent();
1.3552 + }
1.3553 + void visitArrayLiteral(ArrayLiteral *node) {
1.3554 + prefix();
1.3555 + fprintf(fp_, "[ ArrayLiteral\n");
1.3556 + indent();
1.3557 + for (size_t i = 0; i < node->expressions()->length(); i++) {
1.3558 + Expression *expr = node->expressions()->at(i);
1.3559 + indent();
1.3560 + expr->accept(this);
1.3561 + unindent();
1.3562 + }
1.3563 + }
1.3564 + void visitImportStatement(ImportStatement *node) {
1.3565 + prefix();
1.3566 + fprintf(fp_, "[ ImportStatement\n");
1.3567 + }
1.3568 +};
1.3569 +
1.3570 +void
1.3571 +ParseTree::dump(FILE *fp)
1.3572 +{
1.3573 + AstPrinter printer(fp);
1.3574 +
1.3575 + for (size_t i = 0; i < statements_->length(); i++)
1.3576 + statements_->at(i)->accept(&printer);
1.3577 +}