1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/Parser.cpp Tue Jul 24 23:53:34 2012 -0700
1.3 @@ -0,0 +1,1314 @@
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 JITCraft.
1.9 + *
1.10 + * JITCraft 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 + * Foobar 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 + * JITCraft. If not, see http://www.gnu.org/licenses/.
1.21 + */
1.22 +#include "Zone.h"
1.23 +#include "Parser.h"
1.24 +#include "FixedArray.h"
1.25 +#include "Heap.h"
1.26 +#include "Strings.h"
1.27 +#include "Heap-inl.h"
1.28 +
1.29 +using namespace ke;
1.30 +
1.31 +Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
1.32 + : zone_(zone),
1.33 + cc_(cc),
1.34 + pool_(zone_->pool()),
1.35 + scanner_(cc, stream, length),
1.36 + scope_(NULL),
1.37 + unbound_(NULL)
1.38 +{
1.39 + unbound_ = new (pool_) PoolList<NameProxy *>();
1.40 +}
1.41 +
1.42 +bool
1.43 +Parser::match(TokenKind kind)
1.44 +{
1.45 + if (scanner_.peek() != kind)
1.46 + return false;
1.47 + scanner_.scan();
1.48 + return true;
1.49 +}
1.50 +
1.51 +bool
1.52 +Parser::matchSemicolon()
1.53 +{
1.54 + return expect(TOK_SEMICOLON);
1.55 +}
1.56 +
1.57 +bool
1.58 +Parser::expect(TokenKind kind)
1.59 +{
1.60 + TokenKind got = scanner_.scan();
1.61 + if (got == kind)
1.62 + return true;
1.63 + cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
1.64 + return false;
1.65 +}
1.66 +
1.67 +Scope *
1.68 +Parser::enterScope(Scope::Kind kind)
1.69 +{
1.70 + scope_ = new (pool_) Scope(pool_, kind, scope_);
1.71 + if (!scope_->initialize())
1.72 + return NULL;
1.73 + return scope_;
1.74 +}
1.75 +
1.76 +NameProxy *
1.77 +Parser::bind(Handle<String> name)
1.78 +{
1.79 + BoundName *bound = scope_->lookup(name);
1.80 + NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), name, bound);
1.81 + if (!bound && !unbound_->append(proxy))
1.82 + return NULL;
1.83 + return proxy;
1.84 +}
1.85 +
1.86 +bool
1.87 +Parser::matchName(String **name, TokenKind kind)
1.88 +{
1.89 + assert(kind == TOK_NAME || kind == TOK_LABEL);
1.90 + *name = NULL;
1.91 + if (!match(kind))
1.92 + return false;
1.93 + *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1.94 + return true;
1.95 +}
1.96 +
1.97 +String *
1.98 +Parser::expectName()
1.99 +{
1.100 + if (!expect(TOK_NAME))
1.101 + return NULL;
1.102 + return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
1.103 +}
1.104 +
1.105 +void
1.106 +Parser::redeclarationError(BoundName *other)
1.107 +{
1.108 + cc_.reportError(scanner_.begin(), Message_RedeclaredName, other->name()->chars(),
1.109 + other->pos().line, other->pos().col);
1.110 +}
1.111 +
1.112 +Expression *
1.113 +Parser::primitive()
1.114 +{
1.115 + TokenKind kind = scanner_.peek();
1.116 + switch (kind) {
1.117 + case TOK_NAME:
1.118 + {
1.119 + Local<String> name(zone_, expectName());
1.120 + if (!name)
1.121 + return NULL;
1.122 + return bind(name);
1.123 + }
1.124 +
1.125 + case TOK_FLOAT_LITERAL:
1.126 + {
1.127 + scanner_.scan();
1.128 + double value = Scanner::ParseDouble(scanner_.literal());
1.129 + return new (pool_) FloatLiteral(scanner_.begin(), value);
1.130 + }
1.131 +
1.132 + case TOK_INTEGER_LITERAL:
1.133 + {
1.134 + scanner_.scan();
1.135 + int value = atoi(scanner_.literal());
1.136 + return new (pool_) IntegerLiteral(scanner_.begin(), value);
1.137 + }
1.138 +
1.139 + case TOK_STRING_LITERAL:
1.140 + {
1.141 + scanner_.scan();
1.142 + Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
1.143 + if (!array)
1.144 + return NULL;
1.145 + memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
1.146 + return new (pool_) StringLiteral(scanner_.begin(), array);
1.147 + }
1.148 +
1.149 + default:
1.150 + {
1.151 + if (kind != TOK_ERROR)
1.152 + cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
1.153 + return NULL;
1.154 + }
1.155 + }
1.156 +}
1.157 +
1.158 +Expression *
1.159 +Parser::prefix()
1.160 +{
1.161 + switch (scanner_.peek()) {
1.162 + case TOK_LPAREN:
1.163 + {
1.164 + scanner_.scan();
1.165 + Expression *expr = expression();
1.166 + if (!expr)
1.167 + return NULL;
1.168 + if (!expect(TOK_RPAREN))
1.169 + return NULL;
1.170 + return expr;
1.171 + }
1.172 +
1.173 + default:
1.174 + return primitive();
1.175 + }
1.176 +}
1.177 +
1.178 +Expression *
1.179 +Parser::call(Expression *callee)
1.180 +{
1.181 + ExpressionList *arguments = new (pool_) ExpressionList();
1.182 +
1.183 + SourcePosition pos = scanner_.begin();
1.184 + expect(TOK_LPAREN);
1.185 +
1.186 + if (!match(TOK_RPAREN)) {
1.187 + while (true) {
1.188 + Expression *expr = expression();
1.189 + if (!expr)
1.190 + return NULL;
1.191 +
1.192 + if (!arguments->append(expr))
1.193 + return NULL;
1.194 +
1.195 + if (!match(TOK_COMMA))
1.196 + break;
1.197 + }
1.198 +
1.199 + if (!expect(TOK_RPAREN))
1.200 + return NULL;
1.201 + }
1.202 +
1.203 + return new (pool_) CallExpression(pos, callee, arguments);
1.204 +}
1.205 +
1.206 +Expression *
1.207 +Parser::index(Expression *left)
1.208 +{
1.209 + expect(TOK_LBRACKET);
1.210 +
1.211 + SourcePosition pos = scanner_.begin();
1.212 + Expression *expr = expression();
1.213 + if (!expr)
1.214 + return NULL;
1.215 +
1.216 + if (!expect(TOK_RBRACKET))
1.217 + return NULL;
1.218 +
1.219 + return new (pool_) IndexExpression(pos, left, expr);
1.220 +}
1.221 +
1.222 +Expression *
1.223 +Parser::primary()
1.224 +{
1.225 + Expression *expr = prefix();
1.226 + if (!expr)
1.227 + return NULL;
1.228 +
1.229 + for (;;) {
1.230 + switch (scanner_.peek()) {
1.231 + case TOK_LPAREN:
1.232 + expr = call(expr);
1.233 + if (!expr)
1.234 + return NULL;
1.235 + break;
1.236 +
1.237 + case TOK_LBRACKET:
1.238 + expr = index(expr);
1.239 + if (!expr)
1.240 + return NULL;
1.241 + break;
1.242 +
1.243 + default:
1.244 + return expr;
1.245 + }
1.246 + }
1.247 +}
1.248 +
1.249 +Expression *
1.250 +Parser::unary()
1.251 +{
1.252 + TokenKind token = scanner_.peek();
1.253 +
1.254 + SourcePosition pos = scanner_.begin();
1.255 + switch (token) {
1.256 + case TOK_INCREMENT:
1.257 + case TOK_DECREMENT:
1.258 + {
1.259 + scanner_.scan();
1.260 + Expression *expr = expression();
1.261 + if (!expr)
1.262 + return NULL;
1.263 + return new (pool_) IncDecExpression(pos, token, expr, false);
1.264 + }
1.265 +
1.266 + case TOK_MINUS:
1.267 + case TOK_NOT:
1.268 + case TOK_TILDE:
1.269 + {
1.270 + scanner_.scan();
1.271 + Expression *expr = expression();
1.272 + if (!expr)
1.273 + return NULL;
1.274 + return new (pool_) UnaryExpression(pos, token, expr);
1.275 + }
1.276 +
1.277 + default:
1.278 + break;
1.279 + }
1.280 +
1.281 + Expression *expr = primary();
1.282 +
1.283 + token = scanner_.peek();
1.284 + if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
1.285 + scanner_.scan();
1.286 + return new (pool_) IncDecExpression(pos, token, expr, true);
1.287 + }
1.288 +
1.289 + return expr;
1.290 +}
1.291 +
1.292 +Expression *
1.293 +Parser::multiplication()
1.294 +{
1.295 + Expression *left = unary();
1.296 + do {
1.297 + if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
1.298 + break;
1.299 + SourcePosition pos = scanner_.begin();
1.300 + TokenKind kind = scanner_.last();
1.301 + Expression *right = unary();
1.302 + if (!right)
1.303 + return NULL;
1.304 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.305 + } while (left);
1.306 + return left;
1.307 +}
1.308 +
1.309 +Expression *
1.310 +Parser::addition()
1.311 +{
1.312 + Expression *left = multiplication();
1.313 + while (left) {
1.314 + if (!match(TOK_PLUS) && !match(TOK_MINUS))
1.315 + break;
1.316 + SourcePosition pos = scanner_.begin();
1.317 + TokenKind kind = scanner_.last();
1.318 + Expression *right = multiplication();
1.319 + if (!right)
1.320 + return NULL;
1.321 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.322 + }
1.323 + return left;
1.324 +}
1.325 +
1.326 +Expression *
1.327 +Parser::shift()
1.328 +{
1.329 + Expression *left = addition();
1.330 + while (left) {
1.331 + if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
1.332 + break;
1.333 + SourcePosition pos = scanner_.begin();
1.334 + TokenKind kind = scanner_.last();
1.335 + Expression *right = addition();
1.336 + if (!right)
1.337 + return NULL;
1.338 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.339 + }
1.340 + return left;
1.341 +}
1.342 +
1.343 +Expression *
1.344 +Parser::bitand_()
1.345 +{
1.346 + Expression *left = shift();
1.347 + while (left) {
1.348 + if (!match(TOK_BITAND))
1.349 + break;
1.350 + SourcePosition pos = scanner_.begin();
1.351 + Expression *right = shift();
1.352 + if (!right)
1.353 + return NULL;
1.354 + left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
1.355 + }
1.356 + return left;
1.357 +}
1.358 +
1.359 +Expression *
1.360 +Parser::bitxor()
1.361 +{
1.362 + Expression *left = bitand_();
1.363 + while (left) {
1.364 + if (!match(TOK_BITXOR))
1.365 + break;
1.366 + SourcePosition pos = scanner_.begin();
1.367 + Expression *right = shift();
1.368 + if (!right)
1.369 + return NULL;
1.370 + left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
1.371 + }
1.372 + return left;
1.373 +}
1.374 +
1.375 +Expression *
1.376 +Parser::bitor_()
1.377 +{
1.378 + Expression *left = bitxor();
1.379 + while (left) {
1.380 + if (!match(TOK_BITOR))
1.381 + break;
1.382 + SourcePosition pos = scanner_.begin();
1.383 + Expression *right = bitxor();
1.384 + if (!right)
1.385 + return NULL;
1.386 + left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
1.387 + }
1.388 + return left;
1.389 +}
1.390 +
1.391 +Expression *
1.392 +Parser::relational()
1.393 +{
1.394 + Expression *left = bitor_();
1.395 + while (left) {
1.396 + TokenKind kind = scanner_.peek();
1.397 + if (kind < TOK_LT || kind > TOK_GE)
1.398 + break;
1.399 + scanner_.scan();
1.400 + SourcePosition pos = scanner_.begin();
1.401 + Expression *right = shift();
1.402 + if (!right)
1.403 + return NULL;
1.404 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.405 + }
1.406 + return left;
1.407 +}
1.408 +
1.409 +Expression *
1.410 +Parser::equals()
1.411 +{
1.412 + Expression *left = relational();
1.413 + while (left) {
1.414 + if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
1.415 + break;
1.416 + TokenKind kind = scanner_.last();
1.417 + SourcePosition pos = scanner_.begin();
1.418 + Expression *right = relational();
1.419 + if (!right)
1.420 + return NULL;
1.421 + left = new (pool_) BinaryExpression(pos, kind, left, right);
1.422 + }
1.423 + return left;
1.424 +}
1.425 +
1.426 +Expression *
1.427 +Parser::and_()
1.428 +{
1.429 + Expression *left = equals();
1.430 + while (left) {
1.431 + if (!match(TOK_AND))
1.432 + break;
1.433 + SourcePosition pos = scanner_.begin();
1.434 + Expression *right = equals();
1.435 + if (!right)
1.436 + return NULL;
1.437 + left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
1.438 + }
1.439 + return left;
1.440 +}
1.441 +
1.442 +Expression *
1.443 +Parser::or_()
1.444 +{
1.445 + Expression *left = and_();
1.446 + while (left) {
1.447 + if (!match(TOK_OR))
1.448 + break;
1.449 + SourcePosition pos = scanner_.begin();
1.450 + Expression *right = and_();
1.451 + if (!right)
1.452 + return NULL;
1.453 + left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
1.454 + }
1.455 + return left;
1.456 +}
1.457 +
1.458 +Expression *
1.459 +Parser::ternary()
1.460 +{
1.461 + Expression *cond = or_();
1.462 + if (!cond)
1.463 + return NULL;
1.464 +
1.465 + if (!match(TOK_QMARK))
1.466 + return cond;
1.467 +
1.468 + SourcePosition pos = scanner_.begin();
1.469 + Expression *left = expression();
1.470 + if (!left)
1.471 + return NULL;
1.472 +
1.473 + if (!expect(TOK_COLON))
1.474 + return NULL;
1.475 +
1.476 + Expression *right = expression();
1.477 + if (!right)
1.478 + return NULL;
1.479 +
1.480 + return new (pool_) TernaryExpression(pos, cond, left, right);
1.481 +}
1.482 +
1.483 +Expression *
1.484 +Parser::assignment()
1.485 +{
1.486 + Expression *left = ternary();
1.487 + while (left) {
1.488 + TokenKind token = scanner_.peek();
1.489 + if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
1.490 + break;
1.491 + scanner_.scan();
1.492 + SourcePosition pos = scanner_.begin();
1.493 + Expression *expr = ternary();
1.494 + if (!expr)
1.495 + return NULL;
1.496 +
1.497 + left = new (pool_) Assignment(pos, token, left, expr);
1.498 + }
1.499 + return left;
1.500 +}
1.501 +
1.502 +Expression *
1.503 +Parser::expression()
1.504 +{
1.505 + return assignment();
1.506 +}
1.507 +
1.508 +Statement *
1.509 +Parser::while_()
1.510 +{
1.511 + SourcePosition pos = scanner_.begin();
1.512 + scanner_.scan();
1.513 +
1.514 + if (!expect(TOK_LPAREN))
1.515 + return NULL;
1.516 +
1.517 + Expression *condition = expression();
1.518 + if (!condition)
1.519 + return NULL;
1.520 +
1.521 + if (!expect(TOK_RPAREN))
1.522 + return NULL;
1.523 +
1.524 + // Inside a loop, we force the creation of a scope object. Normally, we
1.525 + // will cull scopes if they have no variables. However inside a loop,
1.526 + // function calls that take references may compute a LIFO object, and to
1.527 + // avoid temporarily leaking many such objects, we ensure that a scope
1.528 + // is present so a LIFO slot can be allocated.
1.529 + if (!enterScope(Scope::BLOCK))
1.530 + return NULL;
1.531 +
1.532 + Statement *body;
1.533 + if (scanner_.peek() == TOK_LBRACE)
1.534 + body = block(scope_);
1.535 + else
1.536 + body = localStatement();
1.537 + if (!body)
1.538 + return NULL;
1.539 +
1.540 + scope_ = scope_->enclosing();
1.541 + return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
1.542 +}
1.543 +
1.544 +Statement *
1.545 +Parser::do_()
1.546 +{
1.547 + SourcePosition pos = scanner_.begin();
1.548 + scanner_.scan();
1.549 +
1.550 + // See the comment in ::while_() as to why we force a scope.
1.551 + if (!enterScope(Scope::BLOCK))
1.552 + return NULL;
1.553 +
1.554 + Statement *body;
1.555 + if (scanner_.peek() == TOK_LBRACE)
1.556 + body = block(scope_);
1.557 + else
1.558 + body = localStatement();
1.559 + if (!body)
1.560 + return NULL;
1.561 +
1.562 + scope_ = scope_->enclosing();
1.563 +
1.564 + if (!expect(TOK_WHILE))
1.565 + return NULL;
1.566 +
1.567 + if (!expect(TOK_LPAREN))
1.568 + return NULL;
1.569 + Expression *condition = expression();
1.570 + if (!condition)
1.571 + return NULL;
1.572 + if (!expect(TOK_RPAREN))
1.573 + return NULL;
1.574 +
1.575 + return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
1.576 +}
1.577 +
1.578 +Statement *
1.579 +Parser::forStatement()
1.580 +{
1.581 + SourcePosition pos = scanner_.begin();
1.582 + scanner_.scan();
1.583 + if (!expect(TOK_LPAREN))
1.584 + return NULL;
1.585 +
1.586 + Statement *decl = NULL;
1.587 + if (!match(TOK_SEMICOLON)) {
1.588 + if (scanner_.peek() == TOK_NEW) {
1.589 + if (!enterScope(Scope::BLOCK))
1.590 + return NULL;
1.591 + if ((decl = variableDeclaration()) == NULL)
1.592 + return NULL;
1.593 + } else {
1.594 + if ((decl = expressionStatement()) == NULL)
1.595 + return NULL;
1.596 + }
1.597 + if (!expect(TOK_SEMICOLON))
1.598 + return NULL;
1.599 + }
1.600 +
1.601 + Expression *condition = NULL;
1.602 + if (!match(TOK_SEMICOLON)) {
1.603 + if ((condition = expression()) == NULL)
1.604 + return NULL;
1.605 + if (!expect(TOK_SEMICOLON))
1.606 + return NULL;
1.607 + }
1.608 +
1.609 + Statement *update = NULL;
1.610 + if (!match(TOK_RPAREN)) {
1.611 + if ((update = expressionStatement()) == NULL)
1.612 + return NULL;
1.613 + if (!expect(TOK_RPAREN))
1.614 + return NULL;
1.615 + }
1.616 +
1.617 + // See the comment in ::while_() as to why we force a scope.
1.618 + if (!enterScope(Scope::BLOCK))
1.619 + return NULL;
1.620 +
1.621 + Statement *body;
1.622 + if (scanner_.peek() == TOK_LBRACE)
1.623 + body = block(scope_);
1.624 + else
1.625 + body = localStatement();
1.626 + if (!body)
1.627 + return NULL;
1.628 +
1.629 + scope_ = scope_->enclosing();
1.630 +
1.631 + Scope *declScope = NULL;
1.632 + if (decl && decl->isVariableDeclaration()) {
1.633 + declScope = scope_->unlinkIfEmpty();
1.634 + scope_ = scope_->enclosing();
1.635 + }
1.636 + return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
1.637 +}
1.638 +
1.639 +VariableDeclaration *
1.640 +Parser::variableDeclaration()
1.641 +{
1.642 + if (!expect(TOK_NEW))
1.643 + return NULL;
1.644 +
1.645 + Local<String> tag(zone_);
1.646 + if (matchName(tag.ref(), TOK_LABEL) && !tag)
1.647 + return NULL;
1.648 +
1.649 + Local<String> name(zone_, expectName());
1.650 + if (!name)
1.651 + return NULL;
1.652 +
1.653 + if (BoundName *other = scope_->localLookup(name)) {
1.654 + redeclarationError(other);
1.655 + return NULL;
1.656 + }
1.657 +
1.658 + Variable *var = scope_->declareVariable(name, scanner_.begin());
1.659 + if (!var)
1.660 + return NULL;
1.661 +
1.662 + ExpressionList *postDimensions = NULL;
1.663 + if (scanner_.peek() == TOK_LBRACKET) {
1.664 + postDimensions = new (pool_) ExpressionList();
1.665 + while (match(TOK_LBRACKET)) {
1.666 + Expression *dim = expression();
1.667 + if (!dim)
1.668 + return NULL;
1.669 +
1.670 + if (!expect(TOK_RBRACKET))
1.671 + return NULL;
1.672 +
1.673 + if (!postDimensions->append(dim))
1.674 + return NULL;
1.675 + }
1.676 + }
1.677 +
1.678 + Expression *expr = NULL;
1.679 + if (match(TOK_ASSIGN)) {
1.680 + if ((expr = expression()) == NULL)
1.681 + return NULL;
1.682 + }
1.683 +
1.684 + return new (pool_) VariableDeclaration(var->pos(), var, tag, postDimensions, expr);
1.685 +}
1.686 +
1.687 +Statement *
1.688 +Parser::returnStatement()
1.689 +{
1.690 + SourcePosition pos = scanner_.begin();
1.691 + if (!expect(TOK_RETURN))
1.692 + return NULL;
1.693 +
1.694 + Expression *expr = NULL;
1.695 + if (scanner_.peek() != TOK_SEMICOLON) {
1.696 + if ((expr = expression()) == NULL)
1.697 + return NULL;
1.698 +
1.699 + // We only care about non-void returns when determining whether a
1.700 + // tagless function is non-void.
1.701 + encounteredReturn_ = true;
1.702 + }
1.703 +
1.704 + return new (pool_) ReturnStatement(pos, expr);
1.705 +}
1.706 +
1.707 +Statement *
1.708 +Parser::expressionStatement()
1.709 +{
1.710 + Expression *left = assignment();
1.711 + if (!left)
1.712 + return NULL;
1.713 +
1.714 + return new (pool_) ExpressionStatement(left);
1.715 +}
1.716 +
1.717 +Statement *
1.718 +Parser::block(Scope *scope)
1.719 +{
1.720 + if (!expect(TOK_LBRACE))
1.721 + return NULL;
1.722 +
1.723 + SourcePosition pos = scanner_.begin();
1.724 + if (!scope && !enterScope(Scope::BLOCK))
1.725 + return NULL;
1.726 +
1.727 + StatementList *statements = new (pool_) StatementList();
1.728 + while (!match(TOK_RBRACE)) {
1.729 + Statement *statement = localStatement();
1.730 + if (statement == NULL)
1.731 + return NULL;
1.732 + if (!statements->append(statement))
1.733 + return NULL;
1.734 + }
1.735 +
1.736 + if (!scope) {
1.737 + scope = scope_->unlinkIfEmpty();
1.738 + scope_ = scope_->enclosing();
1.739 + }
1.740 + BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
1.741 + return block;
1.742 +}
1.743 +
1.744 +Statement *
1.745 +Parser::if_()
1.746 +{
1.747 + expect(TOK_IF);
1.748 +
1.749 + SourcePosition pos = scanner_.begin();
1.750 + if (!expect(TOK_LPAREN))
1.751 + return NULL;
1.752 +
1.753 + Expression *cond = expression();
1.754 + if (!cond)
1.755 + return NULL;
1.756 +
1.757 + if (!expect(TOK_RPAREN))
1.758 + return NULL;
1.759 +
1.760 + Statement *ifTrue = localStatement();
1.761 + if (!ifTrue)
1.762 + return NULL;
1.763 +
1.764 + IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
1.765 +
1.766 + IfStatement *last = outer;
1.767 + while (match(TOK_ELSE)) {
1.768 + if (!match(TOK_IF)) {
1.769 + Statement *ifFalse = localStatement();
1.770 + if (!ifFalse)
1.771 + return NULL;
1.772 +
1.773 + last->setIfFalse(ifFalse);
1.774 + break;
1.775 + }
1.776 +
1.777 + SourcePosition pos = scanner_.begin();
1.778 + if (!expect(TOK_LPAREN))
1.779 + return NULL;
1.780 +
1.781 + Expression *otherCond = expression();
1.782 + if (!otherCond)
1.783 + return NULL;
1.784 +
1.785 + if (!expect(TOK_RPAREN))
1.786 + return NULL;
1.787 +
1.788 + Statement *otherIfTrue = localStatement();
1.789 + if (!otherIfTrue)
1.790 + return NULL;
1.791 +
1.792 + IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
1.793 + last->setIfFalse(inner);
1.794 + last = inner;
1.795 + }
1.796 +
1.797 + return outer;
1.798 +}
1.799 +
1.800 +Statement *
1.801 +Parser::localStatement()
1.802 +{
1.803 + Statement *statement = NULL;
1.804 +
1.805 + // Statements which must be followed by a semicolon will break out of the
1.806 + // switch. If they may end in BlockStatements, they'll immediately return.
1.807 +
1.808 + switch (scanner_.peek()) {
1.809 + case TOK_NEW:
1.810 + if ((statement = variableDeclaration()) == NULL)
1.811 + return NULL;
1.812 + break;
1.813 +
1.814 + case TOK_FOR:
1.815 + return forStatement();
1.816 +
1.817 + case TOK_WHILE:
1.818 + return while_();
1.819 +
1.820 + case TOK_BREAK:
1.821 + scanner_.scan();
1.822 + statement = new (pool_) BreakStatement(scanner_.begin());
1.823 + break;
1.824 +
1.825 + case TOK_CONTINUE:
1.826 + scanner_.scan();
1.827 + statement = new (pool_) ContinueStatement(scanner_.begin());
1.828 + break;
1.829 +
1.830 + case TOK_DO:
1.831 + if ((statement = do_()) == NULL)
1.832 + return NULL;
1.833 + break;
1.834 +
1.835 + case TOK_RETURN:
1.836 + if ((statement = returnStatement()) == NULL)
1.837 + return NULL;
1.838 + break;
1.839 +
1.840 + case TOK_ENUM:
1.841 + if ((statement = enum_()) == NULL)
1.842 + return NULL;
1.843 + break;
1.844 +
1.845 + case TOK_IF:
1.846 + return if_();
1.847 +
1.848 + case TOK_LBRACE:
1.849 + return block();
1.850 +
1.851 + default:
1.852 + break;
1.853 + }
1.854 +
1.855 + if (!statement) {
1.856 + if ((statement = expressionStatement()) == NULL)
1.857 + return NULL;
1.858 + }
1.859 +
1.860 + if (!expect(TOK_SEMICOLON))
1.861 + return NULL;
1.862 +
1.863 + return statement;
1.864 +}
1.865 +
1.866 +Statement *
1.867 +Parser::enum_()
1.868 +{
1.869 + expect(TOK_ENUM);
1.870 +
1.871 + SourcePosition pos = scanner_.begin();
1.872 +
1.873 + Local<String> name(zone_);
1.874 + if (matchName(name.ref())) {
1.875 + if (!name)
1.876 + return NULL;
1.877 +
1.878 + if (BoundName *other = scope_->localLookup(name)) {
1.879 + redeclarationError(other);
1.880 + return NULL;
1.881 + }
1.882 +
1.883 + if (!scope_->declareEnum(name, scanner_.begin()))
1.884 + return NULL;
1.885 + }
1.886 +
1.887 + EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
1.888 +
1.889 + if (!expect(TOK_LBRACE))
1.890 + return NULL;
1.891 +
1.892 + do {
1.893 + if (scanner_.peek() == TOK_RBRACE)
1.894 + break;
1.895 +
1.896 + Local<String> name(zone_, expectName());
1.897 + if (!name)
1.898 + return NULL;
1.899 +
1.900 + if (BoundName *other = scope_->localLookup(name)) {
1.901 + redeclarationError(other);
1.902 + return NULL;
1.903 + }
1.904 +
1.905 + NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
1.906 + if (!constant)
1.907 + return NULL;
1.908 +
1.909 + Expression *expr = NULL;
1.910 + if (match(TOK_ASSIGN)) {
1.911 + if ((expr = expression()) == NULL)
1.912 + return NULL;
1.913 + }
1.914 +
1.915 + if (!entries->append(EnumStatement::Entry(constant, expr)))
1.916 + return NULL;
1.917 + } while (match(TOK_COMMA));
1.918 + if (!expect(TOK_RBRACE))
1.919 + return NULL;
1.920 +
1.921 + return new (pool_) EnumStatement(pos, name, entries);
1.922 +}
1.923 +
1.924 +Statement *
1.925 +Parser::function(TokenKind token)
1.926 +{
1.927 + Local<String> name(zone_, expectName());
1.928 + if (!name)
1.929 + return NULL;
1.930 +
1.931 + SourcePosition pos = scanner_.begin();
1.932 +
1.933 + // The function name goes into the outer (global) scope.
1.934 + assert(!scope_->enclosing());
1.935 +
1.936 + NamedFunction *fun;
1.937 + if (BoundName *other = scope_->localLookup(name)) {
1.938 + // We allow a redeclaration if the new type is a public, and the old
1.939 + // type was a forward. However, the forward must come first.
1.940 + if (other->kind() != BoundName::FUNCTION) {
1.941 + redeclarationError(other);
1.942 + return NULL;
1.943 + }
1.944 +
1.945 + fun = other->toNamedFunction();
1.946 + if (!fun->isForward() || token != TOK_PUBLIC) {
1.947 + redeclarationError(other);
1.948 + return NULL;
1.949 + }
1.950 +
1.951 + // We've got the same name, but the original is a forward, so let it
1.952 + // slide and re-use the original declaration.
1.953 + fun->setImplemented(scanner_.begin());
1.954 + } else {
1.955 + fun = scope_->declareFunction(name, scanner_.begin(), token);
1.956 + if (!fun)
1.957 + return NULL;
1.958 + }
1.959 +
1.960 + Scope *scope = enterScope(Scope::FUNCTION);
1.961 + if (!scope)
1.962 + return NULL;
1.963 +
1.964 + ParameterList *parameters = new (pool_) ParameterList();
1.965 +
1.966 + if (!expect(TOK_LPAREN))
1.967 + return NULL;
1.968 + if (!match(TOK_RPAREN)) {
1.969 + while (true) {
1.970 + bool isConst = match(TOK_CONST);
1.971 + bool ref = match(TOK_AMPERSAND);
1.972 +
1.973 + SourcePosition begin = scanner_.begin();
1.974 + Local<String> tag(zone_);
1.975 + if (matchName(tag.ref(), TOK_LABEL) && !tag)
1.976 + return NULL;
1.977 +
1.978 + if (match(TOK_ELLIPSES)) {
1.979 + if (isConst || ref) {
1.980 + cc_.reportError(begin, Message_InvalidVarArgs);
1.981 + return NULL;
1.982 + }
1.983 +
1.984 + if (token != TOK_NATIVE) {
1.985 + cc_.reportError(begin, Message_VarArgsOutsideNative);
1.986 + return NULL;
1.987 + }
1.988 +
1.989 + fun->markNativeVariadic();
1.990 + break;
1.991 + }
1.992 +
1.993 + Local<String> name(zone_, expectName());
1.994 + if (!name)
1.995 + return NULL;
1.996 +
1.997 + if (BoundName *other = scope_->localLookup(name)) {
1.998 + redeclarationError(other);
1.999 + return NULL;
1.1000 + }
1.1001 + Variable *arg = scope_->declareArgument(name, scanner_.begin());
1.1002 + if (!arg)
1.1003 + return NULL;
1.1004 +
1.1005 + // Look for dimensions.
1.1006 + ExpressionList *postDimensions = NULL;
1.1007 + while (match(TOK_LBRACKET)) {
1.1008 + if (!postDimensions)
1.1009 + postDimensions = new (pool_) ExpressionList();
1.1010 +
1.1011 + Expression *dim = NULL;
1.1012 + if (!match(TOK_RBRACKET)) {
1.1013 + if ((dim = expression()) == NULL)
1.1014 + return NULL;
1.1015 + if (!expect(TOK_RBRACKET))
1.1016 + return NULL;
1.1017 + }
1.1018 +
1.1019 + if (!postDimensions->append(dim))
1.1020 + return NULL;
1.1021 + }
1.1022 +
1.1023 + Parameter *parameter = new (pool_) Parameter(arg, tag, ref, isConst, postDimensions);
1.1024 + if (!parameters->append(parameter))
1.1025 + return NULL;
1.1026 +
1.1027 + if (!match(TOK_COMMA))
1.1028 + break;
1.1029 + }
1.1030 + if (!expect(TOK_RPAREN))
1.1031 + return NULL;
1.1032 + }
1.1033 +
1.1034 + encounteredReturn_ = false;
1.1035 +
1.1036 + Statement *body = NULL;
1.1037 + if (token != TOK_FORWARD && token != TOK_NATIVE) {
1.1038 + body = block();
1.1039 + if (!body)
1.1040 + return NULL;
1.1041 + }
1.1042 +
1.1043 + scope_ = scope_->enclosing();
1.1044 + return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, encounteredReturn_);
1.1045 +}
1.1046 +
1.1047 +ParseTree *
1.1048 +Parser::parse()
1.1049 +{
1.1050 + StatementList *statements = new (pool_) StatementList();
1.1051 +
1.1052 + if (!enterScope(Scope::GLOBAL))
1.1053 + return NULL;
1.1054 +
1.1055 + for (;;) {
1.1056 + Statement *statement = NULL;
1.1057 +
1.1058 + switch (scanner_.peek()) {
1.1059 + case TOK_ERROR:
1.1060 + return NULL;
1.1061 +
1.1062 + case TOK_EOF:
1.1063 + break;
1.1064 +
1.1065 + case TOK_NAME:
1.1066 + if ((statement = function(TOK_NAME)) == NULL)
1.1067 + return NULL;
1.1068 + break;
1.1069 +
1.1070 + case TOK_FORWARD:
1.1071 + case TOK_PUBLIC:
1.1072 + case TOK_NATIVE:
1.1073 + {
1.1074 + TokenKind kind = scanner_.scan();
1.1075 + if ((statement = function(kind)) == NULL)
1.1076 + return NULL;
1.1077 + if ((kind == TOK_FORWARD || kind == TOK_NATIVE) && !matchSemicolon())
1.1078 + return NULL;
1.1079 + break;
1.1080 + }
1.1081 +
1.1082 + case TOK_NEW:
1.1083 + {
1.1084 + if ((statement = variableDeclaration()) == NULL)
1.1085 + return NULL;
1.1086 + if (!matchSemicolon())
1.1087 + return NULL;
1.1088 + break;
1.1089 + }
1.1090 +
1.1091 + case TOK_ENUM:
1.1092 + if ((statement = enum_()) == NULL)
1.1093 + return NULL;
1.1094 + if (!matchSemicolon())
1.1095 + return NULL;
1.1096 + break;
1.1097 +
1.1098 + default:
1.1099 + cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
1.1100 + return NULL;
1.1101 + }
1.1102 +
1.1103 + if (!statement)
1.1104 + break;
1.1105 +
1.1106 + if (!statements->append(statement))
1.1107 + return NULL;
1.1108 + }
1.1109 +
1.1110 + return new (pool_) ParseTree(scope_, statements, unbound_);
1.1111 +}
1.1112 +
1.1113 +class AstPrinter : public AstVisitor
1.1114 +{
1.1115 + FILE *fp_;
1.1116 + size_t level_;
1.1117 +
1.1118 + private:
1.1119 + void prefix() {
1.1120 + for (size_t i = 0; i < level_; i++)
1.1121 + fprintf(fp_, " ");
1.1122 + }
1.1123 + void indent() {
1.1124 + level_++;
1.1125 + }
1.1126 + void unindent() {
1.1127 + level_--;
1.1128 + }
1.1129 +
1.1130 + public:
1.1131 + AstPrinter(FILE *fp)
1.1132 + : fp_(fp),
1.1133 + level_(0)
1.1134 + {
1.1135 + }
1.1136 +
1.1137 + void visit(NameProxy *name) {
1.1138 + prefix();
1.1139 + fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
1.1140 + (name->binding() ? "" : " unbound"));
1.1141 + }
1.1142 + void visit(CallExpression *node) {
1.1143 + prefix();
1.1144 + fprintf(fp_, "[ CallExpression\n");
1.1145 + indent();
1.1146 + node->callee()->accept(this);
1.1147 + for (size_t i = 0; i < node->arguments()->length(); i++)
1.1148 + node->arguments()->at(i)->accept(this);
1.1149 + unindent();
1.1150 + }
1.1151 + void visit(FunctionStatement *node) {
1.1152 + prefix();
1.1153 + fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
1.1154 + indent();
1.1155 + if (node->body())
1.1156 + node->body()->accept(this);
1.1157 + unindent();
1.1158 + }
1.1159 + void visit(ExpressionStatement *node) {
1.1160 + prefix();
1.1161 + fprintf(fp_, "[ ExpressionStatement\n");
1.1162 + indent();
1.1163 + node->expression()->accept(this);
1.1164 + unindent();
1.1165 + }
1.1166 + void visit(Assignment *node) {
1.1167 + prefix();
1.1168 + fprintf(fp_, "[ Assignment\n");
1.1169 + indent();
1.1170 + node->lvalue()->accept(this);
1.1171 + node->expression()->accept(this);
1.1172 + unindent();
1.1173 + }
1.1174 + void visit(TernaryExpression *node) {
1.1175 + prefix();
1.1176 + fprintf(fp_, "[ TernaryExpression\n");
1.1177 + indent();
1.1178 + node->condition()->accept(this);
1.1179 + node->left()->accept(this);
1.1180 + node->right()->accept(this);
1.1181 + unindent();
1.1182 + }
1.1183 + void visit(BinaryExpression *node) {
1.1184 + prefix();
1.1185 + fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
1.1186 + indent();
1.1187 + node->left()->accept(this);
1.1188 + node->right()->accept(this);
1.1189 + unindent();
1.1190 + }
1.1191 + void visit(UnaryExpression *node) {
1.1192 + prefix();
1.1193 + fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
1.1194 + indent();
1.1195 + node->expression()->accept(this);
1.1196 + unindent();
1.1197 + }
1.1198 + void visit(ReturnStatement *node) {
1.1199 + prefix();
1.1200 + fprintf(fp_, "[ ReturnStatement\n");
1.1201 + indent();
1.1202 + if (node->expression())
1.1203 + node->expression()->accept(this);
1.1204 + unindent();
1.1205 + }
1.1206 + void visit(ForStatement *node) {
1.1207 + prefix();
1.1208 + fprintf(fp_, "[ ForStatement\n");
1.1209 + indent();
1.1210 + if (node->initialization())
1.1211 + node->initialization()->accept(this);
1.1212 + if (node->condition())
1.1213 + node->condition()->accept(this);
1.1214 + if (node->update())
1.1215 + node->update()->accept(this);
1.1216 + node->body()->accept(this);
1.1217 + unindent();
1.1218 + }
1.1219 + void visit(BlockStatement *node) {
1.1220 + prefix();
1.1221 + fprintf(fp_, "[ BlockStatement\n");
1.1222 + indent();
1.1223 + for (size_t i = 0; i < node->statements()->length(); i++)
1.1224 + node->statements()->at(i)->accept(this);
1.1225 + unindent();
1.1226 + }
1.1227 + void visit(VariableDeclaration *node) {
1.1228 + prefix();
1.1229 + fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
1.1230 + indent();
1.1231 + if (node->initialization())
1.1232 + node->initialization()->accept(this);
1.1233 + unindent();
1.1234 + }
1.1235 + void visit(IntegerLiteral *node) {
1.1236 + prefix();
1.1237 + fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
1.1238 + }
1.1239 + void visit(FloatLiteral *node) {
1.1240 + prefix();
1.1241 + fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
1.1242 + }
1.1243 + void visit(IfStatement *node) {
1.1244 + prefix();
1.1245 + fprintf(fp_, "[ IfStatement\n");
1.1246 + indent();
1.1247 + node->ifTrue()->accept(this);
1.1248 + if (node->ifFalse())
1.1249 + node->ifFalse()->accept(this);
1.1250 + unindent();
1.1251 + }
1.1252 + void visit(IndexExpression *node) {
1.1253 + prefix();
1.1254 + fprintf(fp_, "[ IndexExpression\n");
1.1255 + indent();
1.1256 + node->left()->accept(this);
1.1257 + node->right()->accept(this);
1.1258 + unindent();
1.1259 + }
1.1260 + void visit(EnumStatement *node) {
1.1261 + prefix();
1.1262 + fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
1.1263 + indent();
1.1264 + for (size_t i = 0; i < node->entries()->length(); i++) {
1.1265 + prefix();
1.1266 + fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
1.1267 + if (node->entries()->at(i).expr) {
1.1268 + indent();
1.1269 + node->entries()->at(i).expr->accept(this);
1.1270 + unindent();
1.1271 + }
1.1272 + }
1.1273 + unindent();
1.1274 + }
1.1275 + void visit(WhileStatement *node) {
1.1276 + prefix();
1.1277 + fprintf(fp_, "[ WhileStatement (%s)\n",
1.1278 + (node->token() == TOK_DO) ? "do" : "while");
1.1279 + indent();
1.1280 + if (node->token() == TOK_DO) {
1.1281 + node->condition()->accept(this);
1.1282 + node->body()->accept(this);
1.1283 + } else {
1.1284 + node->condition()->accept(this);
1.1285 + node->body()->accept(this);
1.1286 + }
1.1287 + unindent();
1.1288 + }
1.1289 + void visit(BreakStatement *node) {
1.1290 + prefix();
1.1291 + fprintf(fp_, "[ BreakStatement\n");
1.1292 + }
1.1293 + void visit(ContinueStatement *node) {
1.1294 + prefix();
1.1295 + fprintf(fp_, "[ ContinueStatement\n");
1.1296 + }
1.1297 + void visit(StringLiteral *node) {
1.1298 + prefix();
1.1299 + fprintf(fp_, "[ StringLiteral\n");
1.1300 + }
1.1301 + void visit(IncDecExpression *node) {
1.1302 + prefix();
1.1303 + fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
1.1304 + indent();
1.1305 + node->expression()->accept(this);
1.1306 + unindent();
1.1307 + }
1.1308 +};
1.1309 +
1.1310 +void
1.1311 +ParseTree::dump(FILE *fp)
1.1312 +{
1.1313 + AstPrinter printer(fp);
1.1314 +
1.1315 + for (size_t i = 0; i < statements_->length(); i++)
1.1316 + statements_->at(i)->accept(&printer);
1.1317 +}