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