#ifndef QLOW_SEM_SCOPE_H #define QLOW_SEM_SCOPE_H #include #include #include namespace qlow { namespace ast { struct Type; } namespace sem { /*! * \note contains owning pointers to elements */ template using SymbolTable = std::map>; struct Class; struct Method; struct Variable; class Scope; class GlobalScope; class NativeScope; class ClassScope; class LocalScope; class Type; class NativeType; } } class qlow::sem::Scope { public: virtual ~Scope(void); virtual Variable* getVariable(const std::string& name) = 0; virtual Method* getMethod(const std::string& name) = 0; virtual std::shared_ptr getType(const ast::Type& name) = 0; virtual std::shared_ptr getReturnableType(void) = 0; virtual std::string toString(void) = 0; }; class qlow::sem::GlobalScope : public Scope { public: SymbolTable classes; SymbolTable functions; public: virtual Variable* getVariable(const std::string& name); virtual Method* getMethod(const std::string& name); virtual std::shared_ptr getType(const ast::Type& name); virtual std::shared_ptr getReturnableType(void); virtual std::string toString(void); }; class qlow::sem::NativeScope : public GlobalScope { static NativeScope instance; public: SymbolTable> types; public: virtual std::shared_ptr getType(const ast::Type& name); virtual std::string toString(void); static NativeScope& getInstance(void); }; class qlow::sem::ClassScope : public Scope { Scope& parentScope; Class* class_ref; public: inline ClassScope(Scope& parentScope, Class* class_ref) : parentScope{ parentScope }, class_ref{ class_ref } { } virtual Variable* getVariable(const std::string& name); virtual Method* getMethod(const std::string& name); virtual std::shared_ptr getType(const ast::Type& name); virtual std::shared_ptr getReturnableType(void); virtual std::string toString(void); }; class qlow::sem::LocalScope : public Scope { Scope& parentScope; SymbolTable localVariables; std::shared_ptr returnType; public: inline LocalScope(Scope& parentScope, Type* returnType) : parentScope{ parentScope }, returnType{ returnType } { } inline LocalScope(Scope& parentScope) : parentScope{ parentScope } { auto returnable = parentScope.getReturnableType(); if (returnable) { returnType = std::move(returnable); } else { returnType = nullptr; } } void putVariable(const std::string& name, std::unique_ptr v); SymbolTable& getLocals(void); virtual Variable* getVariable(const std::string& name); virtual Method* getMethod(const std::string& name); virtual std::shared_ptr getType(const ast::Type& name); virtual std::shared_ptr getReturnableType(void); virtual std::string toString(void); }; #endif // QLOW_SEM_SCOPE_H