elna/include/elna/source/symbol_table.h

199 lines
5.1 KiB
C++

// 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 <cstdint>
#include <unordered_map>
#include <string>
#include <memory>
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<const class type> m_type;
public:
explicit type_info(std::shared_ptr<class type> type);
~type_info() override;
virtual type_info *is_type_info() noexcept override;
std::shared_ptr<const class type> type() const noexcept;
};
/**
* Information for a typed symbol.
*/
class typed_info : public info
{
std::shared_ptr<const class type> m_type;
protected:
typed_info(std::shared_ptr<const class type> type);
public:
~typed_info() override;
virtual typed_info *is_typed_info() noexcept override;
std::shared_ptr<const class type> type() const noexcept;
};
/**
* Constant information.
*/
class constant_info final : public typed_info
{
std::int32_t m_value;
public:
constant_info(std::shared_ptr<const class type> 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<const class type> 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<const class type> type);
virtual parameter_info *is_parameter_info() noexcept override;
};
/**
* Intrinsic and external procedure information.
*/
class intrinsic_info : public info
{
std::shared_ptr<const class procedure_type> m_type;
public:
explicit intrinsic_info(const class procedure_type& type);
~intrinsic_info() override;
std::shared_ptr<const class procedure_type> 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<symbol_table> 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<symbol_table> outer_scope);
~procedure_info() override;
std::shared_ptr<symbol_table> scope();
std::size_t stack_size() const noexcept;
virtual procedure_info *is_procedure_info() noexcept override;
};
/**
* Symbol table.
*/
class symbol_table
{
std::unordered_map<std::string, std::shared_ptr<info>> entries;
std::shared_ptr<symbol_table> outer_scope;
public:
/**
* Constructs a new symbol with an optional outer scope.
*
* \param scope Outer scope.
*/
explicit symbol_table(std::shared_ptr<symbol_table> 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<info> 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<info> entry);
/**
* Returns the outer scope or nullptr if the this is the global scope.
*
* \return Outer scope.
*/
std::shared_ptr<symbol_table> scope();
};
/**
* Creates a symbol table with predefined symbols.
*
* \return A symbol table with predefined symbols.
*/
std::shared_ptr<source::symbol_table> add_builtin_symbols();}
}