1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/compiler/Parser.cpp Sat Nov 17 18:41:01 2012 -0800
1.3 @@ -0,0 +1,1737 @@
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<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
1.129 + if (!array)
1.130 + return NULL;
1.131 + memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
1.132 + return new (pool_) StringLiteral(scanner_.begin(), array);
1.133 + }
1.134 +
1.135 + default:
1.136 + {
1.137 + if (kind != TOK_ERROR)
1.138 + cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
1.139 + return NULL;
1.140 + }
1.141 + }
1.142 +}
1.143 +
1.144 +Expression *
1.145 +Parser::arrayLiteral(TokenKind kind)
1.146 +{
1.147 + assert(kind == TOK_LBRACE || kind == TOK_LBRACKET);
1.148 +
1.149 + TokenKind close = (kind == TOK_LBRACE)
1.150 + ? TOK_RBRACE
1.151 + : TOK_RBRACKET;
1.152 +
1.153 + SourcePosition pos = scanner_.begin();
1.154 +
1.155 + ExpressionList *list = new (pool_) ExpressionList();
1.156 + do {
1.157 + if (match(close))
1.158 + break;
1.159 +
1.160 + Expression *expr = NULL;
1.161 + if (kind == TOK_LBRACE) {
1.162 + if (peek(TOK_LBRACE))
1.163 + expr = arrayLiteral(TOK_LBRACE);
1.164 + else
1.165 + expr = primitive();
1.166 + } else {
1.167 + expr = expression();
1.168 + }
1.169 + if (!expr)
1.170 + return NULL;
1.171 +
1.172 + if (!list->append(expr))
1.173 + return NULL;
1.174 +
1.175 + if (!match(TOK_COMMA)) {
1.176 + if (!expect(close))
1.177 + return NULL;
1.178 + break;
1.179 + }
1.180 + } while (true);
1.181 +
1.182 + return new (pool_) ArrayLiteral(pos, kind, list);
1.183 +}
1.184 +
1.185 +Expression *
1.186 +Parser::prefix()
1.187 +{
1.188 + switch (scanner_.peek()) {
1.189 + case TOK_LPAREN:
1.190 + {
1.191 + scanner_.scan();
1.192 + Expression *expr = expression();
1.193 + if (!expr)
1.194 + return NULL;
1.195 + if (!expect(TOK_RPAREN))
1.196 + return NULL;
1.197 + return expr;
1.198 + }
1.199 +
1.200 + case TOK_NAME:
1.201 + {
1.202 + Local<String> name(zone_, expectName());
1.203 + if (!name)
1.204 + return NULL;
1.205 + return new (pool_) NameProxy(scanner_.begin(), name);
1.206 + }
1.207 +
1.208 + default:
1.209 + return primitive();
1.210 + }
1.211 +}
1.212 +
1.213 +// Parses only old-style declarations.
1.214 +bool
1.215 +Parser::typeAndName(Expression **type, String **namep)
1.216 +{
1.217 + if (match(TOK_LABEL)) {
1.218 + // Old-style declaration:
1.219 + // new X:type
1.220 + Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.221 + if (!name)
1.222 + return false;
1.223 +
1.224 + *type = new (pool_) NameProxy(scanner_.begin(), name);
1.225 + *namep = expectName();
1.226 + return !!*namep;
1.227 + }
1.228 +
1.229 + *type = NULL;
1.230 + *namep = expectName();
1.231 +
1.232 + return !!*namep;
1.233 +}
1.234 +
1.235 +// Parses both old and new style declarations.
1.236 +bool
1.237 +Parser::fullTypeAndName(Expression **type, String **namep, DeclKind kind)
1.238 +{
1.239 + // Declaration:
1.240 + // NewDecl ::= Type Ident
1.241 + // OldDecl ::= Label? (Ident | "...")
1.242 + // Type ::= Ident
1.243 + // Label ::= Ident ":"
1.244 + //
1.245 + if (match(TOK_LABEL)) {
1.246 + // We something of the form:
1.247 + // Label Ident
1.248 + // or: Label "..."
1.249 + Local<String> name(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.250 + if (!name)
1.251 + return false;
1.252 +
1.253 + *type = new (pool_) NameProxy(scanner_.begin(), name);
1.254 + if (kind == DeclArg && match(TOK_ELLIPSES)) {
1.255 + *namep = NULL;
1.256 + } else {
1.257 + if ((*namep = expectName()) == NULL)
1.258 + return false;
1.259 + }
1.260 + return true;
1.261 + }
1.262 +
1.263 + Local<String> name(zone_, expectName());
1.264 + if (!name)
1.265 + return false;
1.266 +
1.267 + if (peek(TOK_NAME) || (kind == DeclArg && peek(TOK_ELLIPSES))) {
1.268 + // We got something of the form:
1.269 + // Ident Ident
1.270 + *type = new (pool_) NameProxy(scanner_.begin(), name);
1.271 + if (peek(TOK_NAME)) {
1.272 + if ((*namep = expectName()) == NULL)
1.273 + return false;
1.274 + } else {
1.275 + *namep = NULL;
1.276 + }
1.277 + return true;
1.278 + }
1.279 +
1.280 + // We got something of the form:
1.281 + // Ident
1.282 + *type = NULL;
1.283 + *namep = name;
1.284 + return true;
1.285 +}
1.286 +
1.287 +Expression *
1.288 +Parser::call(Expression *callee)
1.289 +{
1.290 + ExpressionList *arguments = new (pool_) ExpressionList();
1.291 +
1.292 + SourcePosition pos = scanner_.begin();
1.293 + expect(TOK_LPAREN);
1.294 +
1.295 + if (!match(TOK_RPAREN)) {
1.296 + while (true) {
1.297 + Expression *expr = expression();
1.298 + if (!expr)
1.299 + return NULL;
1.300 +
1.301 + if (!arguments->append(expr))
1.302 + return NULL;
1.303 +
1.304 + if (!match(TOK_COMMA))
1.305 + break;
1.306 + }
1.307 +
1.308 + if (!expect(TOK_RPAREN))
1.309 + return NULL;
1.310 + }
1.311 +
1.312 + return new (pool_) CallExpression(pos, callee, arguments);
1.313 +}
1.314 +
1.315 +Expression *
1.316 +Parser::index(Expression *left)
1.317 +{
1.318 + expect(TOK_LBRACKET);
1.319 +
1.320 + SourcePosition pos = scanner_.begin();
1.321 + Expression *expr = expression();
1.322 + if (!expr)
1.323 + return NULL;
1.324 +
1.325 + if (!expect(TOK_RBRACKET))
1.326 + return NULL;
1.327 +
1.328 + return new (pool_) IndexExpression(pos, left, expr);
1.329 +}
1.330 +
1.331 +Expression *
1.332 +Parser::field(Expression *left)
1.333 +{
1.334 + expect(TOK_DOT);
1.335 +
1.336 + SourcePosition pos = scanner_.begin();
1.337 + Local<String> name(zone_, expectName());
1.338 + if (!name)
1.339 + return NULL;
1.340 +
1.341 + return new (pool_) FieldExpression(pos, left, name);
1.342 +}
1.343 +
1.344 +Expression *
1.345 +Parser::primary()
1.346 +{
1.347 + Expression *expr = prefix();
1.348 + if (!expr)
1.349 + return NULL;
1.350 +
1.351 + for (;;) {
1.352 + switch (scanner_.peek()) {
1.353 + case TOK_LPAREN:
1.354 + if ((expr = call(expr)) == NULL)
1.355 + return NULL;
1.356 + break;
1.357 +
1.358 + case TOK_LBRACKET:
1.359 + if ((expr = index(expr)) == NULL)
1.360 + return NULL;
1.361 + break;
1.362 +
1.363 + case TOK_DOT:
1.364 + if ((expr = field(expr)) == NULL)
1.365 + return NULL;
1.366 + break;
1.367 +
1.368 + default:
1.369 + return expr;
1.370 + }
1.371 + }
1.372 +}
1.373 +
1.374 +Expression *
1.375 +Parser::unary()
1.376 +{
1.377 + TokenKind token = scanner_.peek();
1.378 +
1.379 + SourcePosition pos = scanner_.begin();
1.380 + switch (token) {
1.381 + case TOK_INCREMENT:
1.382 + case TOK_DECREMENT:
1.383 + {
1.384 + scanner_.scan();
1.385 + Expression *expr = unary();
1.386 + if (!expr)
1.387 + return NULL;
1.388 + return new (pool_) IncDecExpression(pos, token, expr, false);
1.389 + }
1.390 +
1.391 + case TOK_MINUS:
1.392 + case TOK_NOT:
1.393 + case TOK_TILDE:
1.394 + {
1.395 + scanner_.scan();
1.396 + Expression *expr = unary();
1.397 + if (!expr)
1.398 + return NULL;
1.399 + return new (pool_) UnaryExpression(pos, token, expr);
1.400 + }
1.401 +
1.402 + case TOK_SIZEOF:
1.403 + {
1.404 + scanner_.scan();
1.405 + if (!expect(TOK_LPAREN))
1.406 + return NULL;
1.407 + Expression *expr = unary();
1.408 + if (!expr)
1.409 + return NULL;
1.410 + if (!expect(TOK_RPAREN))
1.411 + return NULL;
1.412 + return new (pool_) UnaryExpression(pos, token, expr);
1.413 + }
1.414 +
1.415 + case TOK_LABEL:
1.416 + {
1.417 + scanner_.scan();
1.418 + Local<String> tag(zone_, zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()));
1.419 + if (!tag)
1.420 + return NULL;
1.421 +
1.422 + NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), tag);
1.423 +
1.424 + Expression *expr = unary();
1.425 + if (!expr)
1.426 + return NULL;
1.427 +
1.428 + return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, proxy);
1.429 + }
1.430 +
1.431 + default:
1.432 + break;
1.433 + }
1.434 +
1.435 + Expression *expr = primary();
1.436 +
1.437 + token = scanner_.peek();
1.438 + if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
1.439 + scanner_.scan();
1.440 + return new (pool_) IncDecExpression(pos, token, expr, true);
1.441 + }
1.442 +
1.443 + return expr;
1.444 +}
1.445 +
1.446 +Expression *
1.447 +Parser::multiplication()
1.448 +{
1.449 + Expression *left = unary();
1.450 + do {
1.451 + if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
1.452 + break;
1.453 + SourcePosition pos = scanner_.begin();
1.454 + TokenKind kind = scanner_.last();
1.455 + Expression *right = unary();
1.456 + if (!right)
1.457 + return NULL;
1.458 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.459 + } while (left);
1.460 + return left;
1.461 +}
1.462 +
1.463 +Expression *
1.464 +Parser::addition()
1.465 +{
1.466 + Expression *left = multiplication();
1.467 + while (left) {
1.468 + if (!match(TOK_PLUS) && !match(TOK_MINUS))
1.469 + break;
1.470 + SourcePosition pos = scanner_.begin();
1.471 + TokenKind kind = scanner_.last();
1.472 + Expression *right = multiplication();
1.473 + if (!right)
1.474 + return NULL;
1.475 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.476 + }
1.477 + return left;
1.478 +}
1.479 +
1.480 +Expression *
1.481 +Parser::shift()
1.482 +{
1.483 + Expression *left = addition();
1.484 + while (left) {
1.485 + if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
1.486 + break;
1.487 + SourcePosition pos = scanner_.begin();
1.488 + TokenKind kind = scanner_.last();
1.489 + Expression *right = addition();
1.490 + if (!right)
1.491 + return NULL;
1.492 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.493 + }
1.494 + return left;
1.495 +}
1.496 +
1.497 +Expression *
1.498 +Parser::bitand_()
1.499 +{
1.500 + Expression *left = shift();
1.501 + while (left) {
1.502 + if (!match(TOK_BITAND))
1.503 + break;
1.504 + SourcePosition pos = scanner_.begin();
1.505 + Expression *right = shift();
1.506 + if (!right)
1.507 + return NULL;
1.508 + left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
1.509 + }
1.510 + return left;
1.511 +}
1.512 +
1.513 +Expression *
1.514 +Parser::bitxor()
1.515 +{
1.516 + Expression *left = bitand_();
1.517 + while (left) {
1.518 + if (!match(TOK_BITXOR))
1.519 + break;
1.520 + SourcePosition pos = scanner_.begin();
1.521 + Expression *right = shift();
1.522 + if (!right)
1.523 + return NULL;
1.524 + left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
1.525 + }
1.526 + return left;
1.527 +}
1.528 +
1.529 +Expression *
1.530 +Parser::bitor_()
1.531 +{
1.532 + Expression *left = bitxor();
1.533 + while (left) {
1.534 + if (!match(TOK_BITOR))
1.535 + break;
1.536 + SourcePosition pos = scanner_.begin();
1.537 + Expression *right = bitxor();
1.538 + if (!right)
1.539 + return NULL;
1.540 + left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
1.541 + }
1.542 + return left;
1.543 +}
1.544 +
1.545 +Expression *
1.546 +Parser::relational()
1.547 +{
1.548 + Expression *left = bitor_();
1.549 + while (left) {
1.550 + TokenKind kind = scanner_.peek();
1.551 + if (kind < TOK_LT || kind > TOK_GE)
1.552 + break;
1.553 + scanner_.scan();
1.554 + SourcePosition pos = scanner_.begin();
1.555 + Expression *right = shift();
1.556 + if (!right)
1.557 + return NULL;
1.558 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.559 + }
1.560 + return left;
1.561 +}
1.562 +
1.563 +Expression *
1.564 +Parser::equals()
1.565 +{
1.566 + Expression *left = relational();
1.567 + while (left) {
1.568 + if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
1.569 + break;
1.570 + TokenKind kind = scanner_.last();
1.571 + SourcePosition pos = scanner_.begin();
1.572 + Expression *right = relational();
1.573 + if (!right)
1.574 + return NULL;
1.575 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.576 + }
1.577 + return left;
1.578 +}
1.579 +
1.580 +Expression *
1.581 +Parser::and_()
1.582 +{
1.583 + Expression *left = equals();
1.584 + while (left) {
1.585 + if (!match(TOK_AND))
1.586 + break;
1.587 + SourcePosition pos = scanner_.begin();
1.588 + Expression *right = equals();
1.589 + if (!right)
1.590 + return NULL;
1.591 + left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
1.592 + }
1.593 + return left;
1.594 +}
1.595 +
1.596 +Expression *
1.597 +Parser::or_()
1.598 +{
1.599 + Expression *left = and_();
1.600 + while (left) {
1.601 + if (!match(TOK_OR))
1.602 + break;
1.603 + SourcePosition pos = scanner_.begin();
1.604 + Expression *right = and_();
1.605 + if (!right)
1.606 + return NULL;
1.607 + left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
1.608 + }
1.609 + return left;
1.610 +}
1.611 +
1.612 +Expression *
1.613 +Parser::ternary()
1.614 +{
1.615 + Expression *cond = or_();
1.616 + if (!cond)
1.617 + return NULL;
1.618 +
1.619 + if (!match(TOK_QMARK))
1.620 + return cond;
1.621 +
1.622 + Expression *left;
1.623 + SourcePosition pos = scanner_.begin();
1.624 + AutoAllowTags<false> disableTags(scanner_);
1.625 + {
1.626 + if ((left = expression()) == NULL)
1.627 + return NULL;
1.628 + }
1.629 +
1.630 + if (!expect(TOK_COLON))
1.631 + return NULL;
1.632 +
1.633 + Expression *right = expression();
1.634 + if (!right)
1.635 + return NULL;
1.636 +
1.637 + return new (pool_) TernaryExpression(pos, cond, left, right);
1.638 +}
1.639 +
1.640 +Expression *
1.641 +Parser::assignment()
1.642 +{
1.643 + Expression *left = ternary();
1.644 + while (left) {
1.645 + TokenKind token = scanner_.peek();
1.646 + if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
1.647 + break;
1.648 + scanner_.scan();
1.649 + SourcePosition pos = scanner_.begin();
1.650 + Expression *expr = ternary();
1.651 + if (!expr)
1.652 + return NULL;
1.653 +
1.654 + left = new (pool_) Assignment(pos, token, left, expr);
1.655 + }
1.656 + return left;
1.657 +}
1.658 +
1.659 +Expression *
1.660 +Parser::expression()
1.661 +{
1.662 + return assignment();
1.663 +}
1.664 +
1.665 +Statement *
1.666 +Parser::while_()
1.667 +{
1.668 + SourcePosition pos = scanner_.begin();
1.669 + scanner_.scan();
1.670 +
1.671 + if (!expect(TOK_LPAREN))
1.672 + return NULL;
1.673 +
1.674 + Expression *condition = expression();
1.675 + if (!condition)
1.676 + return NULL;
1.677 +
1.678 + if (!expect(TOK_RPAREN))
1.679 + return NULL;
1.680 +
1.681 + Statement *body;
1.682 + if (scanner_.peek() == TOK_LBRACE)
1.683 + body = block();
1.684 + else
1.685 + body = localStatement();
1.686 + if (!body)
1.687 + return NULL;
1.688 +
1.689 + return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
1.690 +}
1.691 +
1.692 +Statement *
1.693 +Parser::do_()
1.694 +{
1.695 + SourcePosition pos = scanner_.begin();
1.696 + scanner_.scan();
1.697 +
1.698 + Statement *body;
1.699 + if (scanner_.peek() == TOK_LBRACE)
1.700 + body = block();
1.701 + else
1.702 + body = localStatement();
1.703 + if (!body)
1.704 + return NULL;
1.705 +
1.706 + if (!expect(TOK_WHILE))
1.707 + return NULL;
1.708 +
1.709 + if (!expect(TOK_LPAREN))
1.710 + return NULL;
1.711 + Expression *condition = expression();
1.712 + if (!condition)
1.713 + return NULL;
1.714 + if (!expect(TOK_RPAREN))
1.715 + return NULL;
1.716 +
1.717 + return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
1.718 +}
1.719 +
1.720 +Statement *
1.721 +Parser::switch_()
1.722 +{
1.723 + expect(TOK_SWITCH);
1.724 +
1.725 + SourcePosition pos = scanner_.begin();
1.726 +
1.727 + if (!expect(TOK_LPAREN))
1.728 + return NULL;
1.729 + Expression *expr = expression();
1.730 + if (!expr)
1.731 + return NULL;
1.732 + if (!expect(TOK_RPAREN))
1.733 + return NULL;
1.734 +
1.735 + if (!expect(TOK_LBRACE))
1.736 + return NULL;
1.737 +
1.738 + SourcePosition defaultPos;
1.739 + PoolList<Case *> *cases = new (pool_) PoolList<Case *>();
1.740 +
1.741 + Statement *defaultCase = NULL;
1.742 +
1.743 + while (!peek(TOK_RBRACE)) {
1.744 + Expression *expr = NULL;
1.745 + ExpressionList *others = NULL;
1.746 + if (match(TOK_DEFAULT)) {
1.747 + if (defaultCase) {
1.748 + cc_.reportError(scanner_.begin(), Message_OneDefaultPerSwitch);
1.749 + return NULL;
1.750 + }
1.751 +
1.752 + defaultPos = scanner_.begin();
1.753 + } else {
1.754 + if (defaultCase) {
1.755 + cc_.reportError(defaultPos, Message_DefaultMustBeLastCase);
1.756 + return NULL;
1.757 + }
1.758 +
1.759 + if (!expect(TOK_CASE))
1.760 + return NULL;
1.761 +
1.762 + // A limitation in the grammar is that |case <NAME>:| will be
1.763 + // detected as a label.
1.764 + AutoAllowTags<false> disableTags(scanner_);
1.765 +
1.766 + if ((expr = expression()) == NULL)
1.767 + return NULL;
1.768 +
1.769 + if (peek(TOK_COMMA)) {
1.770 + others = new (pool_) ExpressionList();
1.771 + while (match(TOK_COMMA)) {
1.772 + Expression *other = expression();
1.773 + if (!other)
1.774 + return NULL;
1.775 + if (!others->append(other))
1.776 + return NULL;
1.777 + }
1.778 + }
1.779 + }
1.780 +
1.781 + if (!expect(TOK_COLON))
1.782 + return NULL;
1.783 +
1.784 + Statement *statement = localStatement();
1.785 + if (!statement)
1.786 + return NULL;
1.787 +
1.788 + if (!peek(TOK_CASE) &&
1.789 + !peek(TOK_DEFAULT) &&
1.790 + !peek(TOK_RBRACE))
1.791 + {
1.792 + cc_.reportError(scanner_.begin(), Message_SingleStatementPerCase);
1.793 + return NULL;
1.794 + }
1.795 +
1.796 + if (expr) {
1.797 + Case *caze = new (pool_) Case(expr, others, statement);
1.798 + if (!cases->append(caze))
1.799 + return NULL;
1.800 + } else {
1.801 + defaultCase = statement;
1.802 + }
1.803 + }
1.804 +
1.805 + if (!expect(TOK_RBRACE))
1.806 + return NULL;
1.807 +
1.808 + return new (pool_) SwitchStatement(pos, expr, cases, defaultCase);
1.809 +}
1.810 +
1.811 +Statement *
1.812 +Parser::forStatement()
1.813 +{
1.814 + SourcePosition pos = scanner_.begin();
1.815 + scanner_.scan();
1.816 + if (!expect(TOK_LPAREN))
1.817 + return NULL;
1.818 +
1.819 + Statement *decl = NULL;
1.820 + if (!match(TOK_SEMICOLON)) {
1.821 + if (match(TOK_NEW)) {
1.822 + if ((decl = vars(Qual_None)) == NULL)
1.823 + return NULL;
1.824 + } else {
1.825 + if ((decl = expressionStatement()) == NULL)
1.826 + return NULL;
1.827 + }
1.828 + if (!expect(TOK_SEMICOLON))
1.829 + return NULL;
1.830 + }
1.831 +
1.832 + Expression *condition = NULL;
1.833 + if (!match(TOK_SEMICOLON)) {
1.834 + if ((condition = expression()) == NULL)
1.835 + return NULL;
1.836 + if (!expect(TOK_SEMICOLON))
1.837 + return NULL;
1.838 + }
1.839 +
1.840 + Statement *update = NULL;
1.841 + if (!match(TOK_RPAREN)) {
1.842 + if ((update = expressionStatement()) == NULL)
1.843 + return NULL;
1.844 + if (!expect(TOK_RPAREN))
1.845 + return NULL;
1.846 + }
1.847 +
1.848 + Statement *body;
1.849 + if (scanner_.peek() == TOK_LBRACE)
1.850 + body = block();
1.851 + else
1.852 + body = localStatement();
1.853 + if (!body)
1.854 + return NULL;
1.855 +
1.856 + return new (pool_) ForStatement(pos, decl, condition, update, body);
1.857 +}
1.858 +
1.859 +ExpressionList *
1.860 +Parser::dimensions()
1.861 +{
1.862 + ExpressionList *postDimensions = new (pool_) ExpressionList();
1.863 + while (match(TOK_LBRACKET)) {
1.864 + Expression *dim = NULL;
1.865 + if (!match(TOK_RBRACKET)) {
1.866 + if ((dim = expression()) == NULL)
1.867 + return NULL;
1.868 + if (!expect(TOK_RBRACKET))
1.869 + return NULL;
1.870 + }
1.871 +
1.872 + if (!postDimensions->append(dim))
1.873 + return NULL;
1.874 + }
1.875 + return postDimensions;
1.876 +}
1.877 +
1.878 +VariableDeclaration *
1.879 +Parser::var(TypeQualifiers qual)
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 + SourcePosition pos = scanner_.begin();
1.888 +
1.889 + Expression *expr = NULL;
1.890 + if (match(TOK_ASSIGN)) {
1.891 + switch (scanner_.peek()) {
1.892 + // Note: we don't support [] literals yet.
1.893 + case TOK_LBRACE:
1.894 + if ((expr = arrayLiteral(scanner_.scan())) == NULL)
1.895 + return NULL;
1.896 + break;
1.897 +
1.898 + default:
1.899 + if ((expr = expression()) == NULL)
1.900 + return NULL;
1.901 + break;
1.902 + }
1.903 + }
1.904 +
1.905 + return new (pool_) VariableDeclaration(pos, qual, name, type, expr);
1.906 +}
1.907 +
1.908 +Statement *
1.909 +Parser::vars(TypeQualifiers qual)
1.910 +{
1.911 + VariableDeclaration *decl = var(qual);
1.912 + if (!decl)
1.913 + return NULL;
1.914 +
1.915 + if (!peek(TOK_COMMA))
1.916 + return decl;
1.917 +
1.918 + StatementList *statements = new (pool_) StatementList();
1.919 + if (!statements->append(decl))
1.920 + return NULL;
1.921 +
1.922 + while (match(TOK_COMMA)) {
1.923 + Statement *decl = var(qual);
1.924 + if (!decl)
1.925 + return NULL;
1.926 + if (!statements->append(decl))
1.927 + return NULL;
1.928 + }
1.929 +
1.930 + // Create a fake-o block with no scope to create a statement list.
1.931 + return new (pool_) BlockStatement(decl->pos(), statements);
1.932 +}
1.933 +
1.934 +Statement *
1.935 +Parser::returnStatement()
1.936 +{
1.937 + SourcePosition pos = scanner_.begin();
1.938 + if (!expect(TOK_RETURN))
1.939 + return NULL;
1.940 +
1.941 + Expression *expr = NULL;
1.942 + if (scanner_.peek() != TOK_SEMICOLON) {
1.943 + if ((expr = expression()) == NULL)
1.944 + return NULL;
1.945 +
1.946 + // We only care about non-void returns when determining whether a
1.947 + // tagless function is non-void.
1.948 + encounteredReturn_ = true;
1.949 + }
1.950 +
1.951 + return new (pool_) ReturnStatement(pos, expr);
1.952 +}
1.953 +
1.954 +Statement *
1.955 +Parser::expressionStatement()
1.956 +{
1.957 + Expression *left = assignment();
1.958 + if (!left)
1.959 + return NULL;
1.960 +
1.961 + return new (pool_) ExpressionStatement(left);
1.962 +}
1.963 +
1.964 +Statement *
1.965 +Parser::block()
1.966 +{
1.967 + if (!expect(TOK_LBRACE))
1.968 + return NULL;
1.969 +
1.970 + SourcePosition pos = scanner_.begin();
1.971 +
1.972 + StatementList *statements = new (pool_) StatementList();
1.973 + while (!match(TOK_RBRACE)) {
1.974 + Statement *statement = localStatement();
1.975 + if (statement == NULL)
1.976 + return NULL;
1.977 + if (!statements->append(statement))
1.978 + return NULL;
1.979 + }
1.980 +
1.981 + BlockStatement *block = new (pool_) BlockStatement(pos, statements);
1.982 + return block;
1.983 +}
1.984 +
1.985 +Statement *
1.986 +Parser::if_()
1.987 +{
1.988 + expect(TOK_IF);
1.989 +
1.990 + SourcePosition pos = scanner_.begin();
1.991 + if (!expect(TOK_LPAREN))
1.992 + return NULL;
1.993 +
1.994 + Expression *cond = expression();
1.995 + if (!cond)
1.996 + return NULL;
1.997 +
1.998 + if (!expect(TOK_RPAREN))
1.999 + return NULL;
1.1000 +
1.1001 + Statement *ifTrue = localStatement();
1.1002 + if (!ifTrue)
1.1003 + return NULL;
1.1004 +
1.1005 + IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1.1006 +
1.1007 + IfStatement *last = outer;
1.1008 + while (match(TOK_ELSE)) {
1.1009 + if (!match(TOK_IF)) {
1.1010 + Statement *ifFalse = localStatement();
1.1011 + if (!ifFalse)
1.1012 + return NULL;
1.1013 +
1.1014 + last->setIfFalse(ifFalse);
1.1015 + break;
1.1016 + }
1.1017 +
1.1018 + SourcePosition pos = scanner_.begin();
1.1019 + if (!expect(TOK_LPAREN))
1.1020 + return NULL;
1.1021 +
1.1022 + Expression *otherCond = expression();
1.1023 + if (!otherCond)
1.1024 + return NULL;
1.1025 +
1.1026 + if (!expect(TOK_RPAREN))
1.1027 + return NULL;
1.1028 +
1.1029 + Statement *otherIfTrue = localStatement();
1.1030 + if (!otherIfTrue)
1.1031 + return NULL;
1.1032 +
1.1033 + IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1.1034 + last->setIfFalse(inner);
1.1035 + last = inner;
1.1036 + }
1.1037 +
1.1038 + return outer;
1.1039 +}
1.1040 +
1.1041 +Statement *
1.1042 +Parser::localStatement()
1.1043 +{
1.1044 + Statement *statement = NULL;
1.1045 +
1.1046 + // Statements which must be followed by a semicolon will break out of the
1.1047 + // switch. If they may end in BlockStatements, they'll immediately return.
1.1048 +
1.1049 + TokenKind kind = scanner_.peek();
1.1050 + switch (kind) {
1.1051 + case TOK_CONST:
1.1052 + case TOK_NEW:
1.1053 + {
1.1054 + TypeQualifiers quals = (kind == TOK_CONST)
1.1055 + ? Qual_Const
1.1056 + : Qual_None;
1.1057 + scanner_.scan();
1.1058 + if ((statement = vars(quals)) == NULL)
1.1059 + return NULL;
1.1060 + break;
1.1061 + }
1.1062 +
1.1063 + case TOK_FOR:
1.1064 + return forStatement();
1.1065 +
1.1066 + case TOK_WHILE:
1.1067 + return while_();
1.1068 +
1.1069 + case TOK_BREAK:
1.1070 + scanner_.scan();
1.1071 + statement = new (pool_) BreakStatement(scanner_.begin());
1.1072 + break;
1.1073 +
1.1074 + case TOK_CONTINUE:
1.1075 + scanner_.scan();
1.1076 + statement = new (pool_) ContinueStatement(scanner_.begin());
1.1077 + break;
1.1078 +
1.1079 + case TOK_DO:
1.1080 + if ((statement = do_()) == NULL)
1.1081 + return NULL;
1.1082 + break;
1.1083 +
1.1084 + case TOK_RETURN:
1.1085 + if ((statement = returnStatement()) == NULL)
1.1086 + return NULL;
1.1087 + break;
1.1088 +
1.1089 + case TOK_ENUM:
1.1090 + if ((statement = enum_()) == NULL)
1.1091 + return NULL;
1.1092 + break;
1.1093 +
1.1094 + case TOK_STRUCT:
1.1095 + if ((statement = struct_()) == NULL)
1.1096 + return NULL;
1.1097 + break;
1.1098 +
1.1099 + case TOK_SWITCH:
1.1100 + return switch_();
1.1101 +
1.1102 + case TOK_IF:
1.1103 + return if_();
1.1104 +
1.1105 + case TOK_LBRACE:
1.1106 + return block();
1.1107 +
1.1108 + default:
1.1109 + break;
1.1110 + }
1.1111 +
1.1112 + if (!statement) {
1.1113 + if ((statement = expressionStatement()) == NULL)
1.1114 + return NULL;
1.1115 + }
1.1116 +
1.1117 + if (!expect(TOK_SEMICOLON))
1.1118 + return NULL;
1.1119 +
1.1120 + return statement;
1.1121 +}
1.1122 +
1.1123 +Statement *
1.1124 +Parser::struct_()
1.1125 +{
1.1126 + expect(TOK_STRUCT);
1.1127 +
1.1128 + Local<String> name(zone_, expectName());
1.1129 + if (!name)
1.1130 + return NULL;
1.1131 +
1.1132 + SourcePosition pos = scanner_.begin();
1.1133 +
1.1134 + if (!expect(TOK_LBRACE))
1.1135 + return NULL;
1.1136 +
1.1137 + FieldList *fields = new (pool_) FieldList();
1.1138 +
1.1139 + while (!peek(TOK_RBRACE)) {
1.1140 + Expression *type;
1.1141 + Local<String> fieldName(zone_);
1.1142 +
1.1143 + if (!fullTypeAndName(&type, fieldName.ref(), DeclField))
1.1144 + return NULL;
1.1145 +
1.1146 + SourcePosition pos = scanner_.begin();
1.1147 +
1.1148 + if (!matchSemicolon())
1.1149 + return NULL;
1.1150 +
1.1151 + StructureStatement::Field *field =
1.1152 + new (pool_) StructureStatement::Field(pos, type, fieldName);
1.1153 + if (!field || !fields->append(field))
1.1154 + return NULL;
1.1155 + }
1.1156 +
1.1157 + if (!expect(TOK_RBRACE))
1.1158 + return NULL;
1.1159 +
1.1160 + if (fields->empty()) {
1.1161 + cc_.reportError(pos, Message_StructCantBeEmpty);
1.1162 + return NULL;
1.1163 + }
1.1164 +
1.1165 + return new (pool_) StructureStatement(pos, name, fields);
1.1166 +}
1.1167 +
1.1168 +Statement *
1.1169 +Parser::enum_()
1.1170 +{
1.1171 + expect(TOK_ENUM);
1.1172 +
1.1173 + SourcePosition pos = scanner_.begin();
1.1174 +
1.1175 + Local<String> name(zone_);
1.1176 + if (matchName(name.ref()) && !name)
1.1177 + return NULL;
1.1178 +
1.1179 + EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1.1180 +
1.1181 + if (!expect(TOK_LBRACE))
1.1182 + return NULL;
1.1183 +
1.1184 + do {
1.1185 + if (scanner_.peek() == TOK_RBRACE)
1.1186 + break;
1.1187 +
1.1188 + Local<String> name(zone_, expectName());
1.1189 + if (!name)
1.1190 + return NULL;
1.1191 +
1.1192 + Expression *expr = NULL;
1.1193 + if (match(TOK_ASSIGN)) {
1.1194 + if ((expr = expression()) == NULL)
1.1195 + return NULL;
1.1196 + }
1.1197 +
1.1198 + if (!entries->append(EnumStatement::Entry(name, expr)))
1.1199 + return NULL;
1.1200 + } while (match(TOK_COMMA));
1.1201 + if (!expect(TOK_RBRACE))
1.1202 + return NULL;
1.1203 +
1.1204 + return new (pool_) EnumStatement(pos, name, entries);
1.1205 +}
1.1206 +
1.1207 +template <class T>
1.1208 +static inline ScopedRoot<T> *
1.1209 +NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
1.1210 +{
1.1211 + ScopedRoot<T> *root = pool.alloc<ScopedRoot<T> >();
1.1212 + new (root) ScopedRoot<T>(obj);
1.1213 + return root;
1.1214 +}
1.1215 +
1.1216 +ImportStatement *
1.1217 +Parser::import()
1.1218 +{
1.1219 + NameList *names = new (pool_) NameList();
1.1220 +
1.1221 + SourcePosition pos = scanner_.begin();
1.1222 +
1.1223 + Local<String> name(zone_, expectName());
1.1224 + if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
1.1225 + return NULL;
1.1226 +
1.1227 + TokenKind suffix = TOK_NONE;
1.1228 + while (match(TOK_DOT)) {
1.1229 + if (match(TOK_STAR)) {
1.1230 + suffix = TOK_STAR;
1.1231 + break;
1.1232 + }
1.1233 +
1.1234 + if ((name = expectName()) == NULL)
1.1235 + return NULL;
1.1236 +
1.1237 + if (!names->append(NewScopedRoot<String>(pool_, name)))
1.1238 + return NULL;
1.1239 + }
1.1240 +
1.1241 + return new (pool_) ImportStatement(pos, names, suffix);
1.1242 +}
1.1243 +
1.1244 +Statement *
1.1245 +Parser::function(TokenKind token)
1.1246 +{
1.1247 + Expression *returnType;
1.1248 + Local<String> name(zone_);
1.1249 +
1.1250 + if (!fullTypeAndName(&returnType, name.ref(), DeclFun))
1.1251 + return NULL;
1.1252 +
1.1253 + SourcePosition pos = scanner_.begin();
1.1254 + ParameterList *parameters = new (pool_) ParameterList();
1.1255 +
1.1256 + if (!expect(TOK_LPAREN))
1.1257 + return NULL;
1.1258 +
1.1259 + bool variadic = false;
1.1260 +
1.1261 + if (!match(TOK_RPAREN)) {
1.1262 + while (true) {
1.1263 + bool isConst = match(TOK_CONST);
1.1264 + bool ref = match(TOK_AMPERSAND);
1.1265 +
1.1266 + SourcePosition begin = scanner_.begin();
1.1267 + Expression *type;
1.1268 + Local<String> name(zone_);
1.1269 + if (!fullTypeAndName(&type, name.ref(), DeclArg))
1.1270 + return NULL;
1.1271 +
1.1272 + if (!name) {
1.1273 + if (isConst || ref) {
1.1274 + cc_.reportError(begin, Message_InvalidVarArgs);
1.1275 + return NULL;
1.1276 + }
1.1277 +
1.1278 + if (token != TOK_NATIVE) {
1.1279 + cc_.reportError(begin, Message_VarArgsOutsideNative);
1.1280 + return NULL;
1.1281 + }
1.1282 +
1.1283 + variadic = true;
1.1284 + break;
1.1285 + }
1.1286 +
1.1287 + Expression *expr = NULL;
1.1288 + if (match(TOK_ASSIGN)) {
1.1289 + if ((expr = expression()) == NULL)
1.1290 + return NULL;
1.1291 + }
1.1292 +
1.1293 + Parameter *parameter = new (pool_) Parameter(name, type, ref, isConst, expr, begin);
1.1294 + if (!parameters->append(parameter))
1.1295 + return NULL;
1.1296 +
1.1297 + if (!match(TOK_COMMA))
1.1298 + break;
1.1299 + }
1.1300 + if (!expect(TOK_RPAREN))
1.1301 + return NULL;
1.1302 + }
1.1303 +
1.1304 + encounteredReturn_ = false;
1.1305 +
1.1306 + Statement *body = NULL;
1.1307 + if (token != TOK_FORWARD && token != TOK_NATIVE && token != TOK_TYPEDEF) {
1.1308 + body = block();
1.1309 + if (!body)
1.1310 + return NULL;
1.1311 + }
1.1312 +
1.1313 + FunctionSignature signature(returnType, parameters, variadic);
1.1314 + if (token == TOK_TYPEDEF)
1.1315 + return new (pool_) FunctionTypeStatement(pos, name, signature);
1.1316 +
1.1317 + return new (pool_) FunctionStatement(pos, name, token, body, signature, encounteredReturn_);
1.1318 +}
1.1319 +
1.1320 +static inline bool
1.1321 +DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, Handle<Type> type)
1.1322 +{
1.1323 + Local<String> tag(zone, zone->makeSymbol(name));
1.1324 + if (!tag)
1.1325 + return false;
1.1326 +
1.1327 + assert(false);
1.1328 + return false; //return !!scope->declareType(tag, type);
1.1329 +}
1.1330 +
1.1331 +static inline bool
1.1332 +DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
1.1333 +{
1.1334 + Local<Type> primitive(zone, zone->types()->getPrimitive(type));
1.1335 + assert(primitive);
1.1336 + return DeclareIntrinsicType(zone, scope, name, primitive);
1.1337 +}
1.1338 +
1.1339 +bool
1.1340 +Parser::setupIntrinsics()
1.1341 +{
1.1342 +#if 0
1.1343 + if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
1.1344 + return false;
1.1345 + if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
1.1346 + return false;
1.1347 + if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
1.1348 + return false;
1.1349 + if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
1.1350 + return false;
1.1351 +
1.1352 + Local<Type> unchecked(zone_, zone_->types()->getUnchecked());
1.1353 + if (!DeclareIntrinsicType(zone_, scope_, "unchecked", unchecked))
1.1354 + return false;
1.1355 +
1.1356 + Local<Type> voidType(zone_, zone_->types()->getVoid());
1.1357 + if (!DeclareIntrinsicType(zone_, scope_, "void", voidType))
1.1358 + return false;
1.1359 +
1.1360 + Local<Type> intType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1.1361 + if (!DeclareIntrinsicType(zone_, scope_, "int", intType))
1.1362 + return false;
1.1363 +#endif
1.1364 + return true;
1.1365 +}
1.1366 +
1.1367 +ParseTree *
1.1368 +Parser::parse()
1.1369 +{
1.1370 + StatementList *statements = new (pool_) StatementList();
1.1371 +
1.1372 + if (!setupIntrinsics())
1.1373 + return NULL;
1.1374 +
1.1375 + for (;;) {
1.1376 + Statement *statement = NULL;
1.1377 +
1.1378 + TokenKind kind = scanner_.peek();
1.1379 + switch (kind) {
1.1380 + case TOK_ERROR:
1.1381 + return NULL;
1.1382 +
1.1383 + case TOK_EOF:
1.1384 + break;
1.1385 +
1.1386 + case TOK_NAME:
1.1387 + if ((statement = function(TOK_NAME)) == NULL)
1.1388 + return NULL;
1.1389 + break;
1.1390 +
1.1391 + case TOK_IMPORT:
1.1392 + {
1.1393 + scanner_.scan();
1.1394 + if (statements->length())
1.1395 + cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
1.1396 + ImportStatement *stmt = import();
1.1397 + if (!stmt)
1.1398 + return NULL;
1.1399 + if (!imports_->append(stmt))
1.1400 + return NULL;
1.1401 + if (!matchSemicolon())
1.1402 + return NULL;
1.1403 + continue;
1.1404 + }
1.1405 +
1.1406 + case TOK_FORWARD:
1.1407 + case TOK_PUBLIC:
1.1408 + case TOK_NATIVE:
1.1409 + case TOK_STOCK:
1.1410 + case TOK_LABEL:
1.1411 + case TOK_TYPEDEF:
1.1412 + {
1.1413 + if (kind != TOK_LABEL)
1.1414 + scanner_.scan();
1.1415 + if (kind == TOK_PUBLIC && peek(TOK_CONST)) {
1.1416 + TypeQualifiers quals = TypeQualifiers(Qual_Public | Qual_Const);
1.1417 + if ((statement = var(quals)) == NULL)
1.1418 + return NULL;
1.1419 + if (!matchSemicolon())
1.1420 + return NULL;
1.1421 + } else {
1.1422 + if ((statement = function(kind)) == NULL)
1.1423 + return NULL;
1.1424 + if ((kind == TOK_FORWARD || kind == TOK_NATIVE || kind == TOK_TYPEDEF) && !matchSemicolon())
1.1425 + return NULL;
1.1426 + }
1.1427 + break;
1.1428 + }
1.1429 +
1.1430 + case TOK_CONST:
1.1431 + case TOK_NEW:
1.1432 + {
1.1433 + TypeQualifiers quals = (kind == TOK_NEW) ? Qual_Const : Qual_None;
1.1434 + // Note: at global scope, we don't accept comma-delimited
1.1435 + // declarations yet, to see if we can get away with forcing
1.1436 + // a nicer top-level style.
1.1437 + scanner_.scan();
1.1438 + if ((statement = var(quals)) == NULL)
1.1439 + return NULL;
1.1440 + if (!matchSemicolon())
1.1441 + return NULL;
1.1442 + break;
1.1443 + }
1.1444 +
1.1445 + case TOK_ENUM:
1.1446 + if ((statement = enum_()) == NULL)
1.1447 + return NULL;
1.1448 + if (!matchSemicolon())
1.1449 + return NULL;
1.1450 + break;
1.1451 +
1.1452 + case TOK_STRUCT:
1.1453 + if ((statement = struct_()) == NULL)
1.1454 + return NULL;
1.1455 + if (!matchSemicolon())
1.1456 + return NULL;
1.1457 + break;
1.1458 +
1.1459 + default:
1.1460 + cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1.1461 + return NULL;
1.1462 + }
1.1463 +
1.1464 + if (!statement)
1.1465 + break;
1.1466 +
1.1467 + if (!statements->append(statement))
1.1468 + return NULL;
1.1469 + }
1.1470 +
1.1471 + return new (pool_) ParseTree(statements, unbound_, imports_);
1.1472 +}
1.1473 +
1.1474 +class AstPrinter : public AstVisitor
1.1475 +{
1.1476 + FILE *fp_;
1.1477 + size_t level_;
1.1478 +
1.1479 + private:
1.1480 + void prefix() {
1.1481 + for (size_t i = 0; i < level_; i++)
1.1482 + fprintf(fp_, " ");
1.1483 + }
1.1484 + void indent() {
1.1485 + level_++;
1.1486 + }
1.1487 + void unindent() {
1.1488 + level_--;
1.1489 + }
1.1490 +
1.1491 + public:
1.1492 + AstPrinter(FILE *fp)
1.1493 + : fp_(fp),
1.1494 + level_(0)
1.1495 + {
1.1496 + }
1.1497 +
1.1498 + void dump(const FunctionSignature &sig) {
1.1499 + prefix();
1.1500 + fprintf(fp_, "()\n");
1.1501 + }
1.1502 + void visitNameProxy(NameProxy *name) {
1.1503 + prefix();
1.1504 + fprintf(fp_, "[ NameProxy (%s)\n", name->name()->chars());
1.1505 + }
1.1506 + void visitCallExpression(CallExpression *node) {
1.1507 + prefix();
1.1508 + fprintf(fp_, "[ CallExpression\n");
1.1509 + indent();
1.1510 + node->callee()->accept(this);
1.1511 + for (size_t i = 0; i < node->arguments()->length(); i++)
1.1512 + node->arguments()->at(i)->accept(this);
1.1513 + unindent();
1.1514 + }
1.1515 + void visitFunctionTypeStatement(FunctionTypeStatement *node) {
1.1516 + prefix();
1.1517 + fprintf(fp_, "[ FunctionTypeStatement (%s)\n", node->name()->chars());
1.1518 + indent();
1.1519 + dump(node->signature());
1.1520 + unindent();
1.1521 + }
1.1522 + void visitFunctionStatement(FunctionStatement *node) {
1.1523 + prefix();
1.1524 + fprintf(fp_, "[ FunctionStatement (%s)\n", node->name()->chars());
1.1525 + indent();
1.1526 + dump(node->signature());
1.1527 + if (node->body())
1.1528 + node->body()->accept(this);
1.1529 + unindent();
1.1530 + }
1.1531 + void visitExpressionStatement(ExpressionStatement *node) {
1.1532 + prefix();
1.1533 + fprintf(fp_, "[ ExpressionStatement\n");
1.1534 + indent();
1.1535 + node->expression()->accept(this);
1.1536 + unindent();
1.1537 + }
1.1538 + void visitAssignment(Assignment *node) {
1.1539 + prefix();
1.1540 + fprintf(fp_, "[ Assignment\n");
1.1541 + indent();
1.1542 + node->lvalue()->accept(this);
1.1543 + node->expression()->accept(this);
1.1544 + unindent();
1.1545 + }
1.1546 + void visitTernaryExpression(TernaryExpression *node) {
1.1547 + prefix();
1.1548 + fprintf(fp_, "[ TernaryExpression\n");
1.1549 + indent();
1.1550 + node->condition()->accept(this);
1.1551 + node->left()->accept(this);
1.1552 + node->right()->accept(this);
1.1553 + unindent();
1.1554 + }
1.1555 + void visitBinaryExpression(BinaryExpression *node) {
1.1556 + prefix();
1.1557 + fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1.1558 + indent();
1.1559 + node->left()->accept(this);
1.1560 + node->right()->accept(this);
1.1561 + unindent();
1.1562 + }
1.1563 + void visitUnaryExpression(UnaryExpression *node) {
1.1564 + prefix();
1.1565 + fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1.1566 + indent();
1.1567 + node->expression()->accept(this);
1.1568 + unindent();
1.1569 + }
1.1570 + void visitReturnStatement(ReturnStatement *node) {
1.1571 + prefix();
1.1572 + fprintf(fp_, "[ ReturnStatement\n");
1.1573 + indent();
1.1574 + if (node->expression())
1.1575 + node->expression()->accept(this);
1.1576 + unindent();
1.1577 + }
1.1578 + void visitForStatement(ForStatement *node) {
1.1579 + prefix();
1.1580 + fprintf(fp_, "[ ForStatement\n");
1.1581 + indent();
1.1582 + if (node->initialization())
1.1583 + node->initialization()->accept(this);
1.1584 + if (node->condition())
1.1585 + node->condition()->accept(this);
1.1586 + if (node->update())
1.1587 + node->update()->accept(this);
1.1588 + node->body()->accept(this);
1.1589 + unindent();
1.1590 + }
1.1591 + void visitBlockStatement(BlockStatement *node) {
1.1592 + prefix();
1.1593 + fprintf(fp_, "[ BlockStatement\n");
1.1594 + indent();
1.1595 + for (size_t i = 0; i < node->statements()->length(); i++)
1.1596 + node->statements()->at(i)->accept(this);
1.1597 + unindent();
1.1598 + }
1.1599 + void visitVariableDeclaration(VariableDeclaration *node) {
1.1600 + prefix();
1.1601 + fprintf(fp_, "[ VariableDeclaration (%s)\n", node->name()->chars());
1.1602 + indent();
1.1603 + if (node->initialization())
1.1604 + node->initialization()->accept(this);
1.1605 + unindent();
1.1606 + }
1.1607 + void visitIntegerLiteral(IntegerLiteral *node) {
1.1608 + prefix();
1.1609 + fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1.1610 + }
1.1611 + void visitBooleanLiteral(BooleanLiteral *node) {
1.1612 + prefix();
1.1613 + fprintf(fp_, "[ BooleanLiteral (%s)\n",
1.1614 + (node->token() == TOK_TRUE) ? "true" : "false");
1.1615 + }
1.1616 + void visitFloatLiteral(FloatLiteral *node) {
1.1617 + prefix();
1.1618 + fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1.1619 + }
1.1620 + void visitIfStatement(IfStatement *node) {
1.1621 + prefix();
1.1622 + fprintf(fp_, "[ IfStatement\n");
1.1623 + indent();
1.1624 + node->ifTrue()->accept(this);
1.1625 + if (node->ifFalse())
1.1626 + node->ifFalse()->accept(this);
1.1627 + unindent();
1.1628 + }
1.1629 + void visitIndexExpression(IndexExpression *node) {
1.1630 + prefix();
1.1631 + fprintf(fp_, "[ IndexExpression\n");
1.1632 + indent();
1.1633 + node->left()->accept(this);
1.1634 + node->right()->accept(this);
1.1635 + unindent();
1.1636 + }
1.1637 + void visitEnumStatement(EnumStatement *node) {
1.1638 + prefix();
1.1639 + fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1.1640 + indent();
1.1641 + for (size_t i = 0; i < node->entries()->length(); i++) {
1.1642 + prefix();
1.1643 + fprintf(fp_, "%s =\n", node->entries()->at(i).name->chars());
1.1644 + if (node->entries()->at(i).expr) {
1.1645 + indent();
1.1646 + node->entries()->at(i).expr->accept(this);
1.1647 + unindent();
1.1648 + }
1.1649 + }
1.1650 + unindent();
1.1651 + }
1.1652 + void visitWhileStatement(WhileStatement *node) {
1.1653 + prefix();
1.1654 + fprintf(fp_, "[ WhileStatement (%s)\n",
1.1655 + (node->token() == TOK_DO) ? "do" : "while");
1.1656 + indent();
1.1657 + if (node->token() == TOK_DO) {
1.1658 + node->condition()->accept(this);
1.1659 + node->body()->accept(this);
1.1660 + } else {
1.1661 + node->condition()->accept(this);
1.1662 + node->body()->accept(this);
1.1663 + }
1.1664 + unindent();
1.1665 + }
1.1666 + void visitBreakStatement(BreakStatement *node) {
1.1667 + prefix();
1.1668 + fprintf(fp_, "[ BreakStatement\n");
1.1669 + }
1.1670 + void visitContinueStatement(ContinueStatement *node) {
1.1671 + prefix();
1.1672 + fprintf(fp_, "[ ContinueStatement\n");
1.1673 + }
1.1674 + void visitStringLiteral(StringLiteral *node) {
1.1675 + prefix();
1.1676 + fprintf(fp_, "[ StringLiteral\n");
1.1677 + }
1.1678 + void visitIncDecExpression(IncDecExpression *node) {
1.1679 + prefix();
1.1680 + fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1.1681 + indent();
1.1682 + node->expression()->accept(this);
1.1683 + unindent();
1.1684 + }
1.1685 + void visitStructureStatement(StructureStatement *node) {
1.1686 + prefix();
1.1687 + fprintf(fp_, "[ StructureStatement %s\n", node->name()->chars());
1.1688 + }
1.1689 + void visitFieldExpression(FieldExpression *node) {
1.1690 + prefix();
1.1691 + fprintf(fp_, "[ FieldExpression %s\n", node->field()->chars());
1.1692 + indent();
1.1693 + node->left()->accept(this);
1.1694 + unindent();
1.1695 + }
1.1696 + void visitSwitchStatement(SwitchStatement *node) {
1.1697 + prefix();
1.1698 + fprintf(fp_, "[ SwitchStatement\n");
1.1699 + indent();
1.1700 + node->expression()->accept(this);
1.1701 + for (size_t i = 0; i < node->cases()->length(); i++) {
1.1702 + Case *c = node->cases()->at(i);
1.1703 + c->expression()->accept(this);
1.1704 + if (c->others()) {
1.1705 + for (size_t j = 0; j < c->others()->length(); j++)
1.1706 + c->others()->at(j)->accept(this);
1.1707 + }
1.1708 + indent();
1.1709 + c->statement()->accept(this);
1.1710 + unindent();
1.1711 + }
1.1712 + if (node->defaultCase())
1.1713 + node->defaultCase()->accept(this);
1.1714 + unindent();
1.1715 + }
1.1716 + void visitArrayLiteral(ArrayLiteral *node) {
1.1717 + prefix();
1.1718 + fprintf(fp_, "[ ArrayLiteral\n");
1.1719 + indent();
1.1720 + for (size_t i = 0; i < node->expressions()->length(); i++) {
1.1721 + Expression *expr = node->expressions()->at(i);
1.1722 + indent();
1.1723 + expr->accept(this);
1.1724 + unindent();
1.1725 + }
1.1726 + }
1.1727 + void visitImportStatement(ImportStatement *node) {
1.1728 + prefix();
1.1729 + fprintf(fp_, "[ ImportStatement\n");
1.1730 + }
1.1731 +};
1.1732 +
1.1733 +void
1.1734 +ParseTree::dump(FILE *fp)
1.1735 +{
1.1736 + AstPrinter printer(fp);
1.1737 +
1.1738 + for (size_t i = 0; i < statements_->length(); i++)
1.1739 + statements_->at(i)->accept(&printer);
1.1740 +}