src/compiler/AST.h
author David Anderson <dvander@alliedmods.net>
Sat Nov 17 18:41:01 2012 -0800 (2012-11-17)
changeset 195 c1ba166f3fc4
parent 191 src/AST.h@9d17f29fe16a
child 196 9904633b1dfc
permissions -rw-r--r--
Massive SemA/BC refactoring to support better type systems. Read on for more.

The previous compiler had a simple pipeline, best outlined as:
(1) Parsing and name binding -> AST
(2) Storage allocation -> AST
(3) Semantic Analysis (SemA) -> AST
(4) Bytecode Compilation (BC) -> Code

This pipeline, unfortunately, had two problems. First, name binding cannot be performed in one pass if we wish to have multi-file support in the form of modules. Name binding must be two-pass.

Second, because SemA was only capable of annotating AST nodes with a single type, most coercion work had to be duplicated in the BC phase, as coercion was not explicit in the SemA output. This made introducing new type rules extremely difficult, and all but precluded concepts like operator overloading (or overloading at all).

This patch rewrites most of Keima's backend. Of interest are the following changes:
(1) CompileContext has been refactored around future multi-file support.
(2) Parsing no longer performs any name binding.
(3) The grammar for type-and-name has been changed from:
(Label | Identifier)? Identifier
to:
Type? Identifier
where:
Type ::= OldType | NewType
OldType ::= Label
NewType ::= Identifier (. NewType)*


Although we do not implement the full production for Type yet, this
distinction is important. A type identifier is now affixed to the AST
as an Expression (right now, always a NameProxy), so it can fully
participate in name binding.

(4) Immediately after parsing, the AST goes through a NamePopulation phase.
This phase creates Scope objects for every scope which declares a name,
and if those names are declaring types or functions, a Symbol is created
and entered into the scope. Symbols entirely replace the old BoundName
classes.

(5) After NamePopulation comes NameBinding. This phase performs three steps:
(a) Links Scope objects together, to form a tree.
(b) Binds any free name to an existing name in the scope chain.
(c) Creates and registers any Symbols for names which have not yet been
added to the scope (for example, local variables).

In accordance, all "allocation" and "binding" concepts have been removed
from Scopes, which are now lightweight container classes.

(6) SemA now generates bytecode for each statement in the AST. Expression
compilation is performed via a separate mechanism called HIR (High-level
Intermediate Representation). To analyze an expression, SemA will walk
the AST, and produce a HIR object for each node. HIR is typed, and SemA
may insert coercion nodes, or even expand an AST node into multiple HIR
nodes. The result of evaluating an expression in SemA is therefore the
the root of a HIR tree, which SemA then sends to the HIRTranslator, which
performs bytecode generation.

As before, SemA still performs full semantic analysis. However, not it
also produces each function's bytecode.

This split allows us to decompose potentially complex semantics into
a more fine-grained, AST-like structure, which can have very simple
code-generation logic. For example, (1.0 + 5) might look like:

HAdd(HFloat(1.0), HConvert(HInteger(5), <Float>))

As part of this decomposition, many opcodes have been removed. Rather than
using typed jumps, we now expand jumps into longer tests. For example:
jge.f <label>
becomes:
ge.f
cvt.f2b
jt <label>

This simplifies the pipeline, and JITs should be able to melt the added
work away.

HIR is not used at a statement level, and HIR does not have any concept
of control-flow.

(7) The old BytecodeCompiler has been removed, as its work is now split
between SemA and HIRTranslator.


In addition, some minor refactorings have taken place:

(1) Opcodes.tbl no longer hardcodes numbers (aaah).
(2) Type has been split into smaller, typed structs.
(3) BytecodeEmitter no longer relies on Pools or RootScopes.
(4) SemA is now responsible for variable/storage allocation.
(5) Native table are now global, rather than per-module. As such, native
declarations now result in a Native object (which still requires a
CALLNATIVE opcode), which is an index into the global table. Natives
must be bound globally. This is in preparation for module support.
(6) Publics are no longer tracked, but rather registered via a global
callback upon module load. This callback can be set by embedders. This
is in preparation for multi-file support.
(7) The BytecodeEmitter now performs Symbol allocations itself, and it
also generates Code objects itself, which removes a good deal of
complexity.

Finally, a test harness has been added. This harness is a python script which finds *.test files, recursively, in the tests folder. For each file it runs the corresponding .sp. The contents of the .test file must match stdout+stderr.
dvander@132
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@132
     2
 *
dvander@0
     3
 * Copyright (C) 2012 David Anderson
dvander@0
     4
 *
dvander@132
     5
 * This file is part of SourcePawn.
dvander@0
     6
 *
dvander@132
     7
 * SourcePawn is free software: you can redistribute it and/or modify it under
dvander@0
     8
 * the terms of the GNU General Public License as published by the Free
dvander@0
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@0
    10
 * any later version.
dvander@0
    11
 * 
dvander@132
    12
 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@0
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@0
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@0
    15
 *
dvander@0
    16
 * You should have received a copy of the GNU General Public License along with
dvander@132
    17
 * SourcePawn. If not, see http://www.gnu.org/licenses/.
dvander@0
    18
 */
dvander@168
    19
#ifndef _include_sourcepawn_ast_h_
dvander@168
    20
#define _include_sourcepawn_ast_h_
dvander@0
    21
dvander@195
    22
#include "../PoolAllocator.h"
dvander@195
    23
#include "../Vector.h"
dvander@0
    24
#include "Token.h"
dvander@0
    25
#include "NameBinding.h"
dvander@195
    26
#include "Symbols.h"
dvander@195
    27
#include "../QualType.h"
dvander@0
    28
dvander@59
    29
