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