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