namespace ke {
dvander@0
    30
dvander@195
    31
class Scope;
dvander@195
    32
dvander@0
    33
#define ASTKINDS(_)             \
dvander@0
    34
    _(VariableDeclaration)      \
dvander@0
    35
    _(ForStatement)             \
dvander@0
    36
    _(ReturnStatement)          \
dvander@4
    37
    _(IntegerLiteral)           \
dvander@4
    38
    _(FloatLiteral)             \
dvander@21
    39
    _(StringLiteral)            \
dvander@0
    40
    _(BinaryExpression)         \
dvander@0
    41
    _(BlockStatement)           \
dvander@0
    42
    _(Assignment)               \
dvander@0
    43
    _(NameProxy)                \
dvander@0
    44
    _(ExpressionStatement)      \
dvander@0
    45
    _(FunctionStatement)        \
dvander@0
    46
    _(CallExpression)           \
dvander@0
    47
    _(IfStatement)              \
dvander@2
    48
    _(IndexExpression)          \
dvander@148
    49
    _(FieldExpression)          \
dvander@9
    50
    _(EnumStatement)            \
dvander@10
    51
    _(WhileStatement)           \
dvander@10
    52
    _(BreakStatement)           \
dvander@23
    53
    _(ContinueStatement)        \
dvander@174
    54
    _(FunctionTypeStatement)    \
dvander@78
    55
    _(IncDecExpression)         \
dvander@83
    56
    _(UnaryExpression)          \
dvander@143
    57
    _(TernaryExpression)        \
dvander@146
    58
    _(BooleanLiteral)           \
dvander@172
    59
    _(StructureStatement)       \
dvander@187
    60
    _(SwitchStatement)          \
dvander@195
    61
    _(ArrayLiteral)             \
dvander@195
    62
	_(ImportStatement)
dvander@0
    63
dvander@0
    64
// Forward declarations.
dvander@0
    65
#define _(name) class name;
dvander@0
    66
ASTKINDS(_)
dvander@0
    67
#undef _
dvander@0
    68
dvander@0
    69
class AstVisitor;
dvander@0
    70
dvander@0
    71
// Interface for AST nodes.
dvander@0
    72
class AstNode : public PoolObject
dvander@0
    73
{
dvander@25
    74
    SourcePosition pos_;
dvander@25
    75
dvander@0
    76
  public:
dvander@0
    77
    enum Kind {
dvander@0
    78
#       define _(name) k##name,
dvander@0
    79
        ASTKINDS(_)
dvander@0
    80
#       undef _
dvander@0
    81
        AstKind_Invalid
dvander@0
    82
    };
dvander@25
    83
dvander@25
    84
    AstNode(const SourcePosition &pos)
dvander@25
    85
      : pos_(pos)
dvander@25
    86
    {
dvander@25
    87
    }
dvander@0
    88
    
dvander@0
    89
    virtual Kind kind() const = 0;
dvander@0
    90
dvander@0
    91
#define _(name)     bool is##name() { return kind() == k##name; }                   \
dvander@187
    92
                    name *to##name() { assert(is##name()); return (name *)this; }   \
dvander@187
    93
                    name *as##name() { if (!is##name()) return NULL; return to##name(); }
dvander@0
    94
    ASTKINDS(_)
dvander@0
    95
#undef _
dvander@0
    96
dvander@0
    97
    virtual void accept(AstVisitor *visitor) = 0;
dvander@25
    98
dvander@25
    99
    const SourcePosition &pos() const {
dvander@25
   100
        return pos_;
dvander@25
   101
    }
dvander@0
   102
};
dvander@0
   103
dvander@195
   104
#define DECLARE_NODE(type)                      \
dvander@195
   105
    Kind kind() const {                         \
dvander@195
   106
        return k##type;                         \
dvander@195
   107
    }                                           \
dvander@195
   108
    void accept(AstVisitor *visitor) {          \
dvander@195
   109
        visitor->visit##type(this);             \
dvander@195
   110
    }
dvander@195
   111
dvander@0
   112
class AstVisitor
dvander@0
   113
{
dvander@0
   114
  public:
dvander@195
   115
#define _(name) virtual void visit##name(name *node) { assert(false); }
dvander@0
   116
    ASTKINDS(_)
dvander@0
   117
#undef _
dvander@0
   118
};
dvander@0
   119
dvander@0
   120
class Statement : public AstNode
dvander@0
   121
{
dvander@25
   122
  public:
dvander@25
   123
    Statement(const SourcePosition &pos)
dvander@25
   124
      : AstNode(pos)
dvander@25
   125
    {
dvander@25
   126
    }
dvander@0
   127
};
dvander@0
   128
dvander@0
   129
class Expression : public AstNode
dvander@0
   130
{
dvander@29
   131
    ScopedRoot<Type> type_;
dvander@0
   132
dvander@0
   133
  public:
dvander@25
   134
    Expression(const SourcePosition &pos)
dvander@25
   135
      : AstNode(pos),
dvander@25
   136
        type_(NULL)
dvander@0
   137
    {
dvander@0
   138
    }
dvander@0
   139
dvander@0
   140
    void setType(Type *type) {
dvander@0
   141
        type_ = type;
dvander@0
   142
    }
dvander@0
   143
    Type *type() const {
dvander@0
   144
        return type_;
dvander@0
   145
    }
dvander@0
   146
};
dvander@0
   147
dvander@0
   148
typedef PoolList<Statement *> StatementList;
dvander@56
   149
typedef PoolList<Expression *> ExpressionList;
dvander@0
   150
dvander@25
   151
class VariableDeclaration : public Statement
dvander@0
   152
{
dvander@195
   153
    TypeQualifiers qual_;
dvander@195
   154
    ScopedRoot<String> name_;
dvander@0
   155
    Expression *initialization_;
dvander@195
   156
    Expression *type_;
dvander@195
   157
    VariableSymbol *sym_;
dvander@0
   158
dvander@0
   159
  public:
dvander@195
   160
    VariableDeclaration(const SourcePosition &pos, TypeQualifiers qual, Handle<String> name,
dvander@195
   161
                        Expression *type, Expression *initialization)
dvander@25
   162
      : Statement(pos),
dvander@195
   163
        qual_(qual),
dvander@195
   164
        name_(name),
dvander@28
   165
        initialization_(initialization),
dvander@145
   166
        type_(type),
dvander@195
   167
        sym_(NULL)
dvander@0
   168
    {
dvander@0
   169
    }
dvander@0
   170
dvander@195
   171
    DECLARE_NODE(VariableDeclaration);
dvander@195
   172
dvander@0
   173
    Expression *initialization() const {
dvander@0
   174
        return initialization_;
dvander@0
   175
    }
dvander@195
   176
    Handle<String> name() {
dvander@195
   177
        return name_;
dvander@195
   178
    }
dvander@195
   179
    Expression *declType() const {
dvander@195
   180
        return type_;
dvander@0
   181
    }
dvander@195
   182
    void setSymbol(VariableSymbol *sym) {
dvander@195
   183
        assert(!sym_);
dvander@195
   184
        sym_ = sym;
dvander@0
   185
    }
dvander@195
   186
    VariableSymbol *sym() const {
dvander@195
   187
        return sym_;
dvander@195
   188
    }
dvander@195
   189
    Expression *type() const {
dvander@195
   190
        return type_;
dvander@135
   191
    }
dvander@0
   192
};
dvander@0
   193
dvander@14
   194
class Parameter : public PoolObject
dvander@14
   195
{
dvander@195
   196
    ScopedRoot<String> name_;
dvander@195
   197
    Expression *type_;
dvander@14
   198
    bool reference_;
dvander@67
   199
    bool const_;
dvander@133
   200
    Expression *initializer_;
dvander@195
   201
    VariableSymbol *sym_;
dvander@195
   202
    SourcePosition pos_;
dvander@14
   203
dvander@14
   204
  public:
dvander@195
   205
    Parameter(Handle<String> name, Expression *type, bool reference, bool isConst,
dvander@195
   206
              Expression *initializer, const SourcePosition &pos)
dvander@195
   207
      : name_(name),
dvander@145
   208
        type_(type),
dvander@66
   209
        reference_(reference),
dvander@67
   210
        const_(isConst),
dvander@195
   211
        initializer_(initializer),
dvander@195
   212
        sym_(NULL),
dvander@195
   213
        pos_(pos)
dvander@14
   214
    {
dvander@14
   215
    }
dvander@14
   216
dvander@195
   217
    Expression *type() const {
dvander@145
   218
        return type_;
dvander@14
   219
    }
dvander@195
   220
    Handle<String> name() const {
dvander@195
   221
        return name_;
dvander@14
   222
    }
dvander@14
   223
    bool reference() const {
dvander@14
   224
        return reference_;
dvander@14
   225
    }
dvander@67
   226
    bool isConst() const {
dvander@67
   227
        return const_;
dvander@67
   228
    }
dvander@133
   229
    Expression *initializer() const {
dvander@133
   230
        return initializer_;
dvander@133
   231
    }
dvander@195
   232
    void setSymbol(VariableSymbol *sym) {
dvander@195
   233
        assert(!sym_);
dvander@195
   234
        sym_ = sym;
dvander@195
   235
    }
dvander@195
   236
    VariableSymbol *sym() const {
dvander@195
   237
        return sym_;
dvander@195
   238
    }
dvander@195
   239
    const SourcePosition &pos() const {
dvander@195
   240
        return pos_;
dvander@195
   241
    }
dvander@14
   242
};
dvander@14
   243
dvander@0
   244
class NameProxy : public Expression
dvander@0
   245
{
dvander@54
   246
    ScopedRoot<String> name_;
dvander@195
   247
    Symbol *binding_;
dvander@0
   248
dvander@0
   249
  public:
dvander@195
   250
    NameProxy(const SourcePosition &pos, Handle<String> name)
dvander@25
   251
      : Expression(pos),
dvander@25
   252
        name_(name),
dvander@195
   253
        binding_(NULL)
dvander@0
   254
    {
dvander@0
   255
    }
dvander@0
   256
dvander@195
   257
    DECLARE_NODE(NameProxy);
dvander@195
   258
    
dvander@195
   259
    Handle<String> name() const {
dvander@0
   260
        return name_;
dvander@0
   261
    }
dvander@195
   262
    Symbol *sym() const {
dvander@0
   263
        return binding_;
dvander@0
   264
    }
dvander@195
   265
    void bind(Symbol *sym) {
dvander@195
   266
        binding_ = sym;
dvander@0
   267
    }
dvander@0
   268
};
dvander@0
   269
dvander@143
   270
class BooleanLiteral : public Expression
dvander@143
   271
{
dvander@143
   272
    TokenKind token_;
dvander@143
   273
dvander@143
   274
  public:
dvander@143
   275
    BooleanLiteral(const SourcePosition &pos, TokenKind token)
dvander@143
   276
      : Expression(pos),
dvander@143
   277
        token_(token)
dvander@143
   278
    {
dvander@143
   279
    }
dvander@143
   280
dvander@195
   281
    DECLARE_NODE(BooleanLiteral);
dvander@143
   282
    TokenKind token() const {
dvander@143
   283
        return token_;
dvander@143
   284
    }
dvander@143
   285
};
dvander@143
   286
dvander@4
   287
class IntegerLiteral : public Expression
dvander@0
   288
{
dvander@0
   289
    int value_;
dvander@0
   290
dvander@0
   291
  public:
dvander@25
   292
    IntegerLiteral(const SourcePosition &pos, int value)
dvander@25
   293
      : Expression(pos),
dvander@25
   294
        value_(value)
dvander@0
   295
    {
dvander@0
   296
    }
dvander@0
   297
dvander@195
   298
    DECLARE_NODE(IntegerLiteral);
dvander@195
   299
dvander@0
   300
    int value() const {
dvander@0
   301
        return value_;
dvander@0
   302
    }
dvander@0
   303
};
dvander@0
   304
dvander@4
   305
class FloatLiteral : public Expression
dvander@4
   306
{
dvander@4
   307
    double value_;
dvander@4
   308
dvander@4
   309
  public:
dvander@25
   310
    FloatLiteral(const SourcePosition &pos, double value)
dvander@25
   311
      : Expression(pos),
dvander@25
   312
        value_(value)
dvander@4
   313
    {
dvander@4
   314
    }
dvander@4
   315
dvander@195
   316
    DECLARE_NODE(FloatLiteral);
dvander@195
   317
dvander@4
   318
    double value() const {
dvander@4
   319
        return value_;
dvander@4
   320
    }
dvander@4
   321
};
dvander@4
   322
dvander@21
   323
class StringLiteral : public Expression
dvander@21
   324
{
dvander@29
   325
    ScopedRoot<ByteArray> string_;
dvander@21
   326
dvander@21
   327
  public:
dvander@25
   328
    StringLiteral(const SourcePosition &pos, ByteArray *array)
dvander@25
   329
      : Expression(pos),
dvander@25
   330
        string_(array)
dvander@21
   331
    {
dvander@21
   332
    }
dvander@21
   333
dvander@195
   334
    DECLARE_NODE(StringLiteral);
dvander@195
   335
dvander@21
   336
    ByteArray *string() const {
dvander@21
   337
        return string_;
dvander@21
   338
    }
dvander@21
   339
};
dvander@21
   340
dvander@187
   341
class ArrayLiteral : public Expression
dvander@187
   342
{
dvander@187
   343
    TokenKind token_;
dvander@187
   344
    ExpressionList *expressions_;
dvander@187
   345
dvander@187
   346
  public:
dvander@187
   347
    ArrayLiteral(const SourcePosition &pos, TokenKind token, ExpressionList *expressions)
dvander@187
   348
      : Expression(pos),
dvander@187
   349
        token_(token),
dvander@187
   350
        expressions_(expressions)
dvander@187
   351
    {
dvander@187
   352
    }
dvander@187
   353
dvander@195
   354
    DECLARE_NODE(ArrayLiteral);
dvander@195
   355
dvander@187
   356
    TokenKind token() const {
dvander@187
   357
        return token_;
dvander@187
   358
    }
dvander@187
   359
    ExpressionList *expressions() const {
dvander@187
   360
        return expressions_;
dvander@187
   361
    }
dvander@187
   362
    bool isFixed() const {
dvander@187
   363
        return token_ == TOK_LBRACE;
dvander@187
   364
    }
dvander@187
   365
};
dvander@187
   366
dvander@78
   367
class UnaryExpression : public Expression
dvander@78
   368
{
dvander@78
   369
    Expression *expression_;
dvander@78
   370
    TokenKind token_;
dvander@195
   371
    NameProxy *tag_;
dvander@78
   372
dvander@78
   373
  public:
dvander@78
   374
    UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr)
dvander@78
   375
      : Expression(pos),
dvander@78
   376
        expression_(expr),
dvander@195
   377
        token_(token),
dvander@195
   378
        tag_(NULL)
dvander@78
   379
    {
dvander@78
   380
    }
dvander@78
   381
dvander@142
   382
    UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr,
dvander@195
   383
                    NameProxy *tag)
