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