src/compiler/AST.h
author Michael Busby <prodigysim@gmail.com>
Mon Jun 10 01:50:18 2013 +0100 (2013-06-10)
changeset 264 70b8f318c379
parent 263 ba85a47ee414
permissions -rw-r--r--
Parse assignment RTL instead of LTR, fixes multiple assignment (bug 5420).
     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         ConstantSymbol *sym;
   877 
   878         Entry(Handle<String> name, Expression *expr, const SourcePosition &pos)
   879           : name(name),
   880             expr(expr),
   881             pos(pos),
   882             sym(NULL)
   883         {
   884         }
   885     };
   886 
   887     typedef PoolList<Entry> EntryList;
   888 
   889   public:
   890     EnumStatement(const SourcePosition &pos, TokenKind visibility, Handle<String> name, EntryList *entries)
   891       : Statement(pos),
   892         name_(name),
   893         sym_(NULL),
   894         entries_(entries),
   895         visibility_(visibility)
   896     {
   897     }
   898 
   899     DECLARE_NODE(EnumStatement);
   900 
   901     Handle<String> name() const {
   902         return name_;
   903     }
   904     EntryList *entries() const {
   905         return entries_;
   906     }
   907     void setSymbol(TypeSymbol *sym) {
   908         assert(!sym_);
   909         sym_ = sym;
   910     }
   911     TypeSymbol *sym() const {
   912         return sym_;
   913     }
   914     TokenKind visibility() const {
   915         return visibility_;
   916     }
   917 
   918   private:
   919     EntryList *entries_;
   920     TokenKind visibility_;
   921 };
   922 
   923 class IncDecExpression : public Expression
   924 {
   925     TokenKind token_;
   926     Expression *expression_;
   927     bool postfix_;
   928 
   929   public:
   930     IncDecExpression(const SourcePosition &pos, TokenKind token, Expression *expression, bool postfix)
   931       : Expression(pos),
   932         token_(token),
   933         expression_(expression),
   934         postfix_(postfix)
   935     {
   936     }
   937 
   938     DECLARE_NODE(IncDecExpression);
   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 };
   950 
   951 class Case : public PoolObject
   952 {
   953   public:
   954     Case(Expression *expression, ExpressionList *others, Statement *statement)
   955       : expression_(expression),
   956         others_(others),
   957         statement_(statement)
   958     {
   959     }
   960 
   961     Expression *expression() const {
   962         return expression_;
   963     }
   964     PoolList<Expression *> *others() const {
   965         return others_;
   966     }
   967     Statement *statement() const {
   968         return statement_;
   969     }
   970 
   971   private:
   972     Expression *expression_;
   973     PoolList <Expression *> *others_;
   974     Statement *statement_;
   975 };
   976 
   977 struct CaseValue
   978 {
   979     BoxedPrimitive box;
   980     size_t statement;
   981 
   982     CaseValue(size_t statement)
   983       : statement(statement)
   984     {
   985     }
   986 };
   987 
   988 typedef PoolList<CaseValue> CaseValueList;
   989 
   990 class SwitchStatement : public Statement
   991 {
   992   public:
   993     SwitchStatement(const SourcePosition &pos, Expression *expression, PoolList<Case *> *cases,
   994                     Statement *def)
   995       : Statement(pos),
   996         expression_(expression),
   997         cases_(cases),
   998         default_(def),
   999         table_(NULL)
  1000     {
  1001     }
  1002 
  1003     DECLARE_NODE(SwitchStatement);
  1004 
  1005     Expression *expression() const {
  1006         return expression_;
  1007     }
  1008     PoolList<Case *> *cases() const {
  1009         return cases_;
  1010     }
  1011     Statement *defaultCase() const {
  1012         return default_;
  1013     }
  1014     void setCaseValueList(CaseValueList *list) {
  1015         table_ = list;
  1016     }
  1017     CaseValueList *caseValueList() const {
  1018         return table_;
  1019     }
  1020 
  1021   private:
  1022     Expression *expression_;
  1023     PoolList<Case *> *cases_;
  1024     Statement *default_;
  1025     CaseValueList *table_;
  1026 };
  1027 
  1028 class StructureStatement : public Statement
  1029 {
  1030   public:
  1031     class Field : public PoolObject
  1032     {
  1033         SourcePosition pos_;
  1034         Expression *type_;
  1035         ScopedRoot<String> name_;
  1036 
  1037       public:
  1038         Field(const SourcePosition &pos,
  1039               Expression *type,
  1040               Handle<String> name)
  1041           : pos_(pos),
  1042             type_(type),
  1043             name_(name)
  1044         {
  1045         }
  1046 
  1047         const SourcePosition &pos() const {
  1048             return pos_;
  1049         }
  1050         Handle<String> name() const {
  1051             return name_;
  1052         }
  1053         Expression *type() const {
  1054             return type_;
  1055         }
  1056     };
  1057 
  1058     typedef PoolList<StructureStatement::Field *> FieldList;
  1059 
  1060   public:
  1061     StructureStatement(const SourcePosition &pos, Handle<String> name, FieldList *fields)
  1062       : Statement(pos),
  1063         name_(name),
  1064         fields_(fields),
  1065         sym_(NULL)
  1066     {
  1067     }
  1068 
  1069     DECLARE_NODE(StructureStatement);
  1070 
  1071     FieldList *fields() const {
  1072         return fields_;
  1073     }
  1074     Handle<String> name() const {
  1075         return name_;
  1076     }
  1077     void setSymbol(TypeSymbol *sym) {
  1078         assert(!sym_);
  1079         sym_ = sym;
  1080     }
  1081     TypeSymbol *sym() const {
  1082         return sym_;
  1083     }
  1084 
  1085   private:
  1086     ScopedRoot<String> name_;
  1087     FieldList *fields_;
  1088     TypeSymbol *sym_;
  1089 };
  1090 
  1091 typedef PoolList<ScopedRoot<String> *> NameList;
  1092 
  1093 class ImportStatement : public Statement
  1094 {
  1095   public:
  1096     ImportStatement(const SourcePosition &pos, PathComponent *path, NameList *names)
  1097       : Statement(pos),
  1098         path_(path),
  1099         names_(names)
  1100     {
  1101     }
  1102 
  1103     DECLARE_NODE(ImportStatement);
  1104 
  1105     PathComponent *path() const {
  1106         return path_;
  1107     }
  1108     void setSource(Importable *source) {
  1109         source_ = source;
  1110     }
  1111     Handle<Importable> source() {
  1112         return source_;
  1113     }
  1114     unsigned importIndex() const {
  1115         return importIndex_;
  1116     }
  1117     void setImportIndex(unsigned index) {
  1118         importIndex_ = index;
  1119     }
  1120     NameList *names() const {
  1121         return names_;
  1122     }
  1123 
  1124     bool importAllNames() const {
  1125         return names_ && names_->empty();
  1126     }
  1127 
  1128   private:
  1129     PathComponent *path_;
  1130     ScopedRoot<Importable> source_;
  1131     unsigned importIndex_;
  1132     NameList *names_;
  1133 };
  1134 
  1135 typedef StructureStatement::FieldList FieldList;
  1136 typedef PoolList<NameProxy *> NameProxyList;
  1137 
  1138 #undef DECLARE_NODE
  1139 
  1140 class ParseTree : public PoolObject
  1141 {
  1142     StatementList *statements_;
  1143     NameProxyList *unbound_;
  1144     PoolList<ImportStatement *> *imports_;
  1145 
  1146   public:
  1147     ParseTree(StatementList *statements, NameProxyList *unbound, PoolList<ImportStatement *> *imports)
  1148       : statements_(statements),
  1149         unbound_(unbound),
  1150         imports_(imports)
  1151     {
  1152     }
  1153 
  1154     void dump(FILE *fp);
  1155 
  1156     StatementList *statements() const {
  1157         return statements_;
  1158     }
  1159     NameProxyList *unbound() const {
  1160         return unbound_;
  1161     }
  1162     PoolList<ImportStatement *> *imports() const {
  1163         return imports_;
  1164     }
  1165 };
  1166 
  1167 }
  1168 
  1169 #endif // _include_sourcepawn_ast_h_