src/AST.h
author David Anderson <dvander@alliedmods.net>
Sun Jul 29 18:19:12 2012 -0700 (2012-07-29)
changeset 132 d8379f5d5a1d
parent 86 32ad0523b309
child 133 7797936ba34c
permissions -rw-r--r--
Support return tags on functions.
     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_jitcraft_ast_h_
    20 #define _include_jitcraft_ast_h_
    21 
    22 #include "PoolAllocator.h"
    23 #include "Token.h"
    24 #include "NameBinding.h"
    25 #include "Vector.h"
    26 
    27 namespace ke {
    28 
    29 #define ASTKINDS(_)             \
    30     _(VariableDeclaration)      \
    31     _(ForStatement)             \
    32     _(ReturnStatement)          \
    33     _(IntegerLiteral)           \
    34     _(FloatLiteral)             \
    35     _(StringLiteral)            \
    36     _(BinaryExpression)         \
    37     _(BlockStatement)           \
    38     _(Assignment)               \
    39     _(NameProxy)                \
    40     _(ExpressionStatement)      \
    41     _(FunctionStatement)        \
    42     _(CallExpression)           \
    43     _(IfStatement)              \
    44     _(IndexExpression)          \
    45     _(EnumStatement)            \
    46     _(WhileStatement)           \
    47     _(BreakStatement)           \
    48     _(ContinueStatement)        \
    49     _(IncDecExpression)         \
    50     _(UnaryExpression)          \
    51     _(TernaryExpression)
    52 
    53 // Forward declarations.
    54 #define _(name) class name;
    55 ASTKINDS(_)
    56 #undef _
    57 
    58 class AstVisitor;
    59 
    60 // Interface for AST nodes.
    61 class AstNode : public PoolObject
    62 {
    63     SourcePosition pos_;
    64 
    65   public:
    66     enum Kind {
    67 #       define _(name) k##name,
    68         ASTKINDS(_)
    69 #       undef _
    70         AstKind_Invalid
    71     };
    72 
    73     AstNode(const SourcePosition &pos)
    74       : pos_(pos)
    75     {
    76     }
    77     
    78     virtual Kind kind() const = 0;
    79 
    80 #define _(name)     bool is##name() { return kind() == k##name; }                   \
    81                     name *to##name() { assert(is##name()); return (name *)this; }
    82     ASTKINDS(_)
    83 #undef _
    84 
    85     virtual void accept(AstVisitor *visitor) = 0;
    86 
    87     const SourcePosition &pos() const {
    88         return pos_;
    89     }
    90 };
    91 
    92 class AstVisitor
    93 {
    94   public:
    95 #define _(name) virtual void visit(name *node) = 0;
    96     ASTKINDS(_)
    97 #undef _
    98 };
    99 
   100 class NameLocation
   101 {
   102   public:
   103     enum Kind {
   104         LOCAL
   105     };
   106 
   107     static NameLocation Local(VariableDeclaration *decl) {
   108         NameLocation loc;
   109         loc.kind_ = LOCAL;
   110         loc.u_.decl = decl;
   111         return loc;
   112     }
   113 
   114     Kind kind() const {
   115         return kind_;
   116     }
   117 
   118     VariableDeclaration *local() const {
   119         assert(kind() == LOCAL);
   120         return u_.decl;
   121     }
   122 
   123   private:
   124     Kind kind_;
   125     union {
   126         VariableDeclaration *decl;
   127     } u_;
   128 };
   129 
   130 class Statement : public AstNode
   131 {
   132   public:
   133     Statement(const SourcePosition &pos)
   134       : AstNode(pos)
   135     {
   136     }
   137 };
   138 
   139 class Expression : public AstNode
   140 {
   141     ScopedRoot<Type> type_;
   142 
   143   public:
   144     Expression(const SourcePosition &pos)
   145       : AstNode(pos),
   146         type_(NULL)
   147     {
   148     }
   149 
   150     void setType(Type *type) {
   151         type_ = type;
   152     }
   153     Type *type() const {
   154         return type_;
   155     }
   156 };
   157 
   158 typedef PoolList<Statement *> StatementList;
   159 typedef PoolList<Expression *> ExpressionList;
   160 
   161 class VariableDeclaration : public Statement
   162 {
   163     Variable *variable_;
   164     Expression *initialization_;
   165     ExpressionList *postDimensions_;
   166     ScopedRoot<String> tag_;
   167 
   168   public:
   169     VariableDeclaration(const SourcePosition &pos, Variable *var, Handle<String> tag,
   170                         ExpressionList *postDimensions, Expression *initialization)
   171       : Statement(pos),
   172         variable_(var),
   173         initialization_(initialization),
   174         postDimensions_(postDimensions),
   175         tag_(tag)
   176     {
   177     }
   178 
   179     String *tag() const {
   180         return tag_;
   181     }
   182     Kind kind() const {
   183         return kVariableDeclaration;
   184     }
   185     Variable *variable() const {
   186         return variable_;
   187     }
   188     Expression *initialization() const {
   189         return initialization_;
   190     }
   191     ExpressionList *postDimensions() const {
   192         return postDimensions_;
   193     }
   194     void accept(AstVisitor *visitor) {
   195         visitor->visit(this);
   196     }
   197 };
   198 
   199 class Parameter : public PoolObject
   200 {
   201     Variable *variable_;
   202     ScopedRoot<String> tag_;
   203     bool reference_;
   204     bool const_;
   205     ExpressionList *dimensions_;
   206 
   207   public:
   208     Parameter(Variable *var, Handle<String> tag, bool reference, bool isConst, ExpressionList *dimensions)
   209       : variable_(var),
   210         tag_(tag),
   211         reference_(reference),
   212         const_(isConst),
   213         dimensions_(dimensions)
   214     {
   215     }
   216 
   217     String *tag() const {
   218         return tag_;
   219     }
   220     Variable *variable() const {
   221         return variable_;
   222     }
   223     bool reference() const {
   224         return reference_;
   225     }
   226     ExpressionList *dimensions() const {
   227         return dimensions_;
   228     }
   229     bool isConst() const {
   230         return const_;
   231     }
   232 };
   233 
   234 class NameProxy : public Expression
   235 {
   236     ScopedRoot<String> name_;
   237     BoundName *binding_;
   238 
   239   public:
   240     NameProxy(const SourcePosition &pos, Handle<String> name, BoundName *binding)
   241       : Expression(pos),
   242         name_(name),
   243         binding_(binding)
   244     {
   245     }
   246 
   247     Kind kind() const {
   248         return kNameProxy;
   249     }
   250     String *name() const {
   251         return name_;
   252     }
   253     void accept(AstVisitor *visitor) {
   254         visitor->visit(this);
   255     }
   256     BoundName *binding() const {
   257         return binding_;
   258     }
   259     void bind(BoundName *name) {
   260         assert(!binding());
   261         binding_ = name;
   262     }
   263 };
   264 
   265 class IntegerLiteral : public Expression
   266 {
   267     int value_;
   268 
   269   public:
   270     IntegerLiteral(const SourcePosition &pos, int value)
   271       : Expression(pos),
   272         value_(value)
   273     {
   274     }
   275 
   276     Kind kind() const {
   277         return kIntegerLiteral;
   278     }
   279     int value() const {
   280         return value_;
   281     }
   282     void accept(AstVisitor *visitor) {
   283         visitor->visit(this);
   284     }
   285 };
   286 
   287 class FloatLiteral : public Expression
   288 {
   289     double value_;
   290 
   291   public:
   292     FloatLiteral(const SourcePosition &pos, double value)
   293       : Expression(pos),
   294         value_(value)
   295     {
   296     }
   297 
   298     Kind kind() const {
   299         return kFloatLiteral;
   300     }
   301     double value() const {
   302         return value_;
   303     }
   304     void accept(AstVisitor *visitor) {
   305         visitor->visit(this);
   306     }
   307 };
   308 
   309 class StringLiteral : public Expression
   310 {
   311     ScopedRoot<ByteArray> string_;
   312 
   313   public:
   314     StringLiteral(const SourcePosition &pos, ByteArray *array)
   315       : Expression(pos),
   316         string_(array)
   317     {
   318     }
   319 
   320     Kind kind() const {
   321         return kStringLiteral;
   322     }
   323     ByteArray *string() const {
   324         return string_;
   325     }
   326     void accept(AstVisitor *visitor) {
   327         visitor->visit(this);
   328     }
   329 };
   330 
   331 class UnaryExpression : public Expression
   332 {
   333     Expression *expression_;
   334     TokenKind token_;
   335 
   336   public:
   337     UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr)
   338       : Expression(pos),
   339         expression_(expr),
   340         token_(token)
   341     {
   342     }
   343 
   344     Kind kind() const {
   345         return kUnaryExpression;
   346     }
   347     Expression *expression() const {
   348         return expression_;
   349     }
   350     TokenKind token() const {
   351         return token_;
   352     }
   353     void accept(AstVisitor *visitor) {
   354         visitor->visit(this);
   355     }
   356 };
   357 
   358 class BinaryExpression : public Expression
   359 {
   360     Expression *left_;
   361     Expression *right_;
   362     TokenKind token_;
   363 
   364   public:
   365     BinaryExpression(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
   366       : Expression(pos),
   367         left_(left),
   368         right_(right),
   369         token_(token)
   370     {
   371     }
   372 
   373     Kind kind() const {
   374         return kBinaryExpression;
   375     }
   376     Expression *left() const {
   377         return left_;
   378     }
   379     Expression *right() const {
   380         return right_;
   381     }
   382     TokenKind token() const {
   383         return token_;
   384     }
   385     void accept(AstVisitor *visitor) {
   386         visitor->visit(this);
   387     }
   388 };
   389 
   390 class TernaryExpression : public Expression
   391 {
   392     Expression *condition_;
   393     Expression *left_;
   394     Expression *right_;
   395 
   396   public:
   397     TernaryExpression(const SourcePosition &pos, Expression *condition, Expression *left, Expression *right)
   398       : Expression(pos),
   399         condition_(condition),
   400         left_(left),
   401         right_(right)
   402     {
   403     }
   404 
   405     Kind kind() const {
   406         return kTernaryExpression;
   407     }
   408     Expression *condition() const {
   409         return condition_;
   410     }
   411     Expression *left() const {
   412         return left_;
   413     }
   414     Expression *right() const {
   415         return right_;
   416     }
   417     void accept(AstVisitor *visitor) {
   418         visitor->visit(this);
   419     }
   420 };
   421 
   422 class IndexExpression : public Expression
   423 {
   424     Expression *left_;
   425     Expression *right_;
   426 
   427   public:
   428     IndexExpression(const SourcePosition &pos, Expression *left, Expression *right)
   429       : Expression(pos),
   430         left_(left),
   431         right_(right)
   432     {
   433     }
   434 
   435     Kind kind() const {
   436         return kIndexExpression;
   437     }
   438     Expression *left() const {
   439         return left_;
   440     }
   441     Expression *right() const {
   442         return right_;
   443     }
   444     void accept(AstVisitor *visitor) {
   445         visitor->visit(this);
   446     }
   447 };
   448 
   449 class CallExpression : public Expression
   450 {
   451     Expression *callee_;
   452     ExpressionList *arguments_;
   453 
   454   public:
   455     CallExpression(const SourcePosition &pos, Expression *callee, ExpressionList *arguments)
   456       : Expression(pos),
   457         callee_(callee),
   458         arguments_(arguments)
   459     {
   460     }
   461 
   462     Kind kind() const {
   463         return kCallExpression;
   464     }
   465     Expression *callee() const {
   466         return callee_;
   467     }
   468     ExpressionList *arguments() const {
   469         return arguments_;
   470     }
   471     void accept(AstVisitor *visitor) {
   472         visitor->visit(this);
   473     }
   474 };
   475 
   476 class ForStatement : public Statement
   477 {
   478     Scope *scope_;
   479     Statement *initialization_;
   480     Expression *condition_;
   481     Statement *update_;
   482     Statement *body_;
   483 
   484   public:
   485     ForStatement(const SourcePosition &pos, Scope *scope, Statement *initialization,
   486                  Expression *condition, Statement *update, Statement *body)
   487       : Statement(pos),
   488         scope_(scope),
   489         initialization_(initialization),
   490         condition_(condition),
   491         update_(update),
   492         body_(body)
   493     {
   494     }
   495 
   496     Kind kind() const {
   497         return kForStatement;
   498     }
   499     Statement *initialization() const {
   500         return initialization_;
   501     }
   502     Scope *scope() const {
   503         return scope_;
   504     }
   505     Expression *condition() const {
   506         return condition_;
   507     }
   508     Statement *update() const {
   509         return update_;
   510     }
   511     Statement *body() const {
   512         return body_;
   513     }
   514     void accept(AstVisitor *visitor) {
   515         visitor->visit(this);
   516     }
   517 };
   518 
   519 class WhileStatement : public Statement
   520 {
   521     TokenKind token_;
   522     Expression *condition_;
   523     Statement *body_;
   524 
   525   public:
   526     WhileStatement(const SourcePosition &pos, TokenKind kind, Expression *condition, Statement *body)
   527       : Statement(pos),
   528         token_(kind),
   529         condition_(condition),
   530         body_(body)
   531     {
   532     }
   533     
   534     Kind kind() const {
   535         return kWhileStatement;
   536     }
   537     TokenKind token() const {
   538         return token_;
   539     }
   540     Expression *condition() const {
   541         return condition_;
   542     }
   543     Statement *body() const {
   544         return body_;
   545     }
   546     void accept(AstVisitor *visitor) {
   547         visitor->visit(this);
   548     }
   549 };
   550 
   551 class ReturnStatement : public Statement
   552 {
   553     Expression *expression_;
   554 
   555   public:
   556     ReturnStatement(const SourcePosition &pos, Expression *expression)
   557       : Statement(pos),
   558         expression_(expression)
   559     {
   560     }
   561 
   562     Kind kind() const {
   563         return kReturnStatement;
   564     }
   565     Expression *expression() const {
   566         return expression_;
   567     }
   568     void accept(AstVisitor *visitor) {
   569         visitor->visit(this);
   570     }
   571 };
   572 
   573 class BreakStatement : public Statement
   574 {
   575   public:
   576     BreakStatement(const SourcePosition &pos)
   577       : Statement(pos)
   578     {
   579     }
   580 
   581     Kind kind() const {
   582         return kBreakStatement;
   583     }
   584     void accept(AstVisitor *visitor) {
   585         visitor->visit(this);
   586     }
   587 };
   588 
   589 class ContinueStatement : public Statement
   590 {
   591   public:
   592     ContinueStatement(const SourcePosition &pos)
   593       : Statement(pos)
   594     {
   595     }
   596 
   597     Kind kind() const {
   598         return kContinueStatement;
   599     }
   600     void accept(AstVisitor *visitor) {
   601         visitor->visit(this);
   602     }
   603 };
   604 
   605 class Assignment : public Expression
   606 {
   607     TokenKind token_;
   608     Expression *lvalue_;
   609     Expression *expression_;
   610 
   611   public:
   612     Assignment(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
   613       : Expression(pos),
   614         token_(token),
   615         lvalue_(left),
   616         expression_(right)
   617     {
   618     }
   619 
   620     Kind kind() const {
   621         return kAssignment;
   622     }
   623     TokenKind token() const {
   624         return token_;
   625     }
   626     Expression *lvalue() const {
   627         return lvalue_;
   628     }
   629     Expression *expression() const {
   630         return expression_;
   631     }
   632     void accept(AstVisitor *visitor) {
   633         visitor->visit(this);
   634     }
   635 };
   636 
   637 class ExpressionStatement : public Statement
   638 {
   639     Expression *expression_;
   640 
   641   public:
   642     ExpressionStatement(Expression *expression)
   643       : Statement(expression->pos()),
   644         expression_(expression)
   645     {
   646     }
   647 
   648     Kind kind() const {
   649         return kExpressionStatement;
   650     }
   651     Expression *expression() const {
   652         return expression_;
   653     }
   654     void accept(AstVisitor *visitor) {
   655         visitor->visit(this);
   656     }
   657 };
   658 
   659 class BlockStatement : public Statement
   660 {
   661     Scope *scope_;
   662     StatementList *statements_;
   663 
   664   public:
   665     BlockStatement(const SourcePosition &pos, Scope *scope, StatementList *statements)
   666       : Statement(pos),
   667         scope_(scope),
   668         statements_(statements)
   669     {
   670     }
   671 
   672     Kind kind() const {
   673         return kBlockStatement;
   674     }
   675     Scope *scope() const {
   676         return scope_;
   677     }
   678     StatementList *statements() const {
   679         return statements_;
   680     }
   681     void accept(AstVisitor *visitor) {
   682         visitor->visit(this);
   683     }
   684 };
   685 
   686 typedef PoolList<Parameter *> ParameterList;
   687 
   688 class FunctionStatement : public Statement
   689 {
   690     Scope *scope_;
   691     NamedFunction *fun_;
   692     Statement *body_;
   693     ParameterList *parameters_;
   694     bool explicitReturn_;
   695     ScopedRoot<String> tag_;
   696 
   697   public:
   698     FunctionStatement(const SourcePosition &pos, Scope *scope, NamedFunction *fun, Statement *body,
   699                       ParameterList *parameters, Handle<String> returnTag, bool explicitReturn)
   700       : Statement(pos),
   701         scope_(scope),
   702         fun_(fun),
   703         body_(body),
   704         parameters_(parameters),
   705         explicitReturn_(explicitReturn)
   706     {
   707     }
   708 
   709     Kind kind() const {
   710         return kFunctionStatement;
   711     }
   712     Scope *scope() const {
   713         return scope_;
   714     }
   715     NamedFunction *fun() const {
   716         return fun_;
   717     }
   718     Statement *body() const {
   719         return body_;
   720     }
   721     ParameterList *parameters() const {
   722         return parameters_;
   723     }
   724     void accept(AstVisitor *visitor) {
   725         visitor->visit(this);
   726     }
   727     bool hasExplicitReturn() const {
   728         return explicitReturn_;
   729     }
   730     String *returnTag() const {
   731         return tag_;
   732     }
   733 };
   734 
   735 class IfStatement : public Statement
   736 {
   737     Expression *condition_;
   738     Statement *ifTrue_;
   739     Statement *ifFalse_;
   740 
   741   public:
   742     IfStatement(const SourcePosition &pos, Expression *condition, Statement *ifTrue)
   743       : Statement(pos),
   744         condition_(condition),
   745         ifTrue_(ifTrue),
   746         ifFalse_(NULL)
   747     {
   748     }
   749 
   750     Kind kind() const {
   751         return kIfStatement;
   752     }
   753     Expression *condition() const {
   754         return condition_;
   755     }
   756     Statement *ifTrue() const {
   757         return ifTrue_;
   758     }
   759     Statement *ifFalse() const {
   760         return ifFalse_;
   761     }
   762     void setIfFalse(Statement *ifFalse) {
   763         ifFalse_ = ifFalse;
   764     }
   765     void accept(AstVisitor *visitor) {
   766         visitor->visit(this);
   767     }
   768 };
   769 
   770 class EnumStatement : public Statement
   771 {
   772     ScopedRoot<String> name_;
   773 
   774   public:
   775     struct Entry {
   776         NamedConstant *name;
   777         Expression *expr;
   778 
   779         Entry(NamedConstant *name, Expression *expr)
   780           : name(name),
   781             expr(expr)
   782         {
   783         }
   784     };
   785 
   786     typedef PoolList<Entry> EntryList;
   787 
   788   public:
   789     EnumStatement(const SourcePosition &pos, Handle<String> name, EntryList *entries)
   790       : Statement(pos),
   791         name_(name),
   792         entries_(entries)
   793     {
   794     }
   795 
   796     Kind kind() const {
   797         return kEnumStatement;
   798     }
   799     String *name() const {
   800         return name_;
   801     }
   802     EntryList *entries() const {
   803         return entries_;
   804     }
   805     void accept(AstVisitor *visitor) {
   806         visitor->visit(this);
   807     }
   808 
   809   private:
   810     EntryList *entries_;
   811 };
   812 
   813 class IncDecExpression : public Expression
   814 {
   815     TokenKind token_;
   816     Expression *expression_;
   817     bool postfix_;
   818 
   819   public:
   820     IncDecExpression(const SourcePosition &pos, TokenKind token, Expression *expression, bool postfix)
   821       : Expression(pos),
   822         token_(token),
   823         expression_(expression),
   824         postfix_(postfix)
   825     {
   826     }
   827 
   828     Kind kind() const {
   829         return kIncDecExpression;
   830     }
   831     TokenKind token() const {
   832         return token_;
   833     }
   834     Expression *expression() const {
   835         return expression_;
   836     }
   837     bool postfix() const {
   838         return postfix_;
   839     }
   840     void accept(AstVisitor *visitor) {
   841         visitor->visit(this);
   842     }
   843 };
   844 
   845 class Scope;
   846 
   847 typedef PoolList<NameProxy *> NameProxyList;
   848 
   849 class ParseTree : public PoolObject
   850 {
   851     StatementList *statements_;
   852     Scope *scope_;
   853     NameProxyList *unbound_;
   854 
   855   public:
   856     ParseTree(Scope *scope, StatementList *statements, NameProxyList *unbound)
   857       : statements_(statements),
   858         scope_(scope),
   859         unbound_(unbound)
   860     {
   861     }
   862 
   863     void dump(FILE *fp);
   864 
   865     StatementList *statements() const {
   866         return statements_;
   867     }
   868     Scope *scope() const {
   869         return scope_;
   870     }
   871     NameProxyList *unbound() const {
   872         return unbound_;
   873     }
   874 };
   875 
   876 }
   877 
   878 #endif // _include_jitcraft_ast_h_