diff options
Diffstat (limited to 'frontend/symbol.cc')
| -rw-r--r-- | frontend/symbol.cc | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/frontend/symbol.cc b/frontend/symbol.cc new file mode 100644 index 0000000..bfecbd4 --- /dev/null +++ b/frontend/symbol.cc @@ -0,0 +1,427 @@ +/* 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/frontend/symbol.h" + +namespace elna::frontend +{ + 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) + { + } + + type::type(std::shared_ptr<enumeration_type> enumeration) + : tag(type_tag::enumeration), enumeration(enumeration) + { + } + + 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; + case type_tag::enumeration: + new (&enumeration) std::shared_ptr<enumeration_type>(other.enumeration); + 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; + case type_tag::enumeration: + new (&enumeration) std::shared_ptr<enumeration_type>(std::move(other.enumeration)); + 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; + case type_tag::enumeration: + this->enumeration.~shared_ptr<enumeration_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; + } + + template<> + std::shared_ptr<enumeration_type> type::get<enumeration_type>() const + { + return tag == type_tag::enumeration ? this->enumeration : 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) + { + } + + enumeration_type::enumeration_type(const std::vector<std::string>& members) + : members(members) + { + } + + info::~info() + { + } + + std::shared_ptr<type_info> info::is_type() + { + return nullptr; + } + + std::shared_ptr<procedure_info> info::is_procedure() + { + return nullptr; + } + + std::shared_ptr<constant_info> info::is_constant() + { + return nullptr; + } + + std::shared_ptr<variable_info> info::is_variable() + { + 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, + std::shared_ptr<symbol_table> scope) + : symbol(symbol), names(names), scope(scope) + { + } + + std::shared_ptr<procedure_info> procedure_info::is_procedure() + { + return std::static_pointer_cast<procedure_info>(shared_from_this()); + } + + bool procedure_info::is_extern() const + { + 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) + { + } + + std::shared_ptr<variable_info> variable_info::is_variable() + { + return std::static_pointer_cast<variable_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("Pointer", std::make_shared<type_info>(type(std::make_shared<primitive_type>("Pointer")))); + 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; + } + + symbol_bag::symbol_bag(forward_table&& unresolved, std::shared_ptr<symbol_table> global_table) + : unresolved(unresolved) + { + this->symbols = std::make_shared<symbol_table>(global_table); + } + + std::shared_ptr<info> symbol_bag::lookup(const std::string& name) + { + for (auto import_bag : this->imports) + { + if (auto result = import_bag->lookup(name)) + { + return result; + } + } + return this->symbols->lookup(name); + } + + bool symbol_bag::enter(const std::string& name, std::shared_ptr<info> entry) + { + return this->symbols->enter(name, entry); + } + + std::shared_ptr<symbol_table> symbol_bag::enter() + { + this->symbols = std::make_shared<symbol_table>(this->symbols); + return this->symbols; + } + + void symbol_bag::enter(std::shared_ptr<symbol_table> child) + { + this->symbols = child; + } + + std::shared_ptr<symbol_table> symbol_bag::leave() + { + std::shared_ptr<symbol_table> result = this->symbols; + + this->symbols = result->scope(); + return result; + } + + std::shared_ptr<alias_type> symbol_bag::declared(const std::string& symbol_name) + { + auto unresolved_alias = this->unresolved.find(symbol_name); + + return unresolved_alias == this->unresolved.end() ? std::shared_ptr<alias_type>() : unresolved_alias->second; + } + + std::shared_ptr<alias_type> symbol_bag::resolve(const std::string& symbol_name, type& resolution) + { + auto unresolved_declaration = this->unresolved.at(symbol_name); + + unresolved_declaration->reference = resolution; + return unresolved_declaration; + } + + void symbol_bag::add_import(const symbol_bag& bag) + { + this->imports.push_front(bag.symbols); + } +} |
