From 5959fbb5524bbeb05a96eb15aba59e961a3efcb7 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 15 Feb 2026 04:10:38 +0100 Subject: Initial commit --- frontend/symbol.cc | 427 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 427 insertions(+) create mode 100644 frontend/symbol.cc (limited to 'frontend/symbol.cc') 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 +. */ + +#include "elna/frontend/symbol.h" + +namespace elna::frontend +{ + type::type() + { + } + + type::type(std::shared_ptr alias) + : tag(type_tag::alias), alias(alias) + { + } + + type::type(std::shared_ptr primitive) + : tag(type_tag::primitive), primitive(primitive) + { + } + + type::type(std::shared_ptr record) + : tag(type_tag::record), record(record) + { + } + + type::type(std::shared_ptr _union) + : tag(type_tag::_union), _union(_union) + { + } + + type::type(std::shared_ptr pointer) + : tag(type_tag::pointer), pointer(pointer) + { + } + + type::type(std::shared_ptr array) + : tag(type_tag::array), array(array) + { + } + + type::type(std::shared_ptr procedure) + : tag(type_tag::procedure), procedure(procedure) + { + } + + type::type(std::shared_ptr 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(other.alias); + break; + case type_tag::primitive: + new (&primitive) std::shared_ptr(other.primitive); + break; + case type_tag::record: + new (&record) std::shared_ptr(other.record); + break; + case type_tag::_union: + new (&_union) std::shared_ptr(other._union); + break; + case type_tag::pointer: + new (&pointer) std::shared_ptr(other.pointer); + break; + case type_tag::array: + new (&array) std::shared_ptr(other.array); + break; + case type_tag::procedure: + new (&procedure) std::shared_ptr(other.procedure); + break; + case type_tag::enumeration: + new (&enumeration) std::shared_ptr(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(std::move(other.alias)); + break; + case type_tag::primitive: + new (&primitive) std::shared_ptr(std::move(other.primitive)); + break; + case type_tag::record: + new (&record) std::shared_ptr(std::move(other.record)); + break; + case type_tag::_union: + new (&_union) std::shared_ptr(std::move(other._union)); + break; + case type_tag::pointer: + new (&pointer) std::shared_ptr(std::move(other.pointer)); + break; + case type_tag::array: + new (&array) std::shared_ptr(std::move(other.array)); + break; + case type_tag::procedure: + new (&procedure) std::shared_ptr(std::move(other.procedure)); + break; + case type_tag::enumeration: + new (&enumeration) std::shared_ptr(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(); + break; + case type_tag::primitive: + this->primitive.~shared_ptr(); + break; + case type_tag::record: + this->record.~shared_ptr(); + break; + case type_tag::_union: + this->_union.~shared_ptr(); + break; + case type_tag::pointer: + this->pointer.~shared_ptr(); + break; + case type_tag::array: + this->array.~shared_ptr(); + break; + case type_tag::procedure: + this->procedure.~shared_ptr(); + break; + case type_tag::enumeration: + this->enumeration.~shared_ptr(); + break; + } + } + + template<> + std::shared_ptr type::get() const + { + return tag == type_tag::alias ? this->alias.lock() : nullptr; + } + + template<> + std::shared_ptr type::get() const + { + return tag == type_tag::primitive ? this->primitive : nullptr; + } + + template<> + std::shared_ptr type::get() const + { + return tag == type_tag::record ? this->record : nullptr; + } + + template<> + std::shared_ptr type::get() const + { + return tag == type_tag::_union ? this->_union : nullptr; + } + + template<> + std::shared_ptr type::get() const + { + return tag == type_tag::pointer ? this->pointer : nullptr; + } + + template<> + std::shared_ptr type::get() const + { + return tag == type_tag::array ? this->array : nullptr; + } + + template<> + std::shared_ptr type::get() const + { + return tag == type_tag::procedure ? this->procedure : nullptr; + } + + template<> + std::shared_ptr type::get() 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& members) + : members(members) + { + } + + info::~info() + { + } + + std::shared_ptr info::is_type() + { + return nullptr; + } + + std::shared_ptr info::is_procedure() + { + return nullptr; + } + + std::shared_ptr info::is_constant() + { + return nullptr; + } + + std::shared_ptr info::is_variable() + { + return nullptr; + } + + type_info::type_info(const type symbol) + : symbol(symbol) + { + } + + std::shared_ptr type_info::is_type() + { + return std::static_pointer_cast(shared_from_this()); + } + + procedure_info::procedure_info(const procedure_type symbol, const std::vector names, + std::shared_ptr scope) + : symbol(symbol), names(names), scope(scope) + { + } + + std::shared_ptr procedure_info::is_procedure() + { + return std::static_pointer_cast(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::is_constant() + { + return std::static_pointer_cast(shared_from_this()); + } + + variable_info::variable_info(const type symbol, bool is_extern) + : symbol(symbol), is_extern(is_extern) + { + } + + std::shared_ptr variable_info::is_variable() + { + return std::static_pointer_cast(shared_from_this()); + } + + std::shared_ptr builtin_symbol_table() + { + auto result = std::make_shared(); + + result->enter("Int", std::make_shared(type(std::make_shared("Int")))); + result->enter("Word", std::make_shared(type(std::make_shared("Word")))); + result->enter("Char", std::make_shared(type(std::make_shared("Char")))); + result->enter("Bool", std::make_shared(type(std::make_shared("Bool")))); + result->enter("Pointer", std::make_shared(type(std::make_shared("Pointer")))); + result->enter("Float", std::make_shared(type(std::make_shared("Float")))); + result->enter("String", std::make_shared(type(std::make_shared("String")))); + + return result; + } + + symbol_bag::symbol_bag(forward_table&& unresolved, std::shared_ptr global_table) + : unresolved(unresolved) + { + this->symbols = std::make_shared(global_table); + } + + std::shared_ptr 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 entry) + { + return this->symbols->enter(name, entry); + } + + std::shared_ptr symbol_bag::enter() + { + this->symbols = std::make_shared(this->symbols); + return this->symbols; + } + + void symbol_bag::enter(std::shared_ptr child) + { + this->symbols = child; + } + + std::shared_ptr symbol_bag::leave() + { + std::shared_ptr result = this->symbols; + + this->symbols = result->scope(); + return result; + } + + std::shared_ptr 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() : unresolved_alias->second; + } + + std::shared_ptr 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); + } +} -- cgit v1.2.3