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