199 lines
5.1 KiB
C++
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();}
|
|
}
|