Add support for unary - and bitcast operator.
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"
37 /* Special LValue types */ \
47 // Forward declarations.
48 #define _(name) class H##name;
57 class HIR : public PoolObject
61 #define _(name) k##name,
68 HIR(AstNode *node, Type *type)
77 AstNode *node() const {
81 virtual bool isLValue() const {
85 virtual HOp op() const = 0;
86 virtual void accept(HIRVisitor *visitor) = 0;
89 bool is##name() const { \
90 return op() == k##name; \
92 H##name *to##name() { \
94 return reinterpret_cast<H##name *>(this); \
101 return reinterpret_cast<HLValue *>(this);
106 ScopedRoot<Type> type_;
109 class BytecodeEmitter;
115 virtual void visit##name(H##name *hir) { \
122 typedef PoolList<HIR *> HIRList;
124 #define DEFINE_HIR(name) \
125 virtual HOp op() const { \
128 virtual void accept(HIRVisitor *visitor) { \
129 visitor->visit##name(this); \
132 class HBoolean : public HIR
135 HBoolean(AstNode *node, Type *type, bool value)
150 class HInteger : public HIR
153 HInteger(AstNode *node, Type *type, int value)
168 class HString : public HIR
171 HString(AstNode *node, Type *type, String *string)
178 Handle<String> string() const {
183 ScopedRoot<String> string_;
186 class HArray : public HIR
189 HArray(AstNode *node, Type *type, Array *array, bool duplicate)
192 duplicate_(duplicate)
197 Handle<Array> array() const {
200 bool duplicate() const {
205 ScopedRoot<Array> array_;
209 class HConvert : public HIR
212 HConvert(AstNode *node, Type *type, Opcode op, HIR *in)
220 Opcode opcode() const {
232 class HLValue : public HIR
235 HLValue(AstNode *node, Type *type)
240 // Pushes a reference to the LValue on the stack.
241 virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
243 // Duplicates a stack reference.
244 virtual void hold(BytecodeEmitter &emitter_) = 0;
246 // Reorders the stack for a post-increment operation:
247 // REF VAL -> VAL REF VAL
248 virtual void swapAndPick(BytecodeEmitter &emitter_) = 0;
250 // Given a stack layout of the form:
254 // Emits a store to the reference.
255 virtual void store(BytecodeEmitter &emitter_) = 0;
256 virtual void load(BytecodeEmitter &emitter_) = 0;
258 // Try to make a direct reference, if semantics allow it. False if the
259 // caller must allocate a reference to the stack.
260 virtual bool ref(BytecodeEmitter &emitter_) = 0;
262 bool isLValue() const {
267 class HLocal : public HLValue
270 HLocal(AstNode *node, VariableSymbol *sym);
274 // Pushes a reference to the LValue on the stack.
275 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
276 void hold(BytecodeEmitter &emitter_);
277 void swapAndPick(BytecodeEmitter &emitter_);
278 void store(BytecodeEmitter &emitter_);
279 void load(BytecodeEmitter &emitter_);
280 bool ref(BytecodeEmitter &emitter_);
282 VariableSymbol *sym() const {
287 VariableSymbol *sym_;
290 class HIndex : public HLValue
293 HIndex(AstNode *node, Type *type, HIR *left, HIR *right)
294 : HLValue(node, type),
302 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
303 void hold(BytecodeEmitter &emitter_);
304 void swapAndPick(BytecodeEmitter &emitter_);
305 void store(BytecodeEmitter &emitter_);
306 void load(BytecodeEmitter &emitter_);
307 bool ref(BytecodeEmitter &emitter_);
314 class HGlobal : public HLValue
317 HGlobal(AstNode *node, Symbol *sym)
318 : HLValue(node, sym->type()),
325 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
326 void hold(BytecodeEmitter &emitter_);
327 void swapAndPick(BytecodeEmitter &emitter_);
328 void store(BytecodeEmitter &emitter_);
329 void load(BytecodeEmitter &emitter_);
330 bool ref(BytecodeEmitter &emitter_);
332 Symbol *sym() const {
340 class HBinary : public HIR
343 HBinary(AstNode *node, Type *type, TokenKind token, HIR *left, HIR *right)
352 TokenKind token() const {
368 class HFloat : public HIR
371 HFloat(AstNode *node, Type *type, float value)
378 float value() const {
386 class HUnary : public HIR
389 HUnary(AstNode *node, Type *type, TokenKind tok, HIR *in)
400 TokenKind token() const {
409 class HStore : public HIR
412 HStore(AstNode *node, HLValue *lval, HIR *rval)
413 : HIR(node, lval->type()),
420 HStore(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
421 : HIR(node, lval->type()),
430 HLValue *lval() const {
436 TokenKind kind() const {
446 class HPostIncDec : public HIR
449 HPostIncDec(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
450 : HIR(node, lval->type()),
457 DEFINE_HIR(PostIncDec);
459 HLValue *lval() const {
465 TokenKind kind() const {
475 class HCall : public HIR
478 HCall(AstNode *node, Type *type, HIR *callee, HIRList *args)
487 HIR *callee() const {
490 HIRList *args() const {
499 class HToRef : public HIR
502 HToRef(AstNode *node, Type *type, HIR *in)
520 void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
524 #endif // _include_sp2_hir_h_