Implement dependent char arrays.
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 _(NewDependentArray) \
38 /* Special LValue types */ \
48 // Forward declarations.
49 #define _(name) class H##name;
58 class HIR : public PoolObject
62 #define _(name) k##name,
69 HIR(AstNode *node, Type *type)
78 AstNode *node() const {
82 virtual bool isLValue() const {
86 virtual HOp op() const = 0;
87 virtual void accept(HIRVisitor *visitor) = 0;
90 bool is##name() const { \
91 return op() == k##name; \
93 H##name *to##name() { \
95 return reinterpret_cast<H##name *>(this); \
100 HLValue *toLValue() {
102 return reinterpret_cast<HLValue *>(this);
107 ScopedRoot<Type> type_;
110 class BytecodeEmitter;
116 virtual void visit##name(H##name *hir) { \
123 typedef PoolList<HIR *> HIRList;
125 #define DEFINE_HIR(name) \
126 virtual HOp op() const { \
129 virtual void accept(HIRVisitor *visitor) { \
130 visitor->visit##name(this); \
133 class HBoolean : public HIR
136 HBoolean(AstNode *node, Type *type, bool value)
151 class HInteger : public HIR
154 HInteger(AstNode *node, Type *type, int value)
169 class HString : public HIR
172 HString(AstNode *node, Type *type, String *string)
179 Handle<String> string() const {
184 ScopedRoot<String> string_;
187 class HArray : public HIR
190 HArray(AstNode *node, Type *type, Array *array, bool duplicate)
193 duplicate_(duplicate)
198 Handle<Array> array() const {
201 bool duplicate() const {
206 ScopedRoot<Array> array_;
210 class HConvert : public HIR
213 HConvert(AstNode *node, Type *type, Opcode op, HIR *in)
221 Opcode opcode() const {
233 class HLValue : public HIR
236 HLValue(AstNode *node, Type *type)
241 // Pushes a reference to the LValue on the stack.
242 virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
244 // Duplicates a stack reference.
245 virtual void hold(BytecodeEmitter &emitter_) = 0;
247 // Reorders the stack for a post-increment operation:
248 // REF VAL -> VAL REF VAL
249 virtual void swapAndPick(BytecodeEmitter &emitter_) = 0;
251 // Given a stack layout of the form:
255 // Emits a store to the reference.
256 virtual void store(BytecodeEmitter &emitter_) = 0;
257 virtual void load(BytecodeEmitter &emitter_) = 0;
259 // Try to make a direct reference, if semantics allow it. False if the
260 // caller must allocate a reference to the stack.
261 virtual bool ref(BytecodeEmitter &emitter_) = 0;
263 bool isLValue() const {
268 class HLocal : public HLValue
271 HLocal(AstNode *node, VariableSymbol *sym);
275 // Pushes a reference to the LValue on the stack.
276 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
277 void hold(BytecodeEmitter &emitter_);
278 void swapAndPick(BytecodeEmitter &emitter_);
279 void store(BytecodeEmitter &emitter_);
280 void load(BytecodeEmitter &emitter_);
281 bool ref(BytecodeEmitter &emitter_);
283 VariableSymbol *sym() const {
288 VariableSymbol *sym_;
291 class HIndex : public HLValue
294 HIndex(AstNode *node, Type *type, HIR *left, HIR *right)
295 : HLValue(node, type),
303 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
304 void hold(BytecodeEmitter &emitter_);
305 void swapAndPick(BytecodeEmitter &emitter_);
306 void store(BytecodeEmitter &emitter_);
307 void load(BytecodeEmitter &emitter_);
308 bool ref(BytecodeEmitter &emitter_);
322 class HGlobal : public HLValue
325 HGlobal(AstNode *node, Symbol *sym)
326 : HLValue(node, sym->type()),
333 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
334 void hold(BytecodeEmitter &emitter_);
335 void swapAndPick(BytecodeEmitter &emitter_);
336 void store(BytecodeEmitter &emitter_);
337 void load(BytecodeEmitter &emitter_);
338 bool ref(BytecodeEmitter &emitter_);
340 Symbol *sym() const {
348 class HBinary : public HIR
351 HBinary(AstNode *node, Type *type, TokenKind token, HIR *left, HIR *right)
360 TokenKind token() const {
376 class HFloat : public HIR
379 HFloat(AstNode *node, Type *type, float value)
386 float value() const {
394 class HUnary : public HIR
397 HUnary(AstNode *node, Type *type, TokenKind tok, HIR *in)
408 TokenKind token() const {
417 class HStore : public HIR
420 HStore(AstNode *node, HLValue *lval, HIR *rval)
421 : HIR(node, lval->type()),
428 HStore(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
429 : HIR(node, lval->type()),
438 HLValue *lval() const {
444 TokenKind kind() const {
454 class HPostIncDec : public HIR
457 HPostIncDec(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
458 : HIR(node, lval->type()),
465 DEFINE_HIR(PostIncDec);
467 HLValue *lval() const {
473 TokenKind kind() const {
483 class HCall : public HIR
486 HCall(AstNode *node, Type *type, HIR *callee, HIRList *args)
495 HIR *callee() const {
498 HIRList *args() const {
507 class HToRef : public HIR
510 HToRef(AstNode *node, Type *type, HIR *in)
526 class HNewDependentArray : public HIR
529 HNewDependentArray(AstNode *node, Type *type, HIR *base, HIR *index)
536 DEFINE_HIR(NewDependentArray);
552 void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
556 #endif // _include_sp2_hir_h_