#pragma once #include #include #include #include #include namespace elna::source { class symbol_table; /** * Generic language entity information. */ class info { public: virtual ~info() = 0; protected: info(); }; /** * Type information. */ class type_info final : public info { std::shared_ptr m_type; public: explicit type_info(const class type& type); ~type_info() override; std::shared_ptr type() const noexcept; }; /** * Constant information. */ class constant_info final : public info { std::int32_t m_value; public: constant_info(const std::int32_t value); ~constant_info() override; std::int32_t value() const noexcept; }; /** * Variable information. */ class variable_info final : public info { std::shared_ptr m_type; public: std::ptrdiff_t offset{ 0 }; explicit variable_info(std::shared_ptr type); ~variable_info() override; std::shared_ptr type() noexcept; }; /** * Procedure parameter information. */ class parameter_info final : public info { std::shared_ptr m_type; public: std::ptrdiff_t offset{ 0 }; explicit parameter_info(std::shared_ptr type); ~parameter_info() override; std::shared_ptr type() const noexcept; }; /** * Intrinsic and external procedure information. */ class intrinsic_info : public info { public: std::vector parameter_infos; ~intrinsic_info() override; std::size_t parameter_stack_size() const noexcept; }; /** * 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 }; explicit procedure_info(std::shared_ptr outer_scope); ~procedure_info() override; std::shared_ptr scope(); std::size_t stack_size() const noexcept; }; /** * 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(); }; }