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