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