elna/boot/symbol.cc

305 lines
8.3 KiB
C++

/* Symbol definitions.
Copyright (C) 2025 Free Software Foundation, Inc.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "elna/boot/symbol.h"
namespace elna::boot
{
type::type()
{
}
type::type(std::shared_ptr<alias_type> alias)
: tag(type_tag::alias), alias(alias)
{
}
type::type(std::shared_ptr<primitive_type> primitive)
: tag(type_tag::primitive), primitive(primitive)
{
}
type::type(std::shared_ptr<record_type> record)
: tag(type_tag::record), record(record)
{
}
type::type(std::shared_ptr<union_type> _union)
: tag(type_tag::_union), _union(_union)
{
}
type::type(std::shared_ptr<pointer_type> pointer)
: tag(type_tag::pointer), pointer(pointer)
{
}
type::type(std::shared_ptr<array_type> array)
: tag(type_tag::array), array(array)
{
}
type::type(std::shared_ptr<procedure_type> procedure)
: tag(type_tag::procedure), procedure(procedure)
{
}
void type::copy(const type& other)
{
switch (other.tag)
{
case type_tag::empty:
break;
case type_tag::alias:
new (&alias) std::weak_ptr<alias_type>(other.alias);
break;
case type_tag::primitive:
new (&primitive) std::shared_ptr<primitive_type>(other.primitive);
break;
case type_tag::record:
new (&record) std::shared_ptr<record_type>(other.record);
break;
case type_tag::_union:
new (&_union) std::shared_ptr<union_type>(other._union);
break;
case type_tag::pointer:
new (&pointer) std::shared_ptr<pointer_type>(other.pointer);
break;
case type_tag::array:
new (&array) std::shared_ptr<array_type>(other.array);
break;
case type_tag::procedure:
new (&procedure) std::shared_ptr<procedure_type>(other.procedure);
break;
}
}
type::type(const type& other)
: tag(other.tag)
{
copy(other);
}
void type::move(type&& other)
{
switch (other.tag)
{
case type_tag::empty:
break;
case type_tag::alias:
new (&alias) std::weak_ptr<alias_type>(std::move(other.alias));
break;
case type_tag::primitive:
new (&primitive) std::shared_ptr<primitive_type>(std::move(other.primitive));
break;
case type_tag::record:
new (&record) std::shared_ptr<record_type>(std::move(other.record));
break;
case type_tag::_union:
new (&_union) std::shared_ptr<union_type>(std::move(other._union));
break;
case type_tag::pointer:
new (&pointer) std::shared_ptr<pointer_type>(std::move(other.pointer));
break;
case type_tag::array:
new (&array) std::shared_ptr<array_type>(std::move(other.array));
break;
case type_tag::procedure:
new (&procedure) std::shared_ptr<procedure_type>(std::move(other.procedure));
break;
}
}
type& type::operator=(const type& other)
{
this->~type();
this->tag = other.tag;
copy(other);
return *this;
}
type::type(type&& other)
: tag(other.tag)
{
move(std::move(other));
}
type& type::operator=(type&& other)
{
this->~type();
this->tag = other.tag;
move(std::move(other));
return *this;
}
bool type::operator==(const std::nullptr_t&)
{
return empty();
}
type::~type()
{
switch (tag)
{
case type_tag::empty:
break;
case type_tag::alias:
this->alias.~weak_ptr<alias_type>();
break;
case type_tag::primitive:
this->primitive.~shared_ptr<primitive_type>();
break;
case type_tag::record:
this->record.~shared_ptr<record_type>();
break;
case type_tag::_union:
this->_union.~shared_ptr<union_type>();
break;
case type_tag::pointer:
this->pointer.~shared_ptr<pointer_type>();
break;
case type_tag::array:
this->array.~shared_ptr<array_type>();
break;
case type_tag::procedure:
this->procedure.~shared_ptr<procedure_type>();
break;
}
}
template<>
std::shared_ptr<alias_type> type::get<alias_type>() const
{
return tag == type_tag::alias ? this->alias.lock() : nullptr;
}
template<>
std::shared_ptr<primitive_type> type::get<primitive_type>() const
{
return tag == type_tag::primitive ? this->primitive : nullptr;
}
template<>
std::shared_ptr<record_type> type::get<record_type>() const
{
return tag == type_tag::record ? this->record : nullptr;
}
template<>
std::shared_ptr<union_type> type::get<union_type>() const
{
return tag == type_tag::_union ? this->_union : nullptr;
}
template<>
std::shared_ptr<pointer_type> type::get<pointer_type>() const
{
return tag == type_tag::pointer ? this->pointer : nullptr;
}
template<>
std::shared_ptr<array_type> type::get<array_type>() const
{
return tag == type_tag::array ? this->array : nullptr;
}
template<>
std::shared_ptr<procedure_type> type::get<procedure_type>() const
{
return tag == type_tag::procedure ? this->procedure : nullptr;
}
bool type::empty() const
{
return tag == type_tag::empty;
}
alias_type::alias_type(const std::string& name)
: name(name), reference()
{
}
pointer_type::pointer_type(type base)
: base(base)
{
}
array_type::array_type(type base, std::uint64_t size)
: base(base), size(size)
{
}
primitive_type::primitive_type(const std::string& identifier)
: identifier(identifier)
{
}
procedure_type::procedure_type(return_t return_type)
: return_type(return_type)
{
}
info::~info()
{
}
std::shared_ptr<type_info> info::is_type()
{
return nullptr;
}
std::shared_ptr<procedure_info> info::is_procedure()
{
return nullptr;
}
type_info::type_info(const type symbol)
: symbol(symbol)
{
}
std::shared_ptr<type_info> type_info::is_type()
{
return std::static_pointer_cast<type_info>(shared_from_this());
}
procedure_info::procedure_info(const procedure_type symbol, const std::vector<std::string> names)
: symbol(symbol), names(names)
{
}
std::shared_ptr<procedure_info> procedure_info::is_procedure()
{
return std::static_pointer_cast<procedure_info>(shared_from_this());
}
std::shared_ptr<symbol_table> builtin_symbol_table()
{
auto result = std::make_shared<symbol_table>();
result->enter("Int", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Int"))));
result->enter("Word", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Word"))));
result->enter("Char", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Char"))));
result->enter("Bool", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Bool"))));
result->enter("Byte", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Byte"))));
result->enter("Float", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Float"))));
result->enter("String", std::make_shared<type_info>(type(std::make_shared<primitive_type>("String"))));
return result;
}
}