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