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