2024-12-27 10:51:46 +01:00
|
|
|
// 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/.
|
2024-12-23 13:54:11 +01:00
|
|
|
#include "elna/source/types.h"
|
|
|
|
#include "elna/source/symbol_table.h"
|
|
|
|
|
|
|
|
namespace elna
|
|
|
|
{
|
|
|
|
namespace source
|
|
|
|
{
|
|
|
|
symbol_table::symbol_table(std::shared_ptr<symbol_table> scope)
|
|
|
|
: outer_scope(scope)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<info> symbol_table::lookup(const std::string& name)
|
|
|
|
{
|
|
|
|
auto entry = entries.find(name);
|
|
|
|
|
|
|
|
if (entry != entries.cend())
|
|
|
|
{
|
|
|
|
return entry->second;
|
|
|
|
}
|
|
|
|
if (this->outer_scope != nullptr)
|
|
|
|
{
|
|
|
|
return this->outer_scope->lookup(name);
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void symbol_table::enter(const std::string& name, std::shared_ptr<info> entry)
|
|
|
|
{
|
|
|
|
entries.insert({ name, entry });
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<symbol_table> symbol_table::scope()
|
|
|
|
{
|
|
|
|
return this->outer_scope;
|
|
|
|
}
|
|
|
|
|
|
|
|
info::~info()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
type_info *info::is_type_info() noexcept
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
typed_info *info::is_typed_info() noexcept
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
constant_info *info::is_constant_info() noexcept
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
variable_info *info::is_variable_info() noexcept
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
parameter_info *info::is_parameter_info() noexcept
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
intrinsic_info *info::is_intrinsic_info() noexcept
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
procedure_info *info::is_procedure_info() noexcept
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
info::info()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
type_info::type_info(std::shared_ptr<class type> type)
|
|
|
|
: info(), m_type(type)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
type_info::~type_info()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<const class type> type_info::type() const noexcept
|
|
|
|
{
|
|
|
|
return m_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
type_info *type_info::is_type_info() noexcept
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
typed_info::typed_info(std::shared_ptr<const class type> type)
|
|
|
|
: m_type(type)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
typed_info::~typed_info()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
typed_info *typed_info::is_typed_info() noexcept
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<const class type> typed_info::type() const noexcept
|
|
|
|
{
|
|
|
|
return m_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
constant_info::constant_info(const std::shared_ptr<const class type> type, const std::int32_t value)
|
|
|
|
: typed_info(type), m_value(value)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
constant_info *constant_info::is_constant_info() noexcept
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::int32_t constant_info::value() const noexcept
|
|
|
|
{
|
|
|
|
return m_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
variable_info::variable_info(std::shared_ptr<const class type> type)
|
|
|
|
: typed_info(type)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
variable_info *variable_info::is_variable_info() noexcept
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
parameter_info::parameter_info(std::shared_ptr<const class type> type)
|
|
|
|
: typed_info(type)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
parameter_info *parameter_info::is_parameter_info() noexcept
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
intrinsic_info::intrinsic_info(const class procedure_type& type)
|
|
|
|
: m_type(std::make_shared<procedure_type>(type))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
intrinsic_info::~intrinsic_info()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<const class procedure_type> intrinsic_info::type() const noexcept
|
|
|
|
{
|
|
|
|
return m_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::size_t intrinsic_info::parameter_stack_size() const noexcept
|
|
|
|
{
|
|
|
|
return type()->arguments.size() * sizeof(std::int32_t);
|
|
|
|
}
|
|
|
|
|
|
|
|
intrinsic_info *intrinsic_info::is_intrinsic_info() noexcept
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
procedure_info::procedure_info(const class procedure_type& type, std::shared_ptr<symbol_table> outer_scope)
|
|
|
|
: intrinsic_info(type), local_table(std::make_shared<symbol_table>(outer_scope))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
procedure_info::~procedure_info()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<symbol_table> procedure_info::scope()
|
|
|
|
{
|
|
|
|
return local_table;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::size_t procedure_info::stack_size() const noexcept
|
|
|
|
{
|
|
|
|
return local_stack_size + argument_stack_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
procedure_info *procedure_info::is_procedure_info() noexcept
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr std::size_t pointer_size = 4;
|
|
|
|
|
|
|
|
std::shared_ptr<source::symbol_table> add_builtin_symbols()
|
|
|
|
{
|
|
|
|
source::symbol_table result;
|
|
|
|
std::vector<std::shared_ptr<const source::type>> intrinsic_arguments;
|
|
|
|
|
|
|
|
auto prim = boolean_type;
|
|
|
|
auto boolean_info = std::make_shared<type_info>(std::make_shared<primitive_type>(boolean_type));
|
|
|
|
auto int_info = std::make_shared<source::type_info>(std::make_shared<primitive_type>(int_type));
|
|
|
|
result.enter("Boolean", boolean_info);
|
|
|
|
result.enter("Int", int_info);
|
|
|
|
|
|
|
|
intrinsic_arguments.push_back(int_info->type());
|
|
|
|
auto writei = std::make_shared<source::intrinsic_info>(
|
|
|
|
source::procedure_type{ intrinsic_arguments, pointer_size });
|
|
|
|
result.enter("writei", writei);
|
|
|
|
intrinsic_arguments.clear();
|
|
|
|
|
|
|
|
intrinsic_arguments.push_back(boolean_info->type());
|
|
|
|
auto writeb = std::make_shared<source::intrinsic_info>(
|
|
|
|
source::procedure_type{ intrinsic_arguments, pointer_size });
|
|
|
|
result.enter("writeb", writeb);
|
|
|
|
intrinsic_arguments.clear();
|
|
|
|
|
|
|
|
return std::make_shared<source::symbol_table>(std::move(result));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|