src/compiler/HIR.h
changeset 263 ba85a47ee414
parent 256 3c184218462d
     1.1 --- a/src/compiler/HIR.h	Mon Jun 10 00:46:29 2013 +0100
     1.2 +++ b/src/compiler/HIR.h	Mon Jun 10 01:04:43 2013 +0100
     1.3 @@ -1,607 +1,607 @@
     1.4 -/*
     1.5 - * Copyright (C) 2012 David Anderson
     1.6 - *
     1.7 - * This file is part of SourcePawn.
     1.8 - *
     1.9 - * SourcePawn is free software: you can redistribute it and/or modify it under
    1.10 - * the terms of the GNU General Public License as published by the Free
    1.11 - * Software Foundation, either version 3 of the License, or (at your option)
    1.12 - * any later version.
    1.13 - * 
    1.14 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    1.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    1.17 - *
    1.18 - * You should have received a copy of the GNU General Public License along with
    1.19 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
    1.20 - */
    1.21 -#ifndef _include_sp2_hir_h_
    1.22 -#define _include_sp2_hir_h_
    1.23 -
    1.24 -#include "../Types.h"
    1.25 -#include "../PoolAllocator.h"
    1.26 -#include "../Opcodes.h"
    1.27 -#include "Symbols.h"
    1.28 -
    1.29 -namespace ke {
    1.30 -
    1.31 -#define HIR_OPS(_)                      \
    1.32 -    _(Call)                             \
    1.33 -    _(Boolean)                          \
    1.34 -    _(Integer)                          \
    1.35 -    _(Float)                            \
    1.36 -    _(String)                           \
    1.37 -    _(Import)                           \
    1.38 -    _(Array)                            \
    1.39 -    _(Store)                            \
    1.40 -    _(ToRef)                            \
    1.41 -    _(NewDependentArray)                \
    1.42 -    /* Special LValue types */          \
    1.43 -    _(Index)                            \
    1.44 -    _(Local)                            \
    1.45 -    _(Global)                           \
    1.46 -    _(Field)                            \
    1.47 -    /* End LValues */                   \
    1.48 -    _(Unary)                            \
    1.49 -    _(Binary)                           \
    1.50 -    _(Convert)                          \
    1.51 -    _(PostIncDec)
    1.52 -
    1.53 -// Forward declarations.
    1.54 -#define _(name)    class H##name;
    1.55 -HIR_OPS(_)
    1.56 -#undef _
    1.57 -
    1.58 -class HIRVisitor;
    1.59 -class AstNode;
    1.60 -class HLValue;
    1.61 -class Array;
    1.62 -
    1.63 -class HIR : public PoolObject
    1.64 -{
    1.65 -  public:
    1.66 -    enum HOp {
    1.67 -#define _(name) k##name,
    1.68 -        HIR_OPS(_)
    1.69 -#undef _
    1.70 -        kTotalOps
    1.71 -    };
    1.72 -
    1.73 -  public:
    1.74 -    HIR(AstNode *node, Type *type)
    1.75 -      : node_(node),
    1.76 -        type_(type)
    1.77 -    {
    1.78 -    }
    1.79 -
    1.80 -    Handle<Type> type() {
    1.81 -        return type_;
    1.82 -    }
    1.83 -    AstNode *node() const {
    1.84 -        return node_;
    1.85 -    }
    1.86 -
    1.87 -    virtual bool isLValue() const {
    1.88 -        return false;
    1.89 -    }
    1.90 -
    1.91 -    virtual HOp op() const = 0;
    1.92 -    virtual void accept(HIRVisitor *visitor) = 0;
    1.93 -
    1.94 -#define _(name)                                         \
    1.95 -    bool is##name() const {                             \
    1.96 -        return op() == k##name;                         \
    1.97 -    }                                                   \
    1.98 -    H##name *to##name() {                               \
    1.99 -        assert(is##name());                             \
   1.100 -        return reinterpret_cast<H##name *>(this);       \
   1.101 -    }
   1.102 -    HIR_OPS(_)
   1.103 -#undef _
   1.104 -
   1.105 -    HLValue *toLValue() {
   1.106 -        assert(isLValue());
   1.107 -        return reinterpret_cast<HLValue *>(this);
   1.108 -    }
   1.109 -
   1.110 -  private:
   1.111 -    AstNode *node_;
   1.112 -    ScopedRoot<Type> type_;
   1.113 -};
   1.114 -
   1.115 -class BytecodeEmitter;
   1.116 -
   1.117 -class HIRVisitor
   1.118 -{
   1.119 -  public:
   1.120 -#define _(name)                                 \
   1.121 -    virtual void visit##name(H##name *hir) {    \
   1.122 -        assert(false);                          \
   1.123 -    }
   1.124 -    HIR_OPS(_)
   1.125 -#undef _
   1.126 -};
   1.127 -
   1.128 -typedef PoolList<HIR *> HIRList;
   1.129 -
   1.130 -#define DEFINE_HIR(name)                        \
   1.131 -    virtual HOp op() const {                    \
   1.132 -        return k##name;                         \
   1.133 -    }                                           \
   1.134 -    virtual void accept(HIRVisitor *visitor) {  \
   1.135 -        visitor->visit##name(this);             \
   1.136 -    }
   1.137 -
   1.138 -class HBoolean : public HIR
   1.139 -{
   1.140 -  public:
   1.141 -    HBoolean(AstNode *node, Type *type, bool value)
   1.142 -      : HIR(node, type),
   1.143 -        value_(value)
   1.144 -    {
   1.145 -    }
   1.146 -
   1.147 -    DEFINE_HIR(Boolean);
   1.148 -    bool value() const {
   1.149 -        return value_;
   1.150 -    }
   1.151 -
   1.152 -  private:
   1.153 -    bool value_;
   1.154 -};
   1.155 -
   1.156 -class HInteger : public HIR
   1.157 -{
   1.158 -  public:
   1.159 -    HInteger(AstNode *node, Type *type, int value)
   1.160 -      : HIR(node, type),
   1.161 -        value_(value)
   1.162 -    {
   1.163 -    }
   1.164 -
   1.165 -    DEFINE_HIR(Integer);
   1.166 -    int value() const {
   1.167 -        return value_;
   1.168 -    }
   1.169 -
   1.170 -  private:
   1.171 -    int value_;
   1.172 -};
   1.173 -
   1.174 -class HString : public HIR
   1.175 -{
   1.176 -  public:
   1.177 -    HString(AstNode *node, Type *type, String *string)
   1.178 -      : HIR(node, type),
   1.179 -        string_(string)
   1.180 -    {
   1.181 -    }
   1.182 -
   1.183 -    DEFINE_HIR(String);
   1.184 -    Handle<String> string() const {
   1.185 -        return string_;
   1.186 -    }
   1.187 -
   1.188 -  private:
   1.189 -    ScopedRoot<String> string_;
   1.190 -};
   1.191 -
   1.192 -class HImport : public HIR
   1.193 -{
   1.194 -  public:
   1.195 -    HImport(AstNode *node, Type *type, unsigned index)
   1.196 -      : HIR(node, type),
   1.197 -        index_(index)
   1.198 -    {
   1.199 -    }
   1.200 -
   1.201 -    DEFINE_HIR(Import);
   1.202 -    unsigned index() const {
   1.203 -        return index_;
   1.204 -    }
   1.205 -
   1.206 -  private:
   1.207 -    unsigned index_;
   1.208 -};
   1.209 -
   1.210 -class HArray : public HIR
   1.211 -{
   1.212 -  public:
   1.213 -    HArray(AstNode *node, Type *type, Array *array, bool duplicate)
   1.214 -      : HIR(node, type),
   1.215 -        array_(array),
   1.216 -        duplicate_(duplicate)
   1.217 -    {
   1.218 -    }
   1.219 -
   1.220 -    DEFINE_HIR(Array);
   1.221 -    Handle<Array> array() const {
   1.222 -        return array_;
   1.223 -    }
   1.224 -    bool duplicate() const {
   1.225 -        return duplicate_;
   1.226 -    }
   1.227 -
   1.228 -  private:
   1.229 -    ScopedRoot<Array> array_;
   1.230 -    bool duplicate_;
   1.231 -};
   1.232 -
   1.233 -class HConvert : public HIR
   1.234 -{
   1.235 -  public:
   1.236 -    HConvert(AstNode *node, Type *type, Opcode op, HIR *in)
   1.237 -      : HIR(node, type),
   1.238 -        op_(op),
   1.239 -        in_(in)
   1.240 -    {
   1.241 -    }
   1.242 -
   1.243 -    DEFINE_HIR(Convert);
   1.244 -    Opcode opcode() const {
   1.245 -        return op_;
   1.246 -    }
   1.247 -    HIR *in() const {
   1.248 -        return in_;
   1.249 -    }
   1.250 -
   1.251 -  private:
   1.252 -    Opcode op_;
   1.253 -    HIR *in_;
   1.254 -};
   1.255 -
   1.256 -class HLValue : public HIR
   1.257 -{
   1.258 -  public:
   1.259 -    HLValue(AstNode *node, Type *type)
   1.260 -      : HIR(node, type)
   1.261 -    {
   1.262 -    }
   1.263 -
   1.264 -    // Pushes a reference to the LValue on the stack.
   1.265 -    virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
   1.266 -    
   1.267 -    // Duplicates a stack reference.
   1.268 -    virtual void hold(BytecodeEmitter &emitter_) = 0;
   1.269 -
   1.270 -    // Reorders the stack for a post-increment operation:
   1.271 -    //   REF VAL -> VAL REF VAL
   1.272 -    virtual void swapAndPick(BytecodeEmitter &emitter_) = 0;
   1.273 -
   1.274 -    // Given a stack layout of the form:
   1.275 -    //  [-1]    value
   1.276 -    //  [-2..n] ref
   1.277 -    //
   1.278 -    // Emits a store to the reference.
   1.279 -    virtual void store(BytecodeEmitter &emitter_) = 0;
   1.280 -    virtual void load(BytecodeEmitter &emitter_) = 0;
   1.281 -
   1.282 -    // Try to make a direct reference, if semantics allow it. False if the
   1.283 -    // caller must allocate a reference to the stack.
   1.284 -    virtual bool ref(BytecodeEmitter &emitter_) = 0;
   1.285 -
   1.286 -    bool isLValue() const {
   1.287 -        return true;
   1.288 -    }
   1.289 -};
   1.290 -
   1.291 -class HLocal : public HLValue
   1.292 -{
   1.293 -  public:
   1.294 -    HLocal(AstNode *node, VariableSymbol *sym);
   1.295 -
   1.296 -    DEFINE_HIR(Local);
   1.297 -
   1.298 -    // Pushes a reference to the LValue on the stack.
   1.299 -    void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   1.300 -    void hold(BytecodeEmitter &emitter_);
   1.301 -    void swapAndPick(BytecodeEmitter &emitter_);
   1.302 -    void store(BytecodeEmitter &emitter_);
   1.303 -    void load(BytecodeEmitter &emitter_);
   1.304 -    bool ref(BytecodeEmitter &emitter_);
   1.305 -
   1.306 -    VariableSymbol *sym() const {
   1.307 -        return sym_;
   1.308 -    }
   1.309 -
   1.310 -  private:
   1.311 -    VariableSymbol *sym_;
   1.312 -};
   1.313 -
   1.314 -class HIndex : public HLValue
   1.315 -{
   1.316 -  public:
   1.317 -    HIndex(AstNode *node, Type *type, HIR *left, HIR *right)
   1.318 -      : HLValue(node, type),
   1.319 -        left_(left),
   1.320 -        right_(right)
   1.321 -    {
   1.322 -    }
   1.323 -
   1.324 -    DEFINE_HIR(Index);
   1.325 -
   1.326 -    void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   1.327 -    void hold(BytecodeEmitter &emitter_);
   1.328 -    void swapAndPick(BytecodeEmitter &emitter_);
   1.329 -    void store(BytecodeEmitter &emitter_);
   1.330 -    void load(BytecodeEmitter &emitter_);
   1.331 -    bool ref(BytecodeEmitter &emitter_);
   1.332 -
   1.333 -    HIR *base() const {
   1.334 -        return left_;
   1.335 -    }
   1.336 -    HIR *index() const {
   1.337 -        return right_;
   1.338 -    }
   1.339 -
   1.340 -  private:
   1.341 -    HIR *left_;
   1.342 -    HIR *right_;
   1.343 -};
   1.344 -
   1.345 -class HField : public HLValue
   1.346 -{
   1.347 -  public:
   1.348 -    HField(AstNode *node, HIR *left, Type *type, unsigned index)
   1.349 -      : HLValue(node, type),
   1.350 -        base_(left),
   1.351 -        index_(index)
   1.352 -    {
   1.353 -    }
   1.354 -
   1.355 -    DEFINE_HIR(Field);
   1.356 -
   1.357 -    void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   1.358 -    void hold(BytecodeEmitter &emitter_);
   1.359 -    void swapAndPick(BytecodeEmitter &emitter_);
   1.360 -    void store(BytecodeEmitter &emitter_);
   1.361 -    void load(BytecodeEmitter &emitter_);
   1.362 -    bool ref(BytecodeEmitter &emitter_);
   1.363 -
   1.364 -    HIR *base() const {
   1.365 -        return base_;
   1.366 -    }
   1.367 -    unsigned index() const {
   1.368 -        return index_;
   1.369 -    }
   1.370 -
   1.371 -  private:
   1.372 -    HIR *base_;
   1.373 -    unsigned index_;
   1.374 -};
   1.375 -
   1.376 -class HGlobal : public HLValue
   1.377 -{
   1.378 -  public:
   1.379 -    HGlobal(AstNode *node, Symbol *sym)
   1.380 -      : HLValue(node, sym->type()),
   1.381 -        sym_(sym)
   1.382 -    {
   1.383 -    }
   1.384 -
   1.385 -    DEFINE_HIR(Global);
   1.386 -
   1.387 -    void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   1.388 -    void hold(BytecodeEmitter &emitter_);
   1.389 -    void swapAndPick(BytecodeEmitter &emitter_);
   1.390 -    void store(BytecodeEmitter &emitter_);
   1.391 -    void load(BytecodeEmitter &emitter_);
   1.392 -    bool ref(BytecodeEmitter &emitter_);
   1.393 -
   1.394 -    Symbol *sym() const {
   1.395 -        return sym_;
   1.396 -    }
   1.397 -
   1.398 -  private:
   1.399 -    Symbol *sym_;
   1.400 -};
   1.401 -
   1.402 -class HBinary : public HIR
   1.403 -{
   1.404 -  public:
   1.405 -    HBinary(AstNode *node, Type *type, TokenKind token, HIR *left, HIR *right)
   1.406 -      : HIR(node, type),
   1.407 -        token_(token),
   1.408 -        left_(left),
   1.409 -        right_(right)
   1.410 -    {
   1.411 -    }
   1.412 -
   1.413 -    DEFINE_HIR(Binary);
   1.414 -    TokenKind token() const {
   1.415 -        return token_;
   1.416 -    }
   1.417 -    HIR *left() const {
   1.418 -        return left_;
   1.419 -    }
   1.420 -    HIR *right() const {
   1.421 -        return right_;
   1.422 -    }
   1.423 -
   1.424 -  private:
   1.425 -    TokenKind token_;
   1.426 -    HIR *left_;
   1.427 -    HIR *right_;
   1.428 -};
   1.429 -
   1.430 -class HFloat : public HIR
   1.431 -{
   1.432 -  public:
   1.433 -    HFloat(AstNode *node, Type *type, float value)
   1.434 -      : HIR(node, type),
   1.435 -        value_(value)
   1.436 -    {
   1.437 -    }
   1.438 -
   1.439 -    DEFINE_HIR(Float);
   1.440 -    float value() const {
   1.441 -        return value_;
   1.442 -    }
   1.443 -
   1.444 -  private:
   1.445 -    float value_;
   1.446 -};
   1.447 -
   1.448 -class HUnary : public HIR
   1.449 -{
   1.450 -  public:
   1.451 -    HUnary(AstNode *node, Type *type, TokenKind tok, HIR *in)
   1.452 -      : HIR(node, type),
   1.453 -        in_(in),
   1.454 -        token_(tok)
   1.455 -    {
   1.456 -    }
   1.457 -
   1.458 -    DEFINE_HIR(Unary);
   1.459 -    HIR *in() const {
   1.460 -        return in_;
   1.461 -    }
   1.462 -    TokenKind token() const {
   1.463 -        return token_;
   1.464 -    }
   1.465 -
   1.466 -  private:
   1.467 -    HIR *in_;
   1.468 -    TokenKind token_;
   1.469 -};
   1.470 -
   1.471 -class HStore : public HIR
   1.472 -{
   1.473 -  public:
   1.474 -    HStore(AstNode *node, HLValue *lval, HIR *rval)
   1.475 -      : HIR(node, lval->type()),
   1.476 -        kind_(TOK_ASSIGN),
   1.477 -        lval_(lval),
   1.478 -        rval_(rval)
   1.479 -    {
   1.480 -    }
   1.481 -
   1.482 -    HStore(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
   1.483 -      : HIR(node, lval->type()),
   1.484 -        kind_(kind),
   1.485 -        lval_(lval),
   1.486 -        rval_(rval)
   1.487 -    {
   1.488 -    }
   1.489 -
   1.490 -    DEFINE_HIR(Store);
   1.491 -
   1.492 -    HLValue *lval() const {
   1.493 -        return lval_;
   1.494 -    }
   1.495 -    HIR *rval() const {
   1.496 -        return rval_;
   1.497 -    }
   1.498 -    TokenKind kind() const {
   1.499 -        return kind_;
   1.500 -    }
   1.501 -
   1.502 -  private:
   1.503 -    TokenKind kind_;
   1.504 -    HLValue *lval_;
   1.505 -    HIR *rval_;
   1.506 -};
   1.507 -
   1.508 -class HPostIncDec : public HIR
   1.509 -{
   1.510 -  public:
   1.511 -    HPostIncDec(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
   1.512 -      : HIR(node, lval->type()),
   1.513 -        kind_(kind),
   1.514 -        lval_(lval),
   1.515 -        rval_(rval)
   1.516 -    {
   1.517 -    }
   1.518 -
   1.519 -    DEFINE_HIR(PostIncDec);
   1.520 -
   1.521 -    HLValue *lval() const {
   1.522 -        return lval_;
   1.523 -    }
   1.524 -    HIR *rval() const {
   1.525 -        return rval_;
   1.526 -    }
   1.527 -    TokenKind kind() const {
   1.528 -        return kind_;
   1.529 -    }
   1.530 -
   1.531 -  private:
   1.532 -    TokenKind kind_;
   1.533 -    HLValue *lval_;
   1.534 -    HIR *rval_;
   1.535 -};
   1.536 -
   1.537 -class HCall : public HIR
   1.538 -{
   1.539 -  public:
   1.540 -    HCall(AstNode *node, Type *type, HIR *callee, HIRList *args)
   1.541 -      : HIR(node, type),
   1.542 -        callee_(callee),
   1.543 -        args_(args)
   1.544 -    {
   1.545 -    }
   1.546 -
   1.547 -    DEFINE_HIR(Call);
   1.548 -
   1.549 -    HIR *callee() const {
   1.550 -        return callee_;
   1.551 -    }
   1.552 -    HIRList *args() const {
   1.553 -        return args_;
   1.554 -    }
   1.555 -
   1.556 -  private:
   1.557 -    HIR *callee_;
   1.558 -    HIRList *args_;
   1.559 -};
   1.560 -
   1.561 -class HToRef : public HIR
   1.562 -{
   1.563 -  public:
   1.564 -    HToRef(AstNode *node, Type *type, HIR *in)
   1.565 -      : HIR(node, type),
   1.566 -        in_(in)
   1.567 -    {
   1.568 -    }
   1.569 -
   1.570 -    DEFINE_HIR(ToRef);
   1.571 -
   1.572 -    HIR *in() const {
   1.573 -        return in_;
   1.574 -    }
   1.575 -
   1.576 -  private:
   1.577 -    HIR *in_;
   1.578 -};
   1.579 -
   1.580 -class HNewDependentArray : public HIR
   1.581 -{
   1.582 -  public:
   1.583 -    HNewDependentArray(AstNode *node, Type *type, HIR *base, HIR *index)
   1.584 -      : HIR(node, type),
   1.585 -        base_(base),
   1.586 -        index_(index)
   1.587 -    {
   1.588 -    }
   1.589 -
   1.590 -    DEFINE_HIR(NewDependentArray);
   1.591 -
   1.592 -    HIR *base() const {
   1.593 -        return base_;
   1.594 -    }
   1.595 -    HIR *index() const {
   1.596 -        return index_;
   1.597 -    }
   1.598 -
   1.599 -  private:
   1.600 -    HIR *base_;
   1.601 -    HIR *index_;
   1.602 -};
   1.603 -
   1.604 -#undef DEFINE_HIR
   1.605 -
   1.606 -void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
   1.607 -
   1.608 -}
   1.609 -
   1.610 -#endif // _include_sp2_hir_h_
   1.611 +/*
   1.612 + * Copyright (C) 2012 David Anderson
   1.613 + *
   1.614 + * This file is part of SourcePawn.
   1.615 + *
   1.616 + * SourcePawn is free software: you can redistribute it and/or modify it under
   1.617 + * the terms of the GNU General Public License as published by the Free
   1.618 + * Software Foundation, either version 3 of the License, or (at your option)
   1.619 + * any later version.
   1.620 + * 
   1.621 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   1.622 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   1.623 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   1.624 + *
   1.625 + * You should have received a copy of the GNU General Public License along with
   1.626 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
   1.627 + */
   1.628 +#ifndef _include_sp2_hir_h_
   1.629 +#define _include_sp2_hir_h_
   1.630 +
   1.631 +#include "../Types.h"
   1.632 +#include "../PoolAllocator.h"
   1.633 +#include "../Opcodes.h"
   1.634 +#include "Symbols.h"
   1.635 +
   1.636 +namespace ke {
   1.637 +
   1.638 +#define HIR_OPS(_)                      \
   1.639 +    _(Call)                             \
   1.640 +    _(Boolean)                          \
   1.641 +    _(Integer)                          \
   1.642 +    _(Float)                            \
   1.643 +    _(String)                           \
   1.644 +    _(Import)                           \
   1.645 +    _(Array)                            \
   1.646 +    _(Store)                            \
   1.647 +    _(ToRef)                            \
   1.648 +    _(NewDependentArray)                \
   1.649 +    /* Special LValue types */          \
   1.650 +    _(Index)                            \
   1.651 +    _(Local)                            \
   1.652 +    _(Global)                           \
   1.653 +    _(Field)                            \
   1.654 +    /* End LValues */                   \
   1.655 +    _(Unary)                            \
   1.656 +    _(Binary)                           \
   1.657 +    _(Convert)                          \
   1.658 +    _(PostIncDec)
   1.659 +
   1.660 +// Forward declarations.
   1.661 +#define _(name)    class H##name;
   1.662 +HIR_OPS(_)
   1.663 +#undef _
   1.664 +
   1.665 +class HIRVisitor;
   1.666 +class AstNode;
   1.667 +class HLValue;
   1.668 +class Array;
   1.669 +
   1.670 +class HIR : public PoolObject
   1.671 +{
   1.672 +  public:
   1.673 +    enum HOp {
   1.674 +#define _(name) k##name,
   1.675 +        HIR_OPS(_)
   1.676 +#undef _
   1.677 +        kTotalOps
   1.678 +    };
   1.679 +
   1.680 +  public:
   1.681 +    HIR(AstNode *node, Type *type)
   1.682 +      : node_(node),
   1.683 +        type_(type)
   1.684 +    {
   1.685 +    }
   1.686 +
   1.687 +    Handle<Type> type() {
   1.688 +        return type_;
   1.689 +    }
   1.690 +    AstNode *node() const {
   1.691 +        return node_;
   1.692 +    }
   1.693 +
   1.694 +    virtual bool isLValue() const {
   1.695 +        return false;
   1.696 +    }
   1.697 +
   1.698 +    virtual HOp op() const = 0;
   1.699 +    virtual void accept(HIRVisitor *visitor) = 0;
   1.700 +
   1.701 +#define _(name)                                         \
   1.702 +    bool is##name() const {                             \
   1.703 +        return op() == k##name;                         \
   1.704 +    }                                                   \
   1.705 +    H##name *to##name() {                               \
   1.706 +        assert(is##name());                             \
   1.707 +        return reinterpret_cast<H##name *>(this);       \
   1.708 +    }
   1.709 +    HIR_OPS(_)
   1.710 +#undef _
   1.711 +
   1.712 +    HLValue *toLValue() {
   1.713 +        assert(isLValue());
   1.714 +        return reinterpret_cast<HLValue *>(this);
   1.715 +    }
   1.716 +
   1.717 +  private:
   1.718 +    AstNode *node_;
   1.719 +    ScopedRoot<Type> type_;
   1.720 +};
   1.721 +
   1.722 +class BytecodeEmitter;
   1.723 +
   1.724 +class HIRVisitor
   1.725 +{
   1.726 +  public:
   1.727 +#define _(name)                                 \
   1.728 +    virtual void visit##name(H##name *hir) {    \
   1.729 +        assert(false);                          \
   1.730 +    }
   1.731 +    HIR_OPS(_)
   1.732 +#undef _
   1.733 +};
   1.734 +
   1.735 +typedef PoolList<HIR *> HIRList;
   1.736 +
   1.737 +#define DEFINE_HIR(name)                        \
   1.738 +    virtual HOp op() const {                    \
   1.739 +        return k##name;                         \
   1.740 +    }                                           \
   1.741 +    virtual void accept(HIRVisitor *visitor) {  \
   1.742 +        visitor->visit##name(this);             \
   1.743 +    }
   1.744 +
   1.745 +class HBoolean : public HIR
   1.746 +{
   1.747 +  public:
   1.748 +    HBoolean(AstNode *node, Type *type, bool value)
   1.749 +      : HIR(node, type),
   1.750 +        value_(value)
   1.751 +    {
   1.752 +    }
   1.753 +
   1.754 +    DEFINE_HIR(Boolean);
   1.755 +    bool value() const {
   1.756 +        return value_;
   1.757 +    }
   1.758 +
   1.759 +  private:
   1.760 +    bool value_;
   1.761 +};
   1.762 +
   1.763 +class HInteger : public HIR
   1.764 +{
   1.765 +  public:
   1.766 +    HInteger(AstNode *node, Type *type, int value)
   1.767 +      : HIR(node, type),
   1.768 +        value_(value)
   1.769 +    {
   1.770 +    }
   1.771 +
   1.772 +    DEFINE_HIR(Integer);
   1.773 +    int value() const {
   1.774 +        return value_;
   1.775 +    }
   1.776 +
   1.777 +  private:
   1.778 +    int value_;
   1.779 +};
   1.780 +
   1.781 +class HString : public HIR
   1.782 +{
   1.783 +  public:
   1.784 +    HString(AstNode *node, Type *type, String *string)
   1.785 +      : HIR(node, type),
   1.786 +        string_(string)
   1.787 +    {
   1.788 +    }
   1.789 +
   1.790 +    DEFINE_HIR(String);
   1.791 +    Handle<String> string() const {
   1.792 +        return string_;
   1.793 +    }
   1.794 +
   1.795 +  private:
   1.796 +    ScopedRoot<String> string_;
   1.797 +};
   1.798 +
   1.799 +class HImport : public HIR
   1.800 +{
   1.801 +  public:
   1.802 +    HImport(AstNode *node, Type *type, unsigned index)
   1.803 +      : HIR(node, type),
   1.804 +        index_(index)
   1.805 +    {
   1.806 +    }
   1.807 +
   1.808 +    DEFINE_HIR(Import);
   1.809 +    unsigned index() const {
   1.810 +        return index_;
   1.811 +    }
   1.812 +
   1.813 +  private:
   1.814 +    unsigned index_;
   1.815 +};
   1.816 +
   1.817 +class HArray : public HIR
   1.818 +{
   1.819 +  public:
   1.820 +    HArray(AstNode *node, Type *type, Array *array, bool duplicate)
   1.821 +      : HIR(node, type),
   1.822 +        array_(array),
   1.823 +        duplicate_(duplicate)
   1.824 +    {
   1.825 +    }
   1.826 +
   1.827 +    DEFINE_HIR(Array);
   1.828 +    Handle<Array> array() const {
   1.829 +        return array_;
   1.830 +    }
   1.831 +    bool duplicate() const {
   1.832 +        return duplicate_;
   1.833 +    }
   1.834 +
   1.835 +  private:
   1.836 +    ScopedRoot<Array> array_;
   1.837 +    bool duplicate_;
   1.838 +};
   1.839 +
   1.840 +class HConvert : public HIR
   1.841 +{
   1.842 +  public:
   1.843 +    HConvert(AstNode *node, Type *type, Opcode op, HIR *in)
   1.844 +      : HIR(node, type),
   1.845 +        op_(op),
   1.846 +        in_(in)
   1.847 +    {
   1.848 +    }
   1.849 +
   1.850 +    DEFINE_HIR(Convert);
   1.851 +    Opcode opcode() const {
   1.852 +        return op_;
   1.853 +    }
   1.854 +    HIR *in() const {
   1.855 +        return in_;
   1.856 +    }
   1.857 +
   1.858 +  private:
   1.859 +    Opcode op_;
   1.860 +    HIR *in_;
   1.861 +};
   1.862 +
   1.863 +class HLValue : public HIR
   1.864 +{
   1.865 +  public:
   1.866 +    HLValue(AstNode *node, Type *type)
   1.867 +      : HIR(node, type)
   1.868 +    {
   1.869 +    }
   1.870 +
   1.871 +    // Pushes a reference to the LValue on the stack.
   1.872 +    virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
   1.873 +    
   1.874 +    // Duplicates a stack reference.
   1.875 +    virtual void hold(BytecodeEmitter &emitter_) = 0;
   1.876 +
   1.877 +    // Reorders the stack for a post-increment operation:
   1.878 +    //   REF VAL -> VAL REF VAL
   1.879 +    virtual void swapAndPick(BytecodeEmitter &emitter_) = 0;
   1.880 +
   1.881 +    // Given a stack layout of the form:
   1.882 +    //  [-1]    value
   1.883 +    //  [-2..n] ref
   1.884 +    //
   1.885 +    // Emits a store to the reference.
   1.886 +    virtual void store(BytecodeEmitter &emitter_) = 0;
   1.887 +    virtual void load(BytecodeEmitter &emitter_) = 0;
   1.888 +
   1.889 +    // Try to make a direct reference, if semantics allow it. False if the
   1.890 +    // caller must allocate a reference to the stack.
   1.891 +    virtual bool ref(BytecodeEmitter &emitter_) = 0;
   1.892 +
   1.893 +    bool isLValue() const {
   1.894 +        return true;
   1.895 +    }
   1.896 +};
   1.897 +
   1.898 +class HLocal : public HLValue
   1.899 +{
   1.900 +  public:
   1.901 +    HLocal(AstNode *node, VariableSymbol *sym);
   1.902 +
   1.903 +    DEFINE_HIR(Local);
   1.904 +
   1.905 +    // Pushes a reference to the LValue on the stack.
   1.906 +    void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   1.907 +    void hold(BytecodeEmitter &emitter_);
   1.908 +    void swapAndPick(BytecodeEmitter &emitter_);
   1.909 +    void store(BytecodeEmitter &emitter_);
   1.910 +    void load(BytecodeEmitter &emitter_);
   1.911 +    bool ref(BytecodeEmitter &emitter_);
   1.912 +
   1.913 +    VariableSymbol *sym() const {
   1.914 +        return sym_;
   1.915 +    }
   1.916 +
   1.917 +  private:
   1.918 +    VariableSymbol *sym_;
   1.919 +};
   1.920 +
   1.921 +class HIndex : public HLValue
   1.922 +{
   1.923 +  public:
   1.924 +    HIndex(AstNode *node, Type *type, HIR *left, HIR *right)
   1.925 +      : HLValue(node, type),
   1.926 +        left_(left),
   1.927 +        right_(right)
   1.928 +    {
   1.929 +    }
   1.930 +
   1.931 +    DEFINE_HIR(Index);
   1.932 +
   1.933 +    void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   1.934 +    void hold(BytecodeEmitter &emitter_);
   1.935 +    void swapAndPick(BytecodeEmitter &emitter_);
   1.936 +    void store(BytecodeEmitter &emitter_);
   1.937 +    void load(BytecodeEmitter &emitter_);
   1.938 +    bool ref(BytecodeEmitter &emitter_);
   1.939 +
   1.940 +    HIR *base() const {
   1.941 +        return left_;
   1.942 +    }
   1.943 +    HIR *index() const {
   1.944 +        return right_;
   1.945 +    }
   1.946 +
   1.947 +  private:
   1.948 +    HIR *left_;
   1.949 +    HIR *right_;
   1.950 +};
   1.951 +
   1.952 +class HField : public HLValue
   1.953 +{
   1.954 +  public:
   1.955 +    HField(AstNode *node, HIR *left, Type *type, unsigned index)
   1.956 +      : HLValue(node, type),
   1.957 +        base_(left),
   1.958 +        index_(index)
   1.959 +    {
   1.960 +    }
   1.961 +
   1.962 +    DEFINE_HIR(Field);
   1.963 +
   1.964 +    void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   1.965 +    void hold(BytecodeEmitter &emitter_);
   1.966 +    void swapAndPick(BytecodeEmitter &emitter_);
   1.967 +    void store(BytecodeEmitter &emitter_);
   1.968 +    void load(BytecodeEmitter &emitter_);
   1.969 +    bool ref(BytecodeEmitter &emitter_);
   1.970 +
   1.971 +    HIR *base() const {
   1.972 +        return base_;
   1.973 +    }
   1.974 +    unsigned index() const {
   1.975 +        return index_;
   1.976 +    }
   1.977 +
   1.978 +  private:
   1.979 +    HIR *base_;
   1.980 +    unsigned index_;
   1.981 +};
   1.982 +
   1.983 +class HGlobal : public HLValue
   1.984 +{
   1.985 +  public:
   1.986 +    HGlobal(AstNode *node, Symbol *sym)
   1.987 +      : HLValue(node, sym->type()),
   1.988 +        sym_(sym)
   1.989 +    {
   1.990 +    }
   1.991 +
   1.992 +    DEFINE_HIR(Global);
   1.993 +
   1.994 +    void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
   1.995 +    void hold(BytecodeEmitter &emitter_);
   1.996 +    void swapAndPick(BytecodeEmitter &emitter_);
   1.997 +    void store(BytecodeEmitter &emitter_);
   1.998 +    void load(BytecodeEmitter &emitter_);
   1.999 +    bool ref(BytecodeEmitter &emitter_);
  1.1000 +
  1.1001 +    Symbol *sym() const {
  1.1002 +        return sym_;
  1.1003 +    }
  1.1004 +
  1.1005 +  private:
  1.1006 +    Symbol *sym_;
  1.1007 +};
  1.1008 +
  1.1009 +class HBinary : public HIR
  1.1010 +{
  1.1011 +  public:
  1.1012 +    HBinary(AstNode *node, Type *type, TokenKind token, HIR *left, HIR *right)
  1.1013 +      : HIR(node, type),
  1.1014 +        token_(token),
  1.1015 +        left_(left),
  1.1016 +        right_(right)
  1.1017 +    {
  1.1018 +    }
  1.1019 +
  1.1020 +    DEFINE_HIR(Binary);
  1.1021 +    TokenKind token() const {
  1.1022 +        return token_;
  1.1023 +    }
  1.1024 +    HIR *left() const {
  1.1025 +        return left_;
  1.1026 +    }
  1.1027 +    HIR *right() const {
  1.1028 +        return right_;
  1.1029 +    }
  1.1030 +
  1.1031 +  private:
  1.1032 +    TokenKind token_;
  1.1033 +    HIR *left_;
  1.1034 +    HIR *right_;
  1.1035 +};
  1.1036 +
  1.1037 +class HFloat : public HIR
  1.1038 +{
  1.1039 +  public:
  1.1040 +    HFloat(AstNode *node, Type *type, float value)
  1.1041 +      : HIR(node, type),
  1.1042 +        value_(value)
  1.1043 +    {
  1.1044 +    }
  1.1045 +
  1.1046 +    DEFINE_HIR(Float);
  1.1047 +    float value() const {
  1.1048 +        return value_;
  1.1049 +    }
  1.1050 +
  1.1051 +  private:
  1.1052 +    float value_;
  1.1053 +};
  1.1054 +
  1.1055 +class HUnary : public HIR
  1.1056 +{
  1.1057 +  public:
  1.1058 +    HUnary(AstNode *node, Type *type, TokenKind tok, HIR *in)
  1.1059 +      : HIR(node, type),
  1.1060 +        in_(in),
  1.1061 +        token_(tok)
  1.1062 +    {
  1.1063 +    }
  1.1064 +
  1.1065 +    DEFINE_HIR(Unary);
  1.1066 +    HIR *in() const {
  1.1067 +        return in_;
  1.1068 +    }
  1.1069 +    TokenKind token() const {
  1.1070 +        return token_;
  1.1071 +    }
  1.1072 +
  1.1073 +  private:
  1.1074 +    HIR *in_;
  1.1075 +    TokenKind token_;
  1.1076 +};
  1.1077 +
  1.1078 +class HStore : public HIR
  1.1079 +{
  1.1080 +  public:
  1.1081 +    HStore(AstNode *node, HLValue *lval, HIR *rval)
  1.1082 +      : HIR(node, lval->type()),
  1.1083 +        kind_(TOK_ASSIGN),
  1.1084 +        lval_(lval),
  1.1085 +        rval_(rval)
  1.1086 +    {
  1.1087 +    }
  1.1088 +
  1.1089 +    HStore(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
  1.1090 +      : HIR(node, lval->type()),
  1.1091 +        kind_(kind),
  1.1092 +        lval_(lval),
  1.1093 +        rval_(rval)
  1.1094 +    {
  1.1095 +    }
  1.1096 +
  1.1097 +    DEFINE_HIR(Store);
  1.1098 +
  1.1099 +    HLValue *lval() const {
  1.1100 +        return lval_;
  1.1101 +    }
  1.1102 +    HIR *rval() const {
  1.1103 +        return rval_;
  1.1104 +    }
  1.1105 +    TokenKind kind() const {
  1.1106 +        return kind_;
  1.1107 +    }
  1.1108 +
  1.1109 +  private:
  1.1110 +    TokenKind kind_;
  1.1111 +    HLValue *lval_;
  1.1112 +    HIR *rval_;
  1.1113 +};
  1.1114 +
  1.1115 +class HPostIncDec : public HIR
  1.1116 +{
  1.1117 +  public:
  1.1118 +    HPostIncDec(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
  1.1119 +      : HIR(node, lval->type()),
  1.1120 +        kind_(kind),
  1.1121 +        lval_(lval),
  1.1122 +        rval_(rval)
  1.1123 +    {
  1.1124 +    }
  1.1125 +
  1.1126 +    DEFINE_HIR(PostIncDec);
  1.1127 +
  1.1128 +    HLValue *lval() const {
  1.1129 +        return lval_;
  1.1130 +    }
  1.1131 +    HIR *rval() const {
  1.1132 +        return rval_;
  1.1133 +    }
  1.1134 +    TokenKind kind() const {
  1.1135 +        return kind_;
  1.1136 +    }
  1.1137 +
  1.1138 +  private:
  1.1139 +    TokenKind kind_;
  1.1140 +    HLValue *lval_;
  1.1141 +    HIR *rval_;
  1.1142 +};
  1.1143 +
  1.1144 +class HCall : public HIR
  1.1145 +{
  1.1146 +  public:
  1.1147 +    HCall(AstNode *node, Type *type, HIR *callee, HIRList *args)
  1.1148 +      : HIR(node, type),
  1.1149 +        callee_(callee),
  1.1150 +        args_(args)
  1.1151 +    {
  1.1152 +    }
  1.1153 +
  1.1154 +    DEFINE_HIR(Call);
  1.1155 +
  1.1156 +    HIR *callee() const {
  1.1157 +        return callee_;
  1.1158 +    }
  1.1159 +    HIRList *args() const {
  1.1160 +        return args_;
  1.1161 +    }
  1.1162 +
  1.1163 +  private:
  1.1164 +    HIR *callee_;
  1.1165 +    HIRList *args_;
  1.1166 +};
  1.1167 +
  1.1168 +class HToRef : public HIR
  1.1169 +{
  1.1170 +  public:
  1.1171 +    HToRef(AstNode *node, Type *type, HIR *in)
  1.1172 +      : HIR(node, type),
  1.1173 +        in_(in)
  1.1174 +    {
  1.1175 +    }
  1.1176 +
  1.1177 +    DEFINE_HIR(ToRef);
  1.1178 +
  1.1179 +    HIR *in() const {
  1.1180 +        return in_;
  1.1181 +    }
  1.1182 +
  1.1183 +  private:
  1.1184 +    HIR *in_;
  1.1185 +};
  1.1186 +
  1.1187 +class HNewDependentArray : public HIR
  1.1188 +{
  1.1189 +  public:
  1.1190 +    HNewDependentArray(AstNode *node, Type *type, HIR *base, HIR *index)
  1.1191 +      : HIR(node, type),
  1.1192 +        base_(base),
  1.1193 +        index_(index)
  1.1194 +    {
  1.1195 +    }
  1.1196 +
  1.1197 +    DEFINE_HIR(NewDependentArray);
  1.1198 +
  1.1199 +    HIR *base() const {
  1.1200 +        return base_;
  1.1201 +    }
  1.1202 +    HIR *index() const {
  1.1203 +        return index_;
  1.1204 +    }
  1.1205 +
  1.1206 +  private:
  1.1207 +    HIR *base_;
  1.1208 +    HIR *index_;
  1.1209 +};
  1.1210 +
  1.1211 +#undef DEFINE_HIR
  1.1212 +
  1.1213 +void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
  1.1214 +
  1.1215 +}
  1.1216 +
  1.1217 +#endif // _include_sp2_hir_h_