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@2: #include "Types.h" dvander@25: #include "Scanner.h" dvander@0: dvander@59: namespace ke { 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@54: class String; dvander@0: dvander@0: class BoundName : public PoolObject dvander@0: { dvander@28: Scope *scope_; dvander@54: ScopedRoot name_; dvander@37: ScopedRoot type_; dvander@63: dvander@63: protected: dvander@25: SourcePosition pos_; 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@54: BoundName(Scope *scope, Handle name, const SourcePosition &pos); dvander@0: dvander@0: virtual Kind kind() const = 0; dvander@0: dvander@54: String *name() const { dvander@0: return name_; dvander@0: } dvander@25: 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@37: void setType(Handle type) { dvander@0: type_ = type; dvander@0: } dvander@25: const SourcePosition &pos() { dvander@25: return pos_; dvander@25: } dvander@0: }; dvander@0: dvander@0: class NamedFunction : public BoundName dvander@0: { dvander@0: unsigned slot_; dvander@63: TokenKind token_; dvander@63: ScopedRoot forwardType_; dvander@68: bool isVariadicNative_; dvander@0: dvander@0: public: dvander@63: NamedFunction(Scope *scope, Handle name, const SourcePosition &pos, TokenKind token); 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@63: bool isForward() const { dvander@63: return token_ == TOK_FORWARD; dvander@63: } dvander@63: bool isPublic() const { dvander@63: return token_ == TOK_PUBLIC; dvander@63: } dvander@68: bool isNative() const { dvander@68: return token_ == TOK_NATIVE; dvander@68: } dvander@63: void setForwardType(Handle type) { dvander@63: forwardType_ = type; dvander@63: } dvander@63: Type *forwardType() { dvander@63: return forwardType_; dvander@63: } dvander@63: void setImplemented(const SourcePosition &at) { dvander@63: token_ = TOK_PUBLIC; dvander@63: pos_ = at; dvander@63: } dvander@68: void markNativeVariadic() { dvander@68: assert(token_ == TOK_NATIVE); dvander@68: isVariadicNative_ = true; dvander@68: } dvander@68: bool isNativeVariadic() { dvander@68: assert(token_ == TOK_NATIVE); dvander@68: return isVariadicNative_; dvander@68: } 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@54: NamedEnum(Scope *scope, Handle name, const SourcePosition &pos) dvander@25: : BoundName(scope, name, pos) 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@54: NamedConstant(Scope *scope, Handle name, const SourcePosition &pos) dvander@25: : BoundName(scope, name, pos), 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@85: PARAMETER, dvander@85: ENVIRONMENT dvander@0: }; dvander@0: dvander@54: Variable(Scope *scope, Handle name, const SourcePosition &pos); 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@85: bool needsHeapAllocation(); 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_