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