// This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #pragma once #include #include #include #include namespace elna { namespace source { class symbol_table; class type_info; class typed_info; class constant_info; class variable_info; class parameter_info; class intrinsic_info; class procedure_info; /** * Generic language entity information. */ class info { public: virtual ~info() = 0; virtual type_info *is_type_info() noexcept; virtual typed_info *is_typed_info() noexcept; virtual constant_info *is_constant_info() noexcept; virtual variable_info *is_variable_info() noexcept; virtual parameter_info *is_parameter_info() noexcept; virtual intrinsic_info *is_intrinsic_info() noexcept; virtual procedure_info *is_procedure_info() noexcept; protected: info(); }; /** * Type information. */ class type_info final : public info { std::shared_ptr m_type; public: explicit type_info(std::shared_ptr type); ~type_info() override; virtual type_info *is_type_info() noexcept override; std::shared_ptr type() const noexcept; }; /** * Information for a typed symbol. */ class typed_info : public info { std::shared_ptr m_type; protected: typed_info(std::shared_ptr type); public: ~typed_info() override; virtual typed_info *is_typed_info() noexcept override; std::shared_ptr type() const noexcept; }; /** * Constant information. */ class constant_info final : public typed_info { std::int32_t m_value; public: constant_info(std::shared_ptr type, const std::int32_t value); virtual constant_info *is_constant_info() noexcept override; std::int32_t value() const noexcept; }; /** * Variable information. */ class variable_info final : public typed_info { public: std::ptrdiff_t offset{ 0 }; explicit variable_info(std::shared_ptr type); virtual variable_info *is_variable_info() noexcept override; }; /** * Procedure parameter information. */ class parameter_info final : public typed_info { public: std::ptrdiff_t offset{ 0 }; explicit parameter_info(std::shared_ptr type); virtual parameter_info *is_parameter_info() noexcept override; }; /** * Intrinsic and external procedure information. */ class intrinsic_info : public info { std::shared_ptr m_type; public: explicit intrinsic_info(const class procedure_type& type); ~intrinsic_info() override; std::shared_ptr type() const noexcept; std::size_t parameter_stack_size() const noexcept; virtual intrinsic_info *is_intrinsic_info() noexcept override; }; /** * Procedure information. */ class procedure_info final : public intrinsic_info { std::shared_ptr local_table; public: std::size_t local_stack_size{ 0 }; std::size_t argument_stack_size{ 0 }; procedure_info(const class procedure_type& type, std::shared_ptr outer_scope); ~procedure_info() override; std::shared_ptr scope(); std::size_t stack_size() const noexcept; virtual procedure_info *is_procedure_info() noexcept override; }; /** * Symbol table. */ class symbol_table { std::unordered_map> entries; std::shared_ptr outer_scope; public: /** * Constructs a new symbol with an optional outer scope. * * \param scope Outer scope. */ explicit symbol_table(std::shared_ptr scope = nullptr); /** * Looks for symbol in the table by name. Returns nullptr if the symbol * can not be found. * * \param name Symbol name. * \return Symbol from the table if found. */ std::shared_ptr lookup(const std::string& name); /** * Registers new symbol. * * \param name Symbol name. * \param entry Symbol information. */ void enter(const std::string& name, std::shared_ptr entry); /** * Returns the outer scope or nullptr if the this is the global scope. * * \return Outer scope. */ std::shared_ptr scope(); }; /** * Creates a symbol table with predefined symbols. * * \return A symbol table with predefined symbols. */ std::shared_ptr add_builtin_symbols();} }