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