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