dvander@142
   384
      : Expression(pos),
dvander@142
   385
        expression_(expr),
dvander@142
   386
        token_(token),
dvander@195
   387
        tag_(tag)
dvander@142
   388
    {
dvander@142
   389
    }
dvander@142
   390
dvander@195
   391
    DECLARE_NODE(UnaryExpression);
dvander@195
   392
dvander@78
   393
    Expression *expression() const {
dvander@78
   394
        return expression_;
dvander@78
   395
    }
dvander@78
   396
    TokenKind token() const {
dvander@78
   397
        return token_;
dvander@78
   398
    }
dvander@195
   399
    NameProxy *tag() const {
dvander@195
   400
        return tag_;
dvander@78
   401
    }
dvander@78
   402
};
dvander@78
   403
dvander@0
   404
class BinaryExpression : public Expression
dvander@0
   405
{
dvander@0
   406
    Expression *left_;
dvander@0
   407
    Expression *right_;
dvander@0
   408
    TokenKind token_;
dvander@0
   409
dvander@0
   410
  public:
dvander@25
   411
    BinaryExpression(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
dvander@25
   412
      : Expression(pos),
dvander@0
   413
        left_(left),
dvander@28
   414
        right_(right),
dvander@28
   415
        token_(token)
dvander@0
   416
    {
dvander@0
   417
    }
dvander@0
   418
dvander@195
   419
    DECLARE_NODE(BinaryExpression);
dvander@195
   420
dvander@0
   421
    Expression *left() const {
dvander@0
   422
        return left_;
dvander@0
   423
    }
dvander@0
   424
    Expression *right() const {
dvander@0
   425
        return right_;
dvander@0
   426
    }
dvander@0
   427
    TokenKind token() const {
dvander@0
   428
        return token_;
dvander@0
   429
    }
dvander@0
   430
};
dvander@0
   431
dvander@83
   432
class TernaryExpression : public Expression
dvander@83
   433
{
dvander@83
   434
    Expression *condition_;
dvander@83
   435
    Expression *left_;
dvander@83
   436
    Expression *right_;
dvander@83
   437
dvander@83
   438
  public:
dvander@83
   439
    TernaryExpression(const SourcePosition &pos, Expression *condition, Expression *left, Expression *right)
dvander@83
   440
      : Expression(pos),
dvander@83
   441
        condition_(condition),
dvander@83
   442
        left_(left),
dvander@83
   443
        right_(right)
dvander@83
   444
    {
dvander@83
   445
    }
dvander@83
   446
dvander@195
   447
    DECLARE_NODE(TernaryExpression);
dvander@195
   448
dvander@83
   449
    Expression *condition() const {
dvander@83
   450
        return condition_;
dvander@83
   451
    }
dvander@83
   452
    Expression *left() const {
dvander@83
   453
        return left_;
dvander@83
   454
    }
dvander@83
   455
    Expression *right() const {
dvander@83
   456
        return right_;
dvander@83
   457
    }
dvander@83
   458
};
dvander@83
   459
dvander@0
   460
class IndexExpression : public Expression
dvander@0
   461
{
dvander@0
   462
    Expression *left_;
dvander@0
   463
    Expression *right_;
dvander@0
   464
dvander@0
   465
  public:
dvander@25
   466
    IndexExpression(const SourcePosition &pos, Expression *left, Expression *right)
dvander@25
   467
      : Expression(pos),
dvander@25
   468
        left_(left),
dvander@0
   469
        right_(right)
dvander@0
   470
    {
dvander@0
   471
    }
dvander@0
   472
dvander@195
   473
    DECLARE_NODE(IndexExpression);
dvander@195
   474
dvander@0
   475
    Expression *left() const {
dvander@0
   476
        return left_;
dvander@0
   477
    }
dvander@0
   478
    Expression *right() const {
dvander@0
   479
        return right_;
dvander@0
   480
    }
dvander@0
   481
};
dvander@0
   482
dvander@148
   483
class FieldExpression : public Expression
dvander@148
   484
{
dvander@148
   485
    Expression *left_;
dvander@148
   486
    ScopedRoot<String> field_;
dvander@148
   487
    unsigned fieldIndex_;
dvander@148
   488
dvander@148
   489
  public:
dvander@148
   490
    FieldExpression(const SourcePosition &pos, Expression *left, Handle<String> field)
dvander@148
   491
      : Expression(pos),
dvander@148
   492
        left_(left),
dvander@148
   493
        field_(field),
dvander@148
   494
        fieldIndex_(unsigned(-1))
dvander@148
   495
    {
dvander@148
   496
    }
dvander@148
   497
dvander@195
   498
    DECLARE_NODE(FieldExpression);
dvander@195
   499
dvander@148
   500
    Expression *left() const {
dvander@148
   501
        return left_;
dvander@148
   502
    }
dvander@148
   503
    String *field() const {
dvander@148
   504
        return field_;
dvander@148
   505
    }
dvander@148
   506
    void setFieldIndex(unsigned index) {
dvander@148
   507
        assert(fieldIndex_ == unsigned(-1));
dvander@148
   508
        fieldIndex_ = index;
dvander@148
   509
    }
dvander@148
   510
    unsigned fieldIndex() const {
dvander@148
   511
        assert(fieldIndex_ != unsigned(-1));
dvander@148
   512
        return fieldIndex_;
dvander@148
   513
    }
dvander@148
   514
};
dvander@148
   515
dvander@0
   516
class CallExpression : public Expression
dvander@0
   517
{
dvander@0
   518
    Expression *callee_;
dvander@0
   519
    ExpressionList *arguments_;
dvander@0
   520
dvander@0
   521
  public:
dvander@25
   522
    CallExpression(const SourcePosition &pos, Expression *callee, ExpressionList *arguments)
dvander@25
   523
      : Expression(pos),
dvander@25
   524
        callee_(callee),
dvander@0
   525
        arguments_(arguments)
dvander@0
   526
    {
dvander@0
   527
    }
dvander@0
   528
dvander@195
   529
    DECLARE_NODE(CallExpression);
dvander@195
   530
dvander@0
   531
    Expression *callee() const {
dvander@0
   532
        return callee_;
dvander@0
   533
    }
dvander@0
   534
    ExpressionList *arguments() const {
dvander@0
   535
        return arguments_;
dvander@0
   536
    }
dvander@0
   537
};
dvander@0
   538
dvander@0
   539
class ForStatement : public Statement
dvander@0
   540
{
dvander@22
   541
    Statement *initialization_;
dvander@0
   542
    Expression *condition_;
dvander@0
   543
    Statement *update_;
dvander@0
   544
    Statement *body_;
dvander@195
   545
    Scope *scope_;
dvander@0
   546
dvander@0
   547
  public:
dvander@195
   548
    ForStatement(const SourcePosition &pos, Statement *initialization,
dvander@0
   549
                 Expression *condition, Statement *update, Statement *body)
dvander@25
   550
      : Statement(pos),
dvander@22
   551
        initialization_(initialization),
dvander@0
   552
        condition_(condition),
dvander@0
   553
        update_(update),
dvander@195
   554
        body_(body),
dvander@195
   555
        scope_(NULL)
dvander@0
   556
    {
dvander@0
   557
    }
dvander@0
   558
dvander@195
   559
    DECLARE_NODE(ForStatement);
dvander@195
   560
dvander@22
   561
    Statement *initialization() const {
dvander@22
   562
        return initialization_;
dvander@0
   563
    }
dvander@0
   564
    Expression *condition() const {
dvander@0
   565
        return condition_;
dvander@0
   566
    }
dvander@0
   567
    Statement *update() const {
dvander@0
   568
        return update_;
dvander@0
   569
    }
dvander@0
   570
    Statement *body() const {
dvander@0
   571
        return body_;
dvander@0
   572
    }
dvander@195
   573
    Scope *scope() const {
dvander@195
   574
        return scope_;
dvander@195
   575
    }
dvander@195
   576
    void setScope(Scope *scope) {
dvander@195
   577
        scope_ = scope;
dvander@0
   578
    }
dvander@0
   579
};
dvander@0
   580
dvander@9
   581
class WhileStatement : public Statement
dvander@9
   582
{
dvander@9
   583
    TokenKind token_;
dvander@9
   584
    Expression *condition_;
dvander@9
   585
    Statement *body_;
dvander@9
   586
dvander@9
   587
  public:
dvander@25
   588
    WhileStatement(const SourcePosition &pos, TokenKind kind, Expression *condition, Statement *body)
dvander@25
   589
      : Statement(pos),
dvander@25
   590
        token_(kind),
dvander@9
   591
        condition_(condition),
dvander@9
   592
        body_(body)
dvander@9
   593
    {
dvander@9
   594
    }
dvander@9
   595
    
dvander@195
   596
    DECLARE_NODE(WhileStatement);
dvander@195
   597
dvander@9
   598
    TokenKind token() const {
dvander@9
   599
        return token_;
dvander@9
   600
    }
dvander@9
   601
    Expression *condition() const {
dvander@9
   602
        return condition_;
dvander@9
   603
    }
dvander@9
   604
    Statement *body() const {
dvander@9
   605
        return body_;
dvander@9
   606
    }
dvander@9
   607
};
dvander@9
   608
dvander@0
   609
class ReturnStatement : public Statement
dvander@0
   610
{
dvander@0
   611
    Expression *expression_;
dvander@0
   612
dvander@0
   613
  public:
dvander@25
   614
    ReturnStatement(const SourcePosition &pos, Expression *expression)
dvander@25
   615
      : Statement(pos),
dvander@25
   616
        expression_(expression)
dvander@0
   617
    {
dvander@0
   618
    }
dvander@0
   619
dvander@195
   620
    DECLARE_NODE(ReturnStatement);
dvander@195
   621
dvander@0
   622
    Expression *expression() const {
dvander@0
   623
        return expression_;
dvander@0
   624
    }
dvander@0
   625
};
dvander@0
   626
dvander@10
   627
class BreakStatement : public Statement
dvander@10
   628
{
dvander@10
   629
  public:
dvander@25
   630
    BreakStatement(const SourcePosition &pos)
dvander@25
   631
      : Statement(pos)
dvander@10
   632
    {
dvander@10
   633
    }
dvander@10
   634
dvander@195
   635
    DECLARE_NODE(BreakStatement);
dvander@10
   636
};
dvander@10
   637
dvander@10
   638
class ContinueStatement : public Statement
dvander@10
   639
{
dvander@10
   640
  public:
dvander@25
   641
    ContinueStatement(const SourcePosition &pos)
dvander@25
   642
      : Statement(pos)
dvander@10
   643
    {
dvander@10
   644
    }
dvander@10
   645
dvander@195
   646
    DECLARE_NODE(ContinueStatement);
dvander@10
   647
};
dvander@10
   648
dvander@0
   649
class Assignment : public Expression
dvander@0
   650
{
dvander@22
   651
    TokenKind token_;
dvander@0
   652
    Expression *lvalue_;
dvander@0
   653
    Expression *expression_;
dvander@0
   654
dvander@0
   655
  public:
dvander@25
   656
    Assignment(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
dvander@25
   657
      : Expression(pos),
dvander@25
   658
        token_(token),
dvander@22
   659
        lvalue_(left),
dvander@0
   660
        expression_(right)
dvander@0
   661
    {
dvander@0
   662
    }
dvander@0
   663
dvander@195
   664
    DECLARE_NODE(Assignment);
dvander@195
   665
dvander@22
   666
    TokenKind token() const {
dvander@22
   667
        return token_;
dvander@22
   668
    }
dvander@0
   669
    Expression *lvalue() const {
dvander@0
   670
        return lvalue_;
dvander@0
   671
    }
dvander@0
   672
    Expression *expression() const {
dvander@0
   673
        return expression_;
dvander@0
   674
    }
dvander@0
   675
};
dvander@0
   676
dvander@0
   677
class ExpressionStatement : public Statement
dvander@0
   678
{
dvander@0
   679
    Expression *expression_;
dvander@0
   680
dvander@0
   681
  public:
dvander@0
   682
    ExpressionStatement(Expression *expression)
dvander@25
   683
      : Statement(expression->pos()),
dvander@25
   684
        expression_(expression)
dvander@0
   685
    {
dvander@0
   686
    }
dvander@0
   687
dvander@195
   688
    DECLARE_NODE(ExpressionStatement);
dvander@195
   689
dvander@0
   690
    Expression *expression() const {
dvander@0
   691
        return expression_;
dvander@0
   692
    }
dvander@0
   693
};
dvander@0
   694
dvander@0
   695
class BlockStatement : public Statement
dvander@0
   696
{
dvander@195
   697
    StatementList *statements_;
dvander@0
   698
    Scope *scope_;
dvander@0
   699
dvander@0
   700
  public:
dvander@195
   701
    BlockStatement(const SourcePosition &pos, StatementList *statements)
dvander@25
   702
      : Statement(pos),
dvander@195
   703
        statements_(statements),
dvander@195
   704
        scope_(NULL)
dvander@0
   705
    {
dvander@0
   706
    }
dvander@0
   707
dvander@195
   708
    DECLARE_NODE(BlockStatement);
dvander@195
   709
dvander@195
   710
    StatementList *statements() const {
dvander@195
   711
        return statements_;
dvander@0
   712
    }
dvander@0
   713
    Scope *scope() const {
dvander@0
   714
        return scope_;
dvander@0
   715
    }
dvander@195
   716
    void setScope(Scope *scope) {
dvander@195
   717
        scope_ = scope;
dvander@0
   718
    }
dvander@0
   719
};
dvander@0
   720
dvander@57
   721
typedef PoolList<Parameter *> ParameterList;
dvander@14
   722
dvander@174
   723
class FunctionSignature
dvander@174
   724
{
dvander@174
   725
  public:
dvander@195
   726
    FunctionSignature(Expression *returnType, ParameterList *parameters, bool variadic)
dvander@174
   727
      : returnType_(returnType),
dvander@195
   728
        parameters_(parameters),
dvander@195
   729
        variadic_(variadic)
dvander@174
   730
    {
dvander@174
   731
    }
dvander@174
   732
dvander@195
   733
    Expression *returnType() const {
dvander@174
   734
        return returnType_;
dvander@174
   735
    }
dvander@174
   736
    ParameterList *parameters() const {
dvander@174
   737
        return parameters_;
dvander@174
   738
    }
dvander@195
   739
    bool variadic() const {
dvander@195
   740
        return variadic_;
dvander@195
   741
    }
dvander@174
   742
dvander@174
   743
  private:
dvander@195
   744
    Expression *returnType_;
dvander@174
   745
    ParameterList *parameters_;
dvander@195
   746
    bool variadic_;
dvander@174
   747
};
dvander@174
   748
dvander@174
   749
class FunctionTypeStatement : public Statement
dvander@174
   750
{
dvander@174
   751
  public:
dvander@195
   752
    FunctionTypeStatement(const SourcePosition &pos, Handle<String> name, const FunctionSignature &signature)
dvander@174
   753
      : Statement(pos),
dvander@195
   754
        name_(name),
dvander@174
   755
        signature_(signature)
dvander@174
   756
    {
dvander@174
   757
    }
dvander@174
   758
dvander@195
   759
    DECLARE_NODE(FunctionTypeStatement);
dvander@195
   760
dvander@195
   761
    Handle<String> name() const {
dvander@195
   762
        return name_;
dvander@174
   763
    }
dvander@174
   764
    const FunctionSignature &signature() const {
dvander@174
   765
        return signature_;
dvander@174
   766
    }
dvander@174
   767
dvander@174
   768
  private:
dvander@195
   769
    ScopedRoot<String> name_;
dvander@174
   770
    FunctionSignature signature_;
dvander@195
   771
    
dvander@174
   772
};
dvander@174
   773
dvander@0
   774
class FunctionStatement : public Statement
dvander@0
   775
{
dvander@195
   776
    ScopedRoot<String> name_;
dvander@195
   777
    TokenKind kind_;
dvander@0
   778
    Statement *body_;
dvander@174
   779
    FunctionSignature signature_;
dvander@71
   780
    bool explicitReturn_;
dvander@195
   781
    FunctionSymbol *sym_;
dvander@195
   782
    Scope *argScope_;
dvander@195
   783
    Scope *varScope_;
dvander@0
   784
dvander@0
   785
  public:
dvander@195
   786
    FunctionStatement(const SourcePosition &pos, Handle<String> name, TokenKind kind,
dvander@195
   787
                      Statement *body, const FunctionSignature &signature, bool explicitReturn)
dvander@25
   788
      : Statement(pos),
dvander@195
   789
        name_(name),
dvander@195
   790
        kind_(kind),
dvander@14
   791
        body_(body),
dvander@174
   792
        signature_(signature),
dvander@195
   793
        explicitReturn_(explicitReturn),
dvander@195
   794
        sym_(NULL),
dvander@195
   795
        argScope_(NULL),
dvander@195
   796
        varScope_(NULL)
dvander@0
   797
    {
dvander@0
   798
    }
dvander@0
   799
dvander@195
   800
    DECLARE_NODE(FunctionStatement);
dvander@195
   801
dvander@195
   802
    Handle<String> name() const {
dvander@195
   803
        return name_;
dvander@0
   804
    }
dvander@0
   805
    Statement *body() const {
dvander@0
   806
        return body_;
dvander@0
   807
    }
dvander@174
   808
    const FunctionSignature &signature() {
dvander@174
   809
        return signature_;
dvander@14
   810
    }
dvander@71
   811
    bool hasExplicitReturn() const {
dvander@71
   812
        return explicitReturn_;
dvander@71
   813
    }
dvander@195
   814
    TokenKind token() const {
dvander@195
   815
        return kind_;
dvander@195
   816
    }
dvander@195
   817
    void setSymbol(FunctionSymbol *sym) {
dvander@195
   818
        assert(!sym_);
dvander@195
   819
        sym_ = sym;
dvander@195
   820
    }
dvander@195
   821
    FunctionSymbol *sym() const {
dvander@195
   822
        return sym_;
dvander@195
   823
    }
dvander@195
   824
    void setScopes(Scope *argScope, Scope *varScope) {
dvander@195
   825
        argScope_ = argScope;
dvander@195
   826
        varScope_ = varScope;
dvander@195
   827
    }
dvander@195
   828
    Scope *argScope() const {
dvander@195
   829
        return argScope_;
dvander@195
   830
    }
dvander@195
   831
    Scope *varScope() const {
dvander@195
   832
        return varScope_;
dvander@195
   833
    }
dvander@0
   834
};
dvander@0
   835
dvander@0
   836
class IfStatement : public Statement
dvander@0
   837
{
dvander@0
   838
    Expression *condition_;
dvander@0
   839
    Statement *ifTrue_;
dvander@0
   840
    Statement *ifFalse_;
dvander@0
   841
dvander@0
   842
  public:
dvander@25
   843
    IfStatement(const SourcePosition &pos, Expression *condition, Statement *ifTrue)
dvander@25
   844
      : Statement(pos),
dvander@25
   845
        condition_(condition),
dvander@0
   846
        ifTrue_(ifTrue),
dvander@0
   847
        ifFalse_(NULL)
dvander@0
   848
    {
dvander@0
   849
    }
dvander@0
   850
dvander@195
   851
    DECLARE_NODE(IfStatement);
dvander@195
   852
dvander@0
   853
    Expression *condition() const {
dvander@0
   854
        return condition_;
dvander@0
   855
    }
dvander@0
   856
    Statement *ifTrue() const {
dvander@0
   857
        return ifTrue_;
dvander@0
   858
    }
dvander@0
   859
    Statement *ifFalse() const {
dvander@0
   860
        return ifFalse_;
dvander@0
   861
    }
dvander@0
   862
    void setIfFalse(Statement *ifFalse) {
dvander@0
   863
        ifFalse_ = ifFalse;
dvander@0
   864
    }
dvander@0
   865
};
dvander@0
   866
dvander@2
   867
class EnumStatement : public Statement
dvander@2
   868
{
dvander@54
   869
    ScopedRoot<String> name_;
dvander@195
   870
    TypeSymbol *sym_;
dvander@2
   871
dvander@2
   872
  public:
dvander@2
   873
    struct Entry {
dvander@195
   874
        ScopedRoot<String> name;
dvander@2
   875
        Expression *expr;
dvander@2
   876
dvander@195
   877
        Entry(Handle<String> name, Expression *expr)
dvander@2
   878
          : name(name),
dvander@2
   879
            expr(expr)
dvander@2
   880
        {
dvander@2
   881
        }
dvander@2
   882
    };
dvander@2
   883
dvander@57
   884
    typedef PoolList<Entry> EntryList;
dvander@2
   885
dvander@2
   886
  public:
dvander@195
   887
    EnumStatement(const SourcePosition &pos, Handle<String> name, EntryList *entries)
dvander@25
   888
      : Statement(pos),
dvander@25
   889
        name_(name),
dvander@195
   890
        entries_(entries),
dvander@195
   891
        sym_(NULL)
dvander@2
   892
    {
dvander@2
   893
    }
dvander@2
   894
dvander@195
   895
    DECLARE_NODE(EnumStatement);
dvander@195
   896
dvander@54
   897
    String *name() const {
dvander@2
   898
        return name_;
dvander@2
   899
    }
dvander@2
   900
    EntryList *entries() const {
dvander@2
   901
        return entries_;
dvander@2
   902
    }
dvander@195
   903
    void setSymbol(TypeSymbol *sym) {
dvander@195
   904
        assert(!sym_);
dvander@195
   905
        sym_ = sym;
dvander@145
   906
    }
dvander@195
   907
    TypeSymbol *sym() const {
dvander@195
   908
        return sym_;
dvander@2
   909
    }
dvander@2
   910
dvander@2
   911
  private:
dvander@2
   912
    EntryList *entries_;
dvander@2
   913
};
dvander@2
   914
dvander@23
   915
class IncDecExpression : public Expression
dvander@23
   916
{
dvander@23
   917
    TokenKind token_;
dvander@23
   918
    Expression *expression_;
dvander@23
   919
    bool postfix_;
dvander@23
   920
dvander@23
   921
  public:
dvander@25
   922
    IncDecExpression(const SourcePosition &pos, TokenKind token, Expression *expression, bool postfix)
dvander@25
   923
      : Expression(pos),
dvander@25
   924
        token_(token),
dvander@23
   925
        expression_(expression),
dvander@23
   926
        postfix_(postfix)
dvander@23
   927
    {
dvander@23
   928
    }
dvander@23
   929
dvander@195
   930
    DECLARE_NODE(IncDecExpression);
dvander@195
   931
dvander@23
   932
    TokenKind token() const {
dvander@23
   933
        return token_;
dvander@23
   934
    }
dvander@23
   935
    Expression *expression() const {
dvander@23
   936
        return expression_;
dvander@23
   937
    }
dvander@23
   938
    bool postfix() const {
dvander@23
   939
        return postfix_;
dvander@23
   940
    }
dvander@23
   941
};
dvander@23
   942
dvander@172
   943
class Case : public PoolObject
dvander@172
   944
{
dvander@172
   945
  public:
dvander@172
   946
    Case(Expression *expression, ExpressionList *others, Statement *statement)
dvander@172
   947
      : expression_(expression),
dvander@172
   948
        others_(others),
dvander@172
   949
        statement_(statement)
dvander@172
   950
    {
dvander@172
   951
    }
dvander@172
   952
dvander@172
   953
    Expression *expression() const {
dvander@172
   954
        return expression_;
dvander@172
   955
    }
dvander@172
   956
    PoolList<Expression *> *others() const {
dvander@172
   957
        return others_;
dvander@172
   958
    }
dvander@172
   959
    Statement *statement() const {
dvander@172
   960
        return statement_;
dvander@172
   961
    }
dvander@172
   962
dvander@172
   963
  private:
dvander@172
   964
    Expression *expression_;
dvander@172
   965
    PoolList <Expression *> *others_;
dvander@172
   966
    Statement *statement_;
dvander@172
   967
};
dvander@172
   968
dvander@172
   969
struct CaseValue
dvander@172
   970
{
dvander@172
   971
    BoxedPrimitive box;
dvander@172
   972
    size_t statement;
dvander@172
   973
dvander@172
   974
    CaseValue(size_t statement)
dvander@172
   975
      : statement(statement)
dvander@172
   976
    {
dvander@172
   977
    }
dvander@172
   978
};
dvander@172
   979
dvander@172
   980
typedef PoolList<CaseValue> CaseValueList;
dvander@172
   981
dvander@172
   982
class SwitchStatement : public Statement
dvander@172
   983
{
dvander@172
   984
  public:
dvander@172
   985
    SwitchStatement(const SourcePosition &pos, Expression *expression, PoolList<Case *> *cases,
dvander@172
   986
                    Statement *def)
dvander@172
   987
      : Statement(pos),
dvander@172
   988
        expression_(expression),
dvander@172
   989
        cases_(cases),
dvander@172
   990
        default_(def),
dvander@172
   991
        table_(NULL)
dvander@172
   992
    {
dvander@172
   993
    }
dvander@172
   994
dvander@195
   995
    DECLARE_NODE(SwitchStatement);
dvander@195
   996
dvander@172
   997
    Expression *expression() const {
dvander@172
   998
        return expression_;
dvander@172
   999
    }
dvander@172
  1000
    PoolList<Case *> *cases() const {
dvander@172
  1001
        return cases_;
dvander@172
  1002
    }
dvander@172
  1003
    Statement *defaultCase() const {
dvander@172
  1004
        return default_;
dvander@172
  1005
    }
dvander@172
  1006
    void setCaseValueList(CaseValueList *list) {
dvander@172
  1007
        table_ = list;
dvander@172
  1008
    }
dvander@172
  1009
    CaseValueList *caseValueList() const {
dvander@172
  1010
        return table_;
dvander@172
  1011
    }
dvander@172
  1012
dvander@172
  1013
  private:
dvander@172
  1014
    Expression *expression_;
dvander@172
  1015
    PoolList<Case *> *cases_;
dvander@172
  1016
    Statement *default_;
dvander@172
  1017
    CaseValueList *table_;
dvander@172
  1018
};
dvander@172
  1019
dvander@146
  1020
class StructureStatement : public Statement
dvander@146
  1021
{
dvander@146
  1022
  public:
dvander@146
  1023
    class Field : public PoolObject
dvander@146
  1024
    {
dvander@146
  1025
        SourcePosition pos_;
dvander@195
  1026
        Expression *type_;
dvander@146
  1027
        ScopedRoot<String> name_;
dvander@146
  1028
dvander@146
  1029
      public:
dvander@146
  1030
        Field(const SourcePosition &pos,
dvander@195
  1031
              Expression *type,
dvander@195
  1032
              Handle<String> name)
dvander@146
  1033
          : pos_(pos),
dvander@146
  1034
            type_(type),
dvander@195
  1035
            name_(name)
dvander@146
  1036
        {
dvander@146
  1037
        }
dvander@146
  1038
dvander@146
  1039
        const SourcePosition &pos() const {
dvander@146
  1040
            return pos_;
dvander@146
  1041
        }
dvander@195
  1042
        Handle<String> name() const {
dvander@146
  1043
            return name_;
dvander@146
  1044
        }
dvander@195
  1045
        Expression *type() const {
dvander@195
  1046
            return type_;
dvander@146
  1047
        }
dvander@146
  1048
    };
dvander@146
  1049
dvander@146
  1050
    typedef PoolList<StructureStatement::Field *> FieldList;
dvander@146
  1051
dvander@146
  1052
  public:
dvander@195
  1053
    StructureStatement(const SourcePosition &pos, Handle<String> name, FieldList *fields)
dvander@146
  1054
      : Statement(pos),
dvander@195
  1055
        name_(name),
dvander@195
  1056
        fields_(fields),
dvander@195
  1057
        sym_(NULL)
dvander@146
  1058
    {
dvander@146
  1059
    }
dvander@146
  1060
dvander@195
  1061
    DECLARE_NODE(StructureStatement);
dvander@195
  1062
dvander@146
  1063
    FieldList *fields() const {
dvander@146
  1064
        return fields_;
dvander@146
  1065
    }
dvander@195
  1066
    Handle<String> name() const {
dvander@195
  1067
        return name_;
dvander@146
  1068
    }
dvander@195
  1069
    void setSymbol(TypeSymbol *sym) {
dvander@195
  1070
        assert(!sym_);
dvander@195
  1071
        sym_ = sym;
dvander@195
  1072
    }
dvander@195
  1073
    TypeSymbol *sym() const {
dvander@195
  1074
        return sym_;
dvander@146
  1075
    }
dvander@146
  1076
dvander@146
  1077
  private:
dvander@195
  1078
    ScopedRoot<String> name_;
dvander@146
  1079
    FieldList *fields_;
dvander@195
  1080
    TypeSymbol *sym_;
dvander@195
  1081
};
dvander@195
  1082
dvander@195
  1083
typedef PoolList<ScopedRoot<String> *> NameList;
dvander@195
  1084
dvander@195
  1085
class ImportStatement : public Statement
dvander@195
  1086
{
dvander@195
  1087
  public:
dvander@195
  1088
    ImportStatement(const SourcePosition &pos, NameList *names, TokenKind suffix)
dvander@195
  1089
      : Statement(pos),
dvander@195
  1090
        names_(names),
dvander@195
  1091
        suffix_(suffix),
dvander@195
  1092
        source_(NULL)
dvander@195
  1093
    {
dvander@195
  1094
    }
dvander@195
  1095
dvander@195
  1096
    DECLARE_NODE(ImportStatement);
dvander@195
  1097
dvander@195
  1098
    NameList *path() const {
dvander@195
  1099
        return names_;
dvander@195
  1100
    }
dvander@195
  1101
    void setImportSource(TranslationUnit *unit) {
dvander@195
  1102
        source_ = unit;
dvander@195
  1103
    }
dvander@195
  1104
    TranslationUnit *source() const {
dvander@195
  1105
        return source_;
dvander@195
  1106
    }
dvander@195
  1107
    TokenKind suffix() const {
dvander@195
  1108
        return suffix_;
dvander@195
  1109
    }
dvander@195
  1110
    Handle<String> name() const {
dvander@195
  1111
        assert(suffix() != TOK_STAR);
dvander@195
  1112
        return *names_->at(names_->length() - 1);
dvander@195
  1113
    }
dvander@195
  1114
dvander@195
  1115
  private:
dvander@195
  1116
    NameList *names_;
dvander@195
  1117
    TokenKind suffix_;
dvander@195
  1118
    TranslationUnit *source_;
dvander@146
  1119
};
dvander@146
  1120
dvander@146
  1121
typedef StructureStatement::FieldList FieldList;
dvander@195
  1122
typedef PoolList<NameProxy *> NameProxyList;
dvander@146
  1123
dvander@195
  1124
#undef DECLARE_NODE
dvander@0
  1125
dvander@0
  1126
class ParseTree : public PoolObject
dvander@0
  1127
{
dvander@0
  1128
    StatementList *statements_;
dvander@0
  1129
    NameProxyList *unbound_;
dvander@195
  1130
    PoolList<ImportStatement *> *imports_;
dvander@0
  1131
dvander@0
  1132
  public:
dvander@195
  1133
    ParseTree(StatementList *statements, NameProxyList *unbound, PoolList<ImportStatement *> *imports)
dvander@0
  1134
      : statements_(statements),
dvander@195
  1135
        unbound_(unbound),
dvander@195
  1136
        imports_(imports)
dvander@0
  1137
    {
dvander@0
  1138
    }
dvander@0
  1139
dvander@0
  1140
    void dump(FILE *fp);
dvander@0
  1141
dvander@0
  1142
    StatementList *statements() const {
dvander@0
  1143
        return statements_;
dvander@0
  1144
    }
dvander@0
  1145
    NameProxyList *unbound() const {
dvander@0
  1146
        return unbound_;
dvander@0
  1147
    }
dvander@195
  1148
    PoolList<ImportStatement *> *imports() const {
dvander@195
  1149
        return imports_;
dvander@195
  1150
    }
dvander@0
  1151
};
dvander@0
  1152
dvander@0
  1153
}
dvander@0
  1154
dvander@168
  1155
#endif // _include_sourcepawn_ast_h_