dvander@195: /* vim: set ts=4 sw=4 tw=99 et: dvander@195: * dvander@195: * Copyright (C) 2012 David Anderson dvander@195: * dvander@195: * This file is part of SourcePawn. dvander@195: * dvander@195: * SourcePawn is free software: you can redistribute it and/or modify it under dvander@195: * the terms of the GNU General Public License as published by the Free dvander@195: * Software Foundation, either version 3 of the License, or (at your option) dvander@195: * any later version. dvander@195: * dvander@195: * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY dvander@195: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@195: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@195: * dvander@195: * You should have received a copy of the GNU General Public License along with dvander@195: * SourcePawn. If not, see http://www.gnu.org/licenses/. dvander@195: */ dvander@195: #ifndef _include_sp2_symbol_h_ dvander@195: #define _include_sp2_symbol_h_ dvander@195: dvander@195: #include "../PoolAllocator.h" dvander@195: #include "../Handles.h" dvander@195: #include "../Opcodes.h" dvander@195: #include "../Types.h" dvander@196: #include "../Strings.h" dvander@195: dvander@195: namespace ke { dvander@195: dvander@195: class String; dvander@195: dvander@195: #define SYMBOL_KINDS(_) \ dvander@195: /* Any kind of variable or argument produces a VariableSymbol. */ \ dvander@195: _(Variable) \ dvander@195: /* A function declaration produces a FunctionSymbol. */ \ dvander@195: _(Function) \ dvander@195: /* A named constant produces a ConstantSymbol. */ \ dvander@195: _(Constant) \ dvander@195: /* A named type (class struct, typedef, etc) produces a TypeSymbol. */ \ dvander@195: _(Type) \ dvander@195: /* // A module import produces a ModuleSymbol. */ \ dvander@195: _(Module) dvander@195: dvander@195: #define _(name) class name##Symbol; dvander@195: SYMBOL_KINDS(_) dvander@195: #undef _ dvander@195: dvander@195: class Scope; dvander@195: dvander@195: // A symbol represents the declaration of a named entity. dvander@195: class Symbol : public PoolObject dvander@195: { dvander@195: public: dvander@195: enum Kind { dvander@195: # define _(name) k##name, dvander@195: SYMBOL_KINDS(_) dvander@195: # undef _ dvander@195: kTotalSymbolKinds dvander@195: }; dvander@195: dvander@195: public: dvander@195: Symbol(Scope *scope, Handle name, const SourcePosition &pos) dvander@195: : scope_(scope), dvander@195: name_(name), dvander@195: pos_(pos) dvander@195: { dvander@195: } dvander@195: dvander@195: virtual Kind kind() const = 0; dvander@195: dvander@195: Handle name() const { dvander@195: return name_; dvander@195: } dvander@195: const SourcePosition &pos() const { dvander@195: return pos_; dvander@195: } dvander@195: Handle type() const { dvander@195: return type_; dvander@195: } dvander@195: Scope *scope() const { dvander@195: return scope_; dvander@195: } dvander@195: dvander@195: public: dvander@195: #define _(name) \ dvander@195: bool is##name() const { \ dvander@195: return (kind() == k##name); \ dvander@195: } \ dvander@195: name##Symbol *as##name() { \ dvander@195: if (is##name()) \ dvander@195: return to##name(); \ dvander@195: return NULL; \ dvander@195: } \ dvander@195: name##Symbol *to##name() { \ dvander@195: assert(is##name()); \ dvander@195: return reinterpret_cast(this); \ dvander@195: } dvander@195: SYMBOL_KINDS(_) dvander@195: #undef _ dvander@195: dvander@195: private: dvander@195: Scope *scope_; dvander@195: ScopedRoot name_; dvander@195: SourcePosition pos_; dvander@195: dvander@195: protected: dvander@195: ScopedRoot type_; dvander@195: }; dvander@195: dvander@195: class VariableSymbol : public Symbol dvander@195: { dvander@195: public: dvander@195: enum Storage { dvander@195: Unknown, dvander@195: Local, dvander@220: Arg, dvander@195: Heap dvander@195: }; dvander@195: dvander@195: public: dvander@195: VariableSymbol(Scope *scope, Handle name, const SourcePosition &pos) dvander@195: : Symbol(scope, name, pos), dvander@195: storage_(Unknown) dvander@195: { dvander@195: } dvander@195: dvander@195: VariableSymbol(Scope *scope, Handle name, const SourcePosition &pos, Handle type) dvander@195: : Symbol(scope, name, pos), dvander@195: storage_(Unknown) dvander@195: { dvander@195: type_ = type; dvander@195: } dvander@195: dvander@195: Kind kind() const { dvander@195: return kVariable; dvander@195: } dvander@195: void setType(Type *type) { dvander@209: assert(!type_); dvander@195: type_ = type; dvander@195: } dvander@195: void allocate(Storage storage, unsigned slot) { dvander@195: storage_ = storage; dvander@195: slot_ = slot; dvander@195: } dvander@195: Storage storage() const { dvander@195: return storage_; dvander@195: } dvander@195: unsigned slot() const { dvander@195: assert(storage() != Unknown); dvander@195: return slot_; dvander@195: } dvander@195: dvander@195: private: dvander@195: Storage storage_; dvander@195: unsigned slot_; dvander@195: }; dvander@195: dvander@195: class TypeSymbol : public Symbol dvander@195: { dvander@195: public: dvander@195: TypeSymbol(Scope *scope, Handle name, Handle type) dvander@195: : Symbol(scope, name, SourcePosition()) dvander@195: { dvander@195: type_ = type; dvander@195: } dvander@195: dvander@195: Kind kind() const { dvander@195: return kType; dvander@195: } dvander@195: }; dvander@195: dvander@195: class FunctionSymbol : public Symbol dvander@195: { dvander@195: public: dvander@195: FunctionSymbol(Scope *scope, Handle name, const SourcePosition &pos, Handle type) dvander@195: : Symbol(scope, name, pos) dvander@195: { dvander@195: type_ = type; dvander@195: } dvander@195: dvander@195: Kind kind() const { dvander@195: return kFunction; dvander@195: } dvander@195: FunctionType *type() const { dvander@195: return FunctionType::cast(type_); dvander@195: } dvander@195: }; dvander@195: dvander@233: class ConstantSymbol : public Symbol dvander@233: { dvander@233: public: dvander@233: ConstantSymbol(Scope *scope, Handle name, const SourcePosition &pos, Handle type, dvander@233: const BoxedPrimitive &prim) dvander@233: : Symbol(scope, name, pos), dvander@233: value_(prim) dvander@233: { dvander@233: type_ = type; dvander@233: } dvander@233: dvander@233: Kind kind() const { dvander@233: return kConstant; dvander@233: } dvander@233: const BoxedPrimitive &value() const { dvander@233: return value_; dvander@233: } dvander@233: dvander@233: private: dvander@233: BoxedPrimitive value_; dvander@233: }; dvander@233: dvander@195: } dvander@195: dvander@195: #endif // _include_sp2_symbol_h_