Re-add postinc support.
2 * Copyright (C) 2012 David Anderson
4 * This file is part of SourcePawn.
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)
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.
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/.
18 #ifndef _include_sp2_hir_h_
19 #define _include_sp2_hir_h_
22 #include "../PoolAllocator.h"
23 #include "../Opcodes.h"
33 /* Special LValue types */ \
42 // Forward declarations.
43 #define _(name) class H##name;
49 class HIR : public PoolObject
53 #define _(name) k##name,
69 virtual bool isLValue() const {
73 virtual HOp op() const = 0;
74 virtual void accept(HIRVisitor *visitor) = 0;
77 ScopedRoot<Type> type_;
80 class BytecodeEmitter;
86 virtual void visit##name(H##name *hir) { \
93 typedef PoolList<HIR *> HIRList;
95 #define DEFINE_HIR(name) \
96 virtual HOp op() const { \
99 virtual void accept(HIRVisitor *visitor) { \
100 visitor->visit##name(this); \
103 class HInteger : public HIR
106 HInteger(Type *type, int value)
121 class HConvert : public HIR
124 HConvert(Type *type, Opcode op, HIR *in)
132 Opcode opcode() const {
144 class HLValue : public HIR
152 // Pushes a reference to the LValue on the stack.
153 virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
155 // Duplicates a stack reference.
156 virtual void hold(BytecodeEmitter &emitter_) = 0;
158 // Reorders the stack for a post-increment operation:
159 // REF VAL -> VAL REF VAL
160 virtual void swapAndPick(BytecodeEmitter &emitter_) = 0;
162 // Given a stack layout of the form:
166 // Emits a store to the reference.
167 virtual void store(BytecodeEmitter &emitter_) = 0;
168 virtual void load(BytecodeEmitter &emitter_) = 0;
170 bool isLValue() const {
175 class HLocal : public HLValue
178 HLocal(VariableSymbol *sym)
179 : HLValue(sym->type()),
186 // Pushes a reference to the LValue on the stack.
187 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
188 void hold(BytecodeEmitter &emitter_);
189 void swapAndPick(BytecodeEmitter &emitter_);
190 void store(BytecodeEmitter &emitter_);
191 void load(BytecodeEmitter &emitter_);
194 VariableSymbol *sym_;
197 class HIndex : public HLValue
200 HIndex(Type *type, HIR *left, HIR *right)
209 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
210 void hold(BytecodeEmitter &emitter_);
211 void swapAndPick(BytecodeEmitter &emitter_);
212 void store(BytecodeEmitter &emitter_);
213 void load(BytecodeEmitter &emitter_);
220 class HGlobal : public HLValue
224 : HLValue(sym->type()),
231 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
232 void hold(BytecodeEmitter &emitter_);
233 void swapAndPick(BytecodeEmitter &emitter_);
234 void store(BytecodeEmitter &emitter_);
235 void load(BytecodeEmitter &emitter_);
237 Symbol *sym() const {
245 class HBinary : public HIR
248 HBinary(Type *type, TokenKind token, HIR *left, HIR *right)
257 TokenKind token() const {
273 class HFloat : public HIR
276 HFloat(Type *type, float value)
283 float value() const {
291 class HStore : public HIR
294 HStore(HLValue *lval, HIR *rval)
302 HStore(TokenKind kind, HLValue *lval, HIR *rval)
312 HLValue *lval() const {
318 TokenKind kind() const {
328 class HPostIncDec : public HIR
331 HPostIncDec(TokenKind kind, HLValue *lval, HIR *rval)
339 DEFINE_HIR(PostIncDec);
341 HLValue *lval() const {
347 TokenKind kind() const {
357 class HCall : public HIR
360 HCall(Type *type, HIR *callee, HIRList *args)
369 HIR *callee() const {
372 HIRList *args() const {
383 void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
387 #endif // _include_sp2_hir_h_