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