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