aboutsummaryrefslogtreecommitdiff
path: root/boot/symbol.cc
diff options
context:
space:
mode:
Diffstat (limited to 'boot/symbol.cc')
-rw-r--r--boot/symbol.cc91
1 files changed, 68 insertions, 23 deletions
diff --git a/boot/symbol.cc b/boot/symbol.cc
index a3a36c1..9985489 100644
--- a/boot/symbol.cc
+++ b/boot/symbol.cc
@@ -43,6 +43,11 @@ namespace elna::boot
{
}
+ type::type(std::shared_ptr<constant_type> constant)
+ : tag(type_tag::constant), constant(constant)
+ {
+ }
+
type::type(std::shared_ptr<array_type> array)
: tag(type_tag::array), array(array)
{
@@ -76,6 +81,9 @@ namespace elna::boot
case type_tag::pointer:
new (&pointer) std::shared_ptr<pointer_type>(other.pointer);
break;
+ case type_tag::constant:
+ new (&constant) std::shared_ptr<constant_type>(other.constant);
+ break;
case type_tag::array:
new (&array) std::shared_ptr<array_type>(other.array);
break;
@@ -112,6 +120,9 @@ namespace elna::boot
case type_tag::pointer:
new (&pointer) std::shared_ptr<pointer_type>(std::move(other.pointer));
break;
+ case type_tag::constant:
+ new (&constant) std::shared_ptr<constant_type>(std::move(other.constant));
+ break;
case type_tag::array:
new (&array) std::shared_ptr<array_type>(std::move(other.array));
break;
@@ -164,6 +175,9 @@ namespace elna::boot
case type_tag::pointer:
this->pointer.~shared_ptr<pointer_type>();
break;
+ case type_tag::constant:
+ this->constant.~shared_ptr<constant_type>();
+ break;
case type_tag::array:
this->array.~shared_ptr<array_type>();
break;
@@ -207,6 +221,12 @@ namespace elna::boot
}
template<>
+ std::shared_ptr<constant_type> type::get<constant_type>() const
+ {
+ return tag == type_tag::constant ? this->constant : nullptr;
+ }
+
+ template<>
std::shared_ptr<procedure_type> type::get<procedure_type>() const
{
return tag == type_tag::procedure ? this->procedure : nullptr;
@@ -225,8 +245,8 @@ namespace elna::boot
bool type::operator==(const type& other) const
{
- type resolved_this = inner_aliased_type(*this);
- type resolved_that = inner_aliased_type(other);
+ type resolved_this = resolve_aliases(*this);
+ type resolved_that = resolve_aliases(other);
if (auto left_record = resolved_this.get<record_type>())
{
@@ -248,6 +268,12 @@ namespace elna::boot
return right_pointer != nullptr && left_pointer->base == right_pointer->base;
}
+ if (auto left_const = resolved_this.get<constant_type>())
+ {
+ auto right_const = resolved_that.get<constant_type>();
+
+ return right_const != nullptr && left_const->unqualified == right_const->unqualified;
+ }
if (auto left_array = resolved_this.get<array_type>())
{
auto right_array = resolved_that.get<array_type>();
@@ -282,6 +308,8 @@ namespace elna::boot
return primitive->identifier;
case type_tag::pointer:
return "^" + pointer->base.to_string();
+ case type_tag::constant:
+ return "const " + constant->unqualified.to_string();
case type_tag::array:
return "[" + std::to_string(array->size) + "]" + array->base.to_string();
case type_tag::record:
@@ -328,6 +356,11 @@ namespace elna::boot
{
}
+ constant_type::constant_type(type unqualified)
+ : unqualified(unqualified)
+ {
+ }
+
array_type::array_type(type base, std::uint64_t size)
: base(base), size(size)
{
@@ -367,11 +400,6 @@ namespace elna::boot
return nullptr;
}
- std::shared_ptr<constant_info> info::is_constant()
- {
- return nullptr;
- }
-
std::shared_ptr<variable_info> info::is_variable()
{
return nullptr;
@@ -403,16 +431,6 @@ namespace elna::boot
return this->scope == nullptr;
}
- constant_info::constant_info(const variant& symbol)
- : symbol(symbol)
- {
- }
-
- std::shared_ptr<constant_info> constant_info::is_constant()
- {
- return std::static_pointer_cast<constant_info>(shared_from_this());
- }
-
variable_info::variable_info(const type symbol, bool is_extern)
: symbol(symbol), is_extern(is_extern)
{
@@ -524,20 +542,47 @@ namespace elna::boot
return m_exported;
}
- type inner_aliased_type(std::shared_ptr<alias_type> alias)
+ type resolve_underlying_type(std::shared_ptr<alias_type> alias)
{
- return inner_aliased_type(alias->reference);
+ return resolve_underlying_type(alias->reference);
}
- type inner_aliased_type(const type& alias)
+ type resolve_underlying_type(const type& alias)
{
- if (auto aliased = alias.get<alias_type>())
+ type resolved_alias = resolve_aliases(alias);
+
+ if (auto qualified = resolved_alias.get<constant_type>())
{
- return inner_aliased_type(aliased);
+ return resolve_underlying_type(qualified->unqualified);
}
else
{
- return alias;
+ return resolved_alias;
+ }
+ }
+
+ type resolve_aliases(const type& checked)
+ {
+ if (auto alias = checked.get<alias_type>())
+ {
+ return resolve_aliases(alias->reference);
+ }
+ return checked;
+ }
+
+ bool is_primitive_type(const type& checked, const std::string& name)
+ {
+ if (auto primitive_checked = checked.get<primitive_type>())
+ {
+ return primitive_checked->identifier == name;
}
+ return false;
+ }
+
+ bool is_any_pointer_type(const type& checked)
+ {
+ return checked.get<pointer_type>() != nullptr
+ || checked.get<procedure_type>() != nullptr
+ || is_primitive_type(checked, "Pointer");
}
}