src/compiler/AST.h
author David Anderson <dvander@alliedmods.net>
Thu Dec 20 00:59:38 2012 -0800 (2012-12-20)
changeset 222 0cde1379b29f
parent 220 5df4a112967d
child 233 bbb498ccb4ac
permissions -rw-r--r--
Re-added support for reference arguments.
     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 
   887         Entry(Handle<String> name, Expression *expr)
   888           : name(name),
   889             expr(expr)
   890         {
   891         }
   892     };
   893 
   894     typedef PoolList<Entry> EntryList;
   895 
   896   public:
   897     EnumStatement(const SourcePosition &pos, Handle<String> name, EntryList *entries)
   898       : Statement(pos),
   899         name_(name),
   900         sym_(NULL),
   901         entries_(entries)
   902     {
   903     }
   904 
   905     DECLARE_NODE(EnumStatement);
   906 
   907     String *name() const {
   908         return name_;
   909     }
   910     EntryList *entries() const {
   911         return entries_;
   912     }
   913     void setSymbol(TypeSymbol *sym) {
   914         assert(!sym_);
   915         sym_ = sym;
   916     }
   917     TypeSymbol *sym() const {
   918         return sym_;
   919     }
   920 
   921   private:
   922     EntryList *entries_;
   923 };
   924 
   925 class IncDecExpression : public Expression
   926 {
   927     TokenKind token_;
   928     Expression *expression_;
   929     bool postfix_;
   930 
   931   public:
   932     IncDecExpression(const SourcePosition &pos, TokenKind token, Expression *expression, bool postfix)
   933       : Expression(pos),
   934         token_(token),
   935         expression_(expression),
   936         postfix_(postfix)
   937     {
   938     }
   939 
   940     DECLARE_NODE(IncDecExpression);
   941 
   942     TokenKind token() const {
   943         return token_;
   944     }
   945     Expression *expression() const {
   946         return expression_;
   947     }
   948     bool postfix() const {
   949         return postfix_;
   950     }
   951 };
   952 
   953 class Case : public PoolObject
   954 {
   955   public:
   956     Case(Expression *expression, ExpressionList *others, Statement *statement)
   957       : expression_(expression),
   958         others_(others),
   959         statement_(statement)
   960     {
   961     }
   962 
   963     Expression *expression() const {
   964         return expression_;
   965     }
   966     PoolList<Expression *> *others() const {
   967         return others_;
   968     }
   969     Statement *statement() const {
   970         return statement_;
   971     }
   972 
   973   private:
   974     Expression *expression_;
   975     PoolList <Expression *> *others_;
   976     Statement *statement_;
   977 };
   978 
   979 struct CaseValue
   980 {
   981     BoxedPrimitive box;
   982     size_t statement;
   983 
   984     CaseValue(size_t statement)
   985       : statement(statement)
   986     {
   987     }
   988 };
   989 
   990 typedef PoolList<CaseValue> CaseValueList;
   991 
   992 class SwitchStatement : public Statement
   993 {
   994   public:
   995     SwitchStatement(const SourcePosition &pos, Expression *expression, PoolList<Case *> *cases,
   996                     Statement *def)
   997       : Statement(pos),
   998         expression_(expression),
   999         cases_(cases),
  1000         default_(def),
  1001         table_(NULL)
  1002     {
  1003     }
  1004 
  1005     DECLARE_NODE(SwitchStatement);
  1006 
  1007     Expression *expression() const {
  1008         return expression_;
  1009     }
  1010     PoolList<Case *> *cases() const {
  1011         return cases_;
  1012     }
  1013     Statement *defaultCase() const {
  1014         return default_;
  1015     }
  1016     void setCaseValueList(CaseValueList *list) {
  1017         table_ = list;
  1018     }
  1019     CaseValueList *caseValueList() const {
  1020         return table_;
  1021     }
  1022 
  1023   private:
  1024     Expression *expression_;
  1025     PoolList<Case *> *cases_;
  1026     Statement *default_;
  1027     CaseValueList *table_;
  1028 };
  1029 
  1030 class StructureStatement : public Statement
  1031 {
  1032   public:
  1033     class Field : public PoolObject
  1034     {
  1035         SourcePosition pos_;
  1036         Expression *type_;
  1037         ScopedRoot<String> name_;
  1038 
  1039       public:
  1040         Field(const SourcePosition &pos,
  1041               Expression *type,
  1042               Handle<String> name)
  1043           : pos_(pos),
  1044             type_(type),
  1045             name_(name)
  1046         {
  1047         }
  1048 
  1049         const SourcePosition &pos() const {
  1050             return pos_;
  1051         }
  1052         Handle<String> name() const {
  1053             return name_;
  1054         }
  1055         Expression *type() const {
  1056             return type_;
  1057         }
  1058     };
  1059 
  1060     typedef PoolList<StructureStatement::Field *> FieldList;
  1061 
  1062   public:
  1063     StructureStatement(const SourcePosition &pos, Handle<String> name, FieldList *fields)
  1064       : Statement(pos),
  1065         name_(name),
  1066         fields_(fields),
  1067         sym_(NULL)
  1068     {
  1069     }
  1070 
  1071     DECLARE_NODE(StructureStatement);
  1072 
  1073     FieldList *fields() const {
  1074         return fields_;
  1075     }
  1076     Handle<String> name() const {
  1077         return name_;
  1078     }
  1079     void setSymbol(TypeSymbol *sym) {
  1080         assert(!sym_);
  1081         sym_ = sym;
  1082     }
  1083     TypeSymbol *sym() const {
  1084         return sym_;
  1085     }
  1086 
  1087   private:
  1088     ScopedRoot<String> name_;
  1089     FieldList *fields_;
  1090     TypeSymbol *sym_;
  1091 };
  1092 
  1093 typedef PoolList<ScopedRoot<String> *> NameList;
  1094 
  1095 class ImportStatement : public Statement
  1096 {
  1097   public:
  1098     ImportStatement(const SourcePosition &pos, NameList *names, TokenKind suffix)
  1099       : Statement(pos),
  1100         names_(names),
  1101         suffix_(suffix),
  1102         source_(NULL)
  1103     {
  1104     }
  1105 
  1106     DECLARE_NODE(ImportStatement);
  1107 
  1108     NameList *path() const {
  1109         return names_;
  1110     }
  1111     void setImportSource(TranslationUnit *unit) {
  1112         source_ = unit;
  1113     }
  1114     TranslationUnit *source() const {
  1115         return source_;
  1116     }
  1117     TokenKind suffix() const {
  1118         return suffix_;
  1119     }
  1120     Handle<String> name() const {
  1121         assert(suffix() != TOK_STAR);
  1122         return *names_->at(names_->length() - 1);
  1123     }
  1124 
  1125   private:
  1126     NameList *names_;
  1127     TokenKind suffix_;
  1128     TranslationUnit *source_;
  1129 };
  1130 
  1131 typedef StructureStatement::FieldList FieldList;
  1132 typedef PoolList<NameProxy *> NameProxyList;
  1133 
  1134 #undef DECLARE_NODE
  1135 
  1136 class ParseTree : public PoolObject
  1137 {
  1138     StatementList *statements_;
  1139     NameProxyList *unbound_;
  1140     PoolList<ImportStatement *> *imports_;
  1141 
  1142   public:
  1143     ParseTree(StatementList *statements, NameProxyList *unbound, PoolList<ImportStatement *> *imports)
  1144       : statements_(statements),
  1145         unbound_(unbound),
  1146         imports_(imports)
  1147     {
  1148     }
  1149 
  1150     void dump(FILE *fp);
  1151 
  1152     StatementList *statements() const {
  1153         return statements_;
  1154     }
  1155     NameProxyList *unbound() const {
  1156         return unbound_;
  1157     }
  1158     PoolList<ImportStatement *> *imports() const {
  1159         return imports_;
  1160     }
  1161 };
  1162 
  1163 }
  1164 
  1165 #endif // _include_sourcepawn_ast_h_