dvander@0: /* dvander@0: * Copyright (C) 2012 David Anderson dvander@0: * dvander@0: * This file is part of JITCraft. dvander@0: * dvander@0: * JITCraft is free software: you can redistribute it and/or modify it under dvander@0: * the terms of the GNU General Public License as published by the Free dvander@0: * Software Foundation, either version 3 of the License, or (at your option) dvander@0: * any later version. dvander@0: * dvander@0: * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY dvander@0: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@0: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@0: * dvander@0: * You should have received a copy of the GNU General Public License along with dvander@0: * JITCraft. If not, see http://www.gnu.org/licenses/. dvander@0: */ dvander@0: #ifndef _include_name_binding_h_ dvander@0: #define _include_name_binding_h_ dvander@0: dvander@0: #include "PoolAllocator.h" dvander@0: #include "StringPool.h" dvander@2: #include "Types.h" dvander@0: dvander@0: namespace jc { dvander@0: dvander@0: class Variable; dvander@0: class NamedFunction; dvander@0: class Scope; dvander@0: class Type; dvander@2: class NamedEnum; dvander@2: class NamedConstant; dvander@0: dvander@0: class BoundName : public PoolObject dvander@0: { dvander@0: Name *name_; dvander@0: Scope *scope_; dvander@0: Type *type_; dvander@0: dvander@0: public: dvander@0: enum Kind { dvander@0: VARIABLE, dvander@1: FUNCTION, dvander@2: ENUM, dvander@2: CONSTANT dvander@0: }; dvander@0: dvander@0: BoundName(Scope *scope, Name *name); dvander@0: dvander@0: virtual Kind kind() const = 0; dvander@0: dvander@0: Name *name() const { dvander@0: return name_; dvander@0: } dvander@0: Scope *scope() const { dvander@0: return scope_; dvander@0: } dvander@0: Variable *toVariable() { dvander@0: assert(kind() == VARIABLE); dvander@0: return reinterpret_cast(this); dvander@0: } dvander@0: NamedFunction *toNamedFunction() { dvander@0: assert(kind() == FUNCTION); dvander@0: return reinterpret_cast(this); dvander@0: } dvander@2: NamedConstant *toNamedConstant() { dvander@2: assert(kind() == CONSTANT); dvander@2: return reinterpret_cast(this); dvander@2: } dvander@0: Type *type() const { dvander@0: return type_; dvander@0: } dvander@0: void setType(Type *type) { dvander@0: type_ = type; dvander@0: } dvander@0: }; dvander@0: dvander@0: class NamedFunction : public BoundName dvander@0: { dvander@0: unsigned slot_; dvander@0: dvander@0: public: dvander@0: NamedFunction(Scope *scope, Name *name); dvander@0: dvander@0: Kind kind() const { dvander@0: return FUNCTION; dvander@0: } dvander@0: void allocate(unsigned slot) { dvander@0: slot_ = slot; dvander@0: } dvander@0: unsigned slot() const { dvander@0: return slot_; dvander@0: } dvander@0: }; dvander@0: dvander@2: class NamedEnum : public BoundName dvander@1: { dvander@1: public: dvander@2: NamedEnum(Scope *scope, Name *name) dvander@2: : BoundName(scope, name) dvander@1: { dvander@1: } dvander@1: dvander@2: Kind kind() const { dvander@2: return ENUM; dvander@1: } dvander@2: }; dvander@2: dvander@2: class NamedConstant : public BoundName dvander@2: { dvander@2: BoxedPrimitive value_; dvander@2: Type *type_; dvander@2: dvander@2: public: dvander@2: NamedConstant(Scope *scope, Name *name) dvander@2: : BoundName(scope, name), dvander@2: type_(NULL) dvander@2: { dvander@2: } dvander@2: dvander@2: Kind kind() const { dvander@2: return CONSTANT; dvander@2: } dvander@2: void set(Type *type, const BoxedPrimitive &value) { dvander@2: value_ = value; dvander@2: type_ = type; dvander@2: } dvander@2: Type *type() const { dvander@2: return type_; dvander@2: } dvander@2: BoxedPrimitive value() const { dvander@2: return value_; dvander@1: } dvander@1: }; dvander@1: dvander@0: class Variable : public BoundName dvander@0: { dvander@0: public: dvander@0: enum Location { dvander@0: UNALLOCATED, dvander@0: STACK, dvander@0: PARAMETER dvander@0: }; dvander@0: dvander@0: Variable(Scope *scope, Name *name); dvander@0: dvander@0: Kind kind() const { dvander@0: return VARIABLE; dvander@0: } dvander@0: bool unallocated() const { dvander@0: return location() == UNALLOCATED; dvander@0: } dvander@0: void allocate(Location location, unsigned slot) { dvander@0: location_ = location; dvander@0: slot_ = slot; dvander@0: } dvander@0: Location location() const { dvander@0: return location_; dvander@0: } dvander@0: unsigned slot() const { dvander@0: assert(!unallocated()); dvander@0: return slot_; dvander@0: } dvander@0: dvander@0: private: dvander@0: Location location_; dvander@0: unsigned slot_; dvander@0: }; dvander@0: dvander@0: } dvander@0: dvander@0: #endif // _include_name_binding_h_