src/compiler/HIR.h
author David Anderson <dvander@alliedmods.net>
Sat Nov 17 19:07:49 2012 -0800 (2012-11-17)
changeset 196 9904633b1dfc
parent 195 c1ba166f3fc4
child 215 b8f650a441a5
permissions -rw-r--r--
Fix Linux build problems.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of SourcePawn.
     5  *
     6  * SourcePawn 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  * SourcePawn 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  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #ifndef _include_sp2_hir_h_
    19 #define _include_sp2_hir_h_
    20 
    21 #include "../Types.h"
    22 #include "../PoolAllocator.h"
    23 #include "../Opcodes.h"
    24 #include "Symbols.h"
    25 
    26 namespace ke {
    27 
    28 #define HIR_OPS(_)                      \
    29     _(Call)                             \
    30     _(Integer)                          \
    31     _(Float)                            \
    32     _(Store)                            \
    33     /* Special LValue types */          \
    34     _(Index)                            \
    35     _(Local)                            \
    36     _(Global)                           \
    37     /* End LValues */                   \
    38     _(Binary)                           \
    39     _(Convert)
    40 
    41 // Forward declarations.
    42 #define _(name)    class H##name;
    43 HIR_OPS(_)
    44 #undef _
    45 
    46 class HIRVisitor;
    47 
    48 class HIR : public PoolObject
    49 {
    50   public:
    51     enum HOp {
    52 #define _(name) k##name,
    53         HIR_OPS(_)
    54 #undef _
    55         kTotalOps
    56     };
    57 
    58   public:
    59     HIR(Type *type)
    60       : type_(type)
    61     {
    62     }
    63 
    64     Handle<Type> type() {
    65         return type_;
    66     }
    67 
    68     virtual bool isLValue() const {
    69         return false;
    70     }
    71 
    72     virtual HOp op() const = 0;
    73     virtual void accept(HIRVisitor *visitor) = 0;
    74 
    75   private:
    76     ScopedRoot<Type> type_;
    77 };
    78 
    79 class BytecodeEmitter;
    80 
    81 class HIRVisitor
    82 {
    83   public:
    84 #define _(name)                                 \
    85     virtual void visit##name(H##name *hir) {    \
    86         assert(false);                          \
    87     }
    88     HIR_OPS(_)
    89 #undef _
    90 };
    91 
    92 typedef PoolList<HIR *> HIRList;
    93 
    94 #define DEFINE_HIR(name)                        \
    95     virtual HOp op() const {                    \
    96         return k##name;                         \
    97     }                                           \
    98     virtual void accept(HIRVisitor *visitor) {  \
    99         visitor->visit##name(this);             \
   100     }
   101 
   102 class HInteger : public HIR
   103 {
   104   public:
   105     HInteger(Type *type, int value)
   106       : HIR(type),
   107         value_(value)
   108     {
   109     }
   110 
   111     DEFINE_HIR(Integer);
   112     int value() const {
   113         return value_;
   114     }
   115 
   116   private:
   117     int value_;
   118 };
   119 
   120 class HConvert : public HIR
   121 {
   122   public:
   123     HConvert(Type *type, Opcode op, HIR *in)
   124       : HIR(type),
   125         op_(op),
   126         in_(in)
   127     {
   128     }
   129 
   130     DEFINE_HIR(Convert);
   131     Opcode opcode() const {
   132         return op_;
   133     }
   134     HIR *in() const {
   135         return in_;
   136     }
   137 
   138   private:
   139     Opcode op_;
   140     HIR *in_;
   141 };
   142 
   143 class HLValue : public HIR
   144 {
   145   public:
   146     HLValue(Type *type)
   147       : HIR(type)
   148     {
   149     }
   150 
   151     // Pushes a reference to the LValue on the stack.
   152     virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
   153 
   154     // Given a stack layout of the form:
   155     //  [-1]    value
   156     //  [-2..n] ref
   157     //
   158     // Emits a store to the reference.
   159     virtual void store(BytecodeEmitter &emitter_) = 0;
   160     virtual void load(BytecodeEmitter &emitter_) = 0;
   161 
   162     bool isLValue() const {
   163         return true;
   164     }
   165 };
   166 
   167 class HLocal : public HLValue
   168 {
   169   public:
   170     HLocal(VariableSymbol *sym)
   171       : HLValue(sym->type()),
   172         sym_(sym)
   173     {
   174     }
   175 
   176     DEFINE_HIR(Local);
   177 
   178     // Pushes a reference to the LValue on the stack.
   179     void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   180     void store(BytecodeEmitter &emitter_);
   181     void load(BytecodeEmitter &emitter_);
   182 
   183   private:
   184     VariableSymbol *sym_;
   185 };
   186 
   187 class HIndex : public HLValue
   188 {
   189   public:
   190     HIndex(Type *type, HIR *left, HIR *right)
   191       : HLValue(type),
   192         left_(left),
   193         right_(right)
   194     {
   195     }
   196 
   197     DEFINE_HIR(Index);
   198 
   199     void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   200     void store(BytecodeEmitter &emitter_);
   201     void load(BytecodeEmitter &emitter_);
   202 
   203   private:
   204     HIR *left_;
   205     HIR *right_;
   206 };
   207 
   208 class HGlobal : public HLValue
   209 {
   210   public:
   211     HGlobal(Symbol *sym)
   212       : HLValue(sym->type()),
   213         sym_(sym)
   214     {
   215     }
   216 
   217     DEFINE_HIR(Global);
   218 
   219     void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   220     void store(BytecodeEmitter &emitter_);
   221     void load(BytecodeEmitter &emitter_);
   222 
   223     Symbol *sym() const {
   224         return sym_;
   225     }
   226 
   227   private:
   228     Symbol *sym_;
   229 };
   230 
   231 class HBinary : public HIR
   232 {
   233   public:
   234     HBinary(Type *type, TokenKind token, HIR *left, HIR *right)
   235       : HIR(type),
   236         token_(token),
   237         left_(left),
   238         right_(right)
   239     {
   240     }
   241 
   242     DEFINE_HIR(Binary);
   243     TokenKind token() const {
   244         return token_;
   245     }
   246     HIR *left() const {
   247         return left_;
   248     }
   249     HIR *right() const {
   250         return right_;
   251     }
   252 
   253   private:
   254     TokenKind token_;
   255     HIR *left_;
   256     HIR *right_;
   257 };
   258 
   259 class HFloat : public HIR
   260 {
   261   public:
   262     HFloat(Type *type, float value)
   263       : HIR(type),
   264         value_(value)
   265     {
   266     }
   267 
   268     DEFINE_HIR(Float);
   269     float value() const {
   270         return value_;
   271     }
   272 
   273   private:
   274     float value_;
   275 };
   276 
   277 class HStore : public HIR
   278 {
   279   public:
   280     HStore(HLValue *lval, HIR *rval)
   281       : HIR(lval->type()),
   282         lval_(lval),
   283         rval_(rval)
   284     {
   285     }
   286 
   287     DEFINE_HIR(Store);
   288 
   289     HLValue *lval() const {
   290         return lval_;
   291     }
   292     HIR *rval() const {
   293         return rval_;
   294     }
   295 
   296   private:
   297     HLValue *lval_;
   298     HIR *rval_;
   299 };
   300 
   301 class HCall : public HIR
   302 {
   303   public:
   304     HCall(Type *type, HIR *callee, HIRList *args)
   305       : HIR(type),
   306         callee_(callee),
   307         args_(args)
   308     {
   309     }
   310 
   311     DEFINE_HIR(Call);
   312 
   313     HIR *callee() const {
   314         return callee_;
   315     }
   316     HIRList *args() const {
   317         return args_;
   318     }
   319 
   320   private:
   321     HIR *callee_;
   322     HIRList *args_;
   323 };
   324 
   325 #undef DEFINE_HIR
   326 
   327 void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
   328 
   329 }
   330 
   331 #endif // _include_sp2_hir_h_