diff --git a/boot/ast.cc b/boot/ast.cc index ac0b57e..5d6d5e3 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -23,215 +23,167 @@ namespace boot { void empty_visitor::visit(variable_declaration *) { + __builtin_unreachable(); } - void empty_visitor::visit(constant_definition *definition) + void empty_visitor::visit(constant_definition *) { - definition->body().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(procedure_definition *definition) + void empty_visitor::visit(procedure_definition *) { - definition->heading().accept(this); - if (definition->body != nullptr) - { - definition->body->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(type_definition *definition) + void empty_visitor::visit(type_definition *) { - definition->body().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(procedure_call *call) + void empty_visitor::visit(procedure_call *) { - for (expression *const argument : call->arguments) - { - argument->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(traits_expression *trait) + void empty_visitor::visit(traits_expression *) { - trait->type().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(cast_expression *expression) + void empty_visitor::visit(cast_expression *) { - expression->target().accept(this); - expression->value().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(assign_statement *statement) + void empty_visitor::visit(assign_statement *) { - statement->rvalue().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(if_statement *statement) + void empty_visitor::visit(if_statement *) { - statement->body().prerequisite().accept(this); - for (const auto body_statement : statement->body().statements) - { - body_statement->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(while_statement *statement) + void empty_visitor::visit(while_statement *) { - statement->body().prerequisite().accept(this); - for (const auto body_statement : statement->body().statements) - { - body_statement->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(return_statement *statement) + void empty_visitor::visit(return_statement *) { - expression *return_expression = statement->return_expression(); - - if (return_expression != nullptr) - { - return_expression->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(defer_statement *defer) + void empty_visitor::visit(defer_statement *) { - for (statement *const body_statement : defer->statements) - { - body_statement->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(block *block) + void empty_visitor::visit(block *) { - for (constant_definition *const constant : block->constants) - { - constant->accept(this); - } - for (variable_declaration *const variable : block->variables) - { - variable->accept(this); - } - for (statement *const body_statement : block->body) - { - body_statement->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(program *program) + void empty_visitor::visit(program *) { - visit(reinterpret_cast(program)); - for (type_definition *const type : program->types) - { - type->accept(this); - } - for (procedure_definition *const procedure : program->procedures) - { - procedure->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(binary_expression *expression) + void empty_visitor::visit(binary_expression *) { - expression->lhs().accept(this); - expression->rhs().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(unary_expression *expression) + void empty_visitor::visit(unary_expression *) { - expression->operand().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(basic_type *) + void empty_visitor::visit(primitive_type_expression *) { + __builtin_unreachable(); } - void empty_visitor::visit(array_type *expression) + void empty_visitor::visit(array_type_expression *) { - expression->base().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(pointer_type *expression) + void empty_visitor::visit(pointer_type_expression *) { - expression->base().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(record_type *expression) + void empty_visitor::visit(record_type_expression *) { - for (auto& field : expression->fields) - { - field.second->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(union_type *expression) + void empty_visitor::visit(union_type_expression *) { - for (auto& field : expression->fields) - { - field.second->accept(this); - } + __builtin_unreachable(); } - void empty_visitor::visit(procedure_type *expression) + void empty_visitor::visit(procedure_type_expression *) { - for (auto parameter : expression->parameters) - { - parameter->accept(this); - } - if (expression->return_type != nullptr) - { - expression->return_type->accept(this); - } + __builtin_unreachable(); } void empty_visitor::visit(variable_expression *) { + __builtin_unreachable(); } - void empty_visitor::visit(array_access_expression *expression) + void empty_visitor::visit(array_access_expression *) { - expression->base().accept(this); - expression->index().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(field_access_expression *expression) + void empty_visitor::visit(field_access_expression *) { - expression->base().accept(this); + __builtin_unreachable(); } - void empty_visitor::visit(dereference_expression *expression) + void empty_visitor::visit(dereference_expression *) { - expression->base().accept(this); + __builtin_unreachable(); } void empty_visitor::visit(number_literal *) { + __builtin_unreachable(); } void empty_visitor::visit(number_literal *) { + __builtin_unreachable(); } void empty_visitor::visit(number_literal *) { + __builtin_unreachable(); } void empty_visitor::visit(number_literal *) { + __builtin_unreachable(); } void empty_visitor::visit(number_literal *) { + __builtin_unreachable(); } void empty_visitor::visit(number_literal *) { + __builtin_unreachable(); } void empty_visitor::visit(number_literal *) { + __builtin_unreachable(); } node::node(const struct position position) @@ -252,78 +204,80 @@ namespace boot { } - top_type::top_type(const struct position position) + type_expression::type_expression(const struct position position) : node(position) { } - basic_type::basic_type(const struct position position, const std::string& name) - : top_type(position), m_name(name) + primitive_type_expression::primitive_type_expression(const struct position position, const std::string& name) + : type_expression(position), m_name(name) { } - void basic_type::accept(parser_visitor *visitor) + void primitive_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - const std::string& basic_type::base_name() + const std::string& primitive_type_expression::base_name() { return m_name; } - array_type::array_type(const struct position position, std::shared_ptr base, const std::uint32_t size) - : top_type(position), m_base(base), size(size) + array_type_expression::array_type_expression(const struct position position, + std::shared_ptr base, const std::uint32_t size) + : type_expression(position), m_base(base), size(size) { } - void array_type::accept(parser_visitor *visitor) + void array_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - top_type& array_type::base() + type_expression& array_type_expression::base() { return *m_base; } - pointer_type::pointer_type(const struct position position, std::shared_ptr base) - : top_type(position), m_base(base) + pointer_type_expression::pointer_type_expression(const struct position position, + std::shared_ptr base) + : type_expression(position), m_base(base) { } - void pointer_type::accept(parser_visitor *visitor) + void pointer_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - top_type& pointer_type::base() + type_expression& pointer_type_expression::base() { return *m_base; } - record_type::record_type(const struct position position, fields_t&& fields) - : top_type(position), fields(std::move(fields)) + record_type_expression::record_type_expression(const struct position position, fields_t&& fields) + : type_expression(position), fields(std::move(fields)) { } - void record_type::accept(parser_visitor *visitor) + void record_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - union_type::union_type(const struct position position, fields_t&& fields) - : top_type(position), fields(std::move(fields)) + union_type_expression::union_type_expression(const struct position position, fields_t&& fields) + : type_expression(position), fields(std::move(fields)) { } - void union_type::accept(parser_visitor *visitor) + void union_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } variable_declaration::variable_declaration(const struct position position, const std::string& identifier, - std::shared_ptr type, const bool exported) + std::shared_ptr type, const bool exported) : definition(position, identifier, exported), m_type(type) { } @@ -333,7 +287,7 @@ namespace boot visitor->visit(this); } - top_type& variable_declaration::variable_type() + type_expression& variable_declaration::variable_type() { return *m_type; } @@ -364,22 +318,23 @@ namespace boot delete m_body; } - procedure_type::procedure_type(const struct position position, std::shared_ptr return_type) - : top_type(position), return_type(return_type), no_return(false) + procedure_type_expression::procedure_type_expression(const struct position position, + std::shared_ptr return_type) + : type_expression(position), return_type(return_type), no_return(false) { } - procedure_type::procedure_type(const struct position position, no_return_t) - : top_type(position), return_type(nullptr), no_return(true) + procedure_type_expression::procedure_type_expression(const struct position position, no_return_t) + : type_expression(position), return_type(nullptr), no_return(true) { } - void procedure_type::accept(parser_visitor *visitor) + void procedure_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - procedure_type::~procedure_type() + procedure_type_expression::~procedure_type_expression() { for (auto parameter : this->parameters) { @@ -388,7 +343,7 @@ namespace boot } procedure_definition::procedure_definition(const struct position position, const std::string& identifier, - const bool exported, std::shared_ptr heading, block *body) + const bool exported, std::shared_ptr heading, block *body) : definition(position, identifier, exported), m_heading(heading), body(body) { } @@ -398,7 +353,7 @@ namespace boot visitor->visit(this); } - procedure_type& procedure_definition::heading() + procedure_type_expression& procedure_definition::heading() { return *m_heading; } @@ -409,7 +364,7 @@ namespace boot } type_definition::type_definition(const struct position position, const std::string& identifier, - const bool exported, std::shared_ptr body) + const bool exported, std::shared_ptr body) : definition(position, identifier, exported), m_body(body) { } @@ -419,7 +374,7 @@ namespace boot visitor->visit(this); } - top_type& type_definition::body() + type_expression& type_definition::body() { return *m_body; } @@ -685,7 +640,7 @@ namespace boot } cast_expression::cast_expression(const struct position position, - std::shared_ptr target, expression *value) + std::shared_ptr target, expression *value) : node(position), m_target(target), m_value(value) { } @@ -695,7 +650,7 @@ namespace boot visitor->visit(this); } - top_type& cast_expression::target() + type_expression& cast_expression::target() { return *m_target; } @@ -711,7 +666,7 @@ namespace boot } traits_expression::traits_expression(const struct position position, - const std::string& name, std::shared_ptr type) + const std::string& name, std::shared_ptr type) : node(position), m_type(type), name(name) { } @@ -721,7 +676,7 @@ namespace boot visitor->visit(this); } - top_type& traits_expression::type() + type_expression& traits_expression::type() { return *m_type; } diff --git a/boot/parser.yy b/boot/parser.yy index b740b70..13f9fe7 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -125,7 +125,7 @@ along with GCC; see the file COPYING3. If not see %type > variable_declarations variable_part variable_declaration formal_parameters formal_parameter_list; %type formal_parameter -%type > type_expression; +%type > type_expression; %type traits_expression; %type expression operand; %type unary_expression; @@ -140,13 +140,14 @@ along with GCC; see the file COPYING3. If not see %type statement; %type > statements; %type procedure_definition; -%type > procedure_heading; +%type > procedure_heading; %type > procedure_definitions procedure_part; %type type_definition; %type > type_definitions type_part; %type block; %type field_declaration; -%type >>> optional_fields required_fields; +%type >>> + optional_fields required_fields; %type > elsif_then_statements elsif_do_statements; %type cast_expression; %type defer_statement; @@ -193,17 +194,18 @@ identifier_definitions: procedure_heading: formal_parameter_list { - $$ = std::make_shared(elna::boot::make_position(@1)); + $$ = std::make_shared(elna::boot::make_position(@1)); std::swap($1, $$->parameters); } | formal_parameter_list "->" "!" { - $$ = std::make_shared(elna::boot::make_position(@1), elna::boot::no_return); + $$ = std::make_shared(elna::boot::make_position(@1), + elna::boot::no_return); std::swap($1, $$->parameters); } | formal_parameter_list "->" type_expression { - $$ = std::make_shared(elna::boot::make_position(@1), $3); + $$ = std::make_shared(elna::boot::make_position(@1), $3); std::swap($1, $$->parameters); } procedure_definition: @@ -484,19 +486,19 @@ optional_fields: type_expression: "[" INTEGER "]" type_expression { - $$ = std::make_shared(elna::boot::make_position(@1), $4, $2); + $$ = std::make_shared(elna::boot::make_position(@1), $4, $2); } | "^" type_expression { - $$ = std::make_shared(elna::boot::make_position(@1), $2); + $$ = std::make_shared(elna::boot::make_position(@1), $2); } | "record" optional_fields "end" { - $$ = std::make_shared(elna::boot::make_position(@1), std::move($2)); + $$ = std::make_shared(elna::boot::make_position(@1), std::move($2)); } | "union" required_fields "end" { - $$ = std::make_shared(elna::boot::make_position(@1), std::move($2)); + $$ = std::make_shared(elna::boot::make_position(@1), std::move($2)); } | "proc" procedure_heading { @@ -504,7 +506,7 @@ type_expression: } | IDENTIFIER { - $$ = std::make_shared(elna::boot::make_position(@1), $1); + $$ = std::make_shared(elna::boot::make_position(@1), $1); } variable_declaration: identifier_definitions ":" type_expression { diff --git a/boot/semantic.cc b/boot/semantic.cc new file mode 100644 index 0000000..bb8c698 --- /dev/null +++ b/boot/semantic.cc @@ -0,0 +1,33 @@ +/* Semantic analysis visitors. + 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/boot/semantic.h" + +namespace elna +{ +namespace boot +{ + name_analysis_visitor::name_analysis_visitor(std::shared_ptr> table) + : table(table) + { + } + + void name_analysis_visitor::visit(program *program) + { + } +} +} diff --git a/boot/symbol.cc b/boot/symbol.cc new file mode 100644 index 0000000..c657fa6 --- /dev/null +++ b/boot/symbol.cc @@ -0,0 +1,32 @@ +/* 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/boot/symbol.h" + +namespace elna +{ +namespace boot +{ + type::~type() + { + } + + info::~info() + { + } +} +} diff --git a/gcc/Make-lang.in b/gcc/Make-lang.in index 3e7190b..a9fed82 100644 --- a/gcc/Make-lang.in +++ b/gcc/Make-lang.in @@ -46,6 +46,8 @@ elna_OBJS = \ elna/driver.o \ elna/lexer.o \ elna/parser.o \ + elna/semantic.o \ + elna/symbol.o \ elna/result.o \ $(END) @@ -134,7 +136,7 @@ elna.stagefeedback: stagefeedback-start -mv elna/*$(objext) stagefeedback/elna ELNA_INCLUDES = -I $(srcdir)/elna/include -I elna/generated -ELNA_CXXFLAGS = -std=c++11 +ELNA_CXXFLAGS = -std=c++14 elna/%.o: elna/boot/%.cc elna/generated/parser.hh elna/generated/location.hh $(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $< diff --git a/gcc/elna-generic.cc b/gcc/elna-generic.cc index aa32df6..398ce0c 100644 --- a/gcc/elna-generic.cc +++ b/gcc/elna-generic.cc @@ -751,13 +751,13 @@ namespace gcc this->current_expression = NULL_TREE; } - tree generic_visitor::build_procedure_type(boot::procedure_type& type) + tree generic_visitor::build_procedure_type(boot::procedure_type_expression& type) { std::vector parameter_types(type.parameters.size()); for (std::size_t i = 0; i < type.parameters.size(); ++i) { - boot::top_type& parameter_type = type.parameters.at(i)->variable_type(); + boot::type_expression& parameter_type = type.parameters.at(i)->variable_type(); parameter_type.accept(this); parameter_types[i] = this->current_expression; } @@ -1102,7 +1102,7 @@ namespace gcc this->current_expression = NULL_TREE; } - void generic_visitor::visit(boot::basic_type *type) + void generic_visitor::visit(boot::primitive_type_expression *type) { tree symbol = this->lookup(type->base_name()); @@ -1119,7 +1119,7 @@ namespace gcc } } - void generic_visitor::visit(boot::array_type *type) + void generic_visitor::visit(boot::array_type_expression *type) { tree lower_bound = build_int_cst_type(integer_type_node, 0); tree upper_bound = build_int_cst_type(integer_type_node, type->size); @@ -1133,7 +1133,7 @@ namespace gcc } } - void generic_visitor::visit(boot::pointer_type *type) + void generic_visitor::visit(boot::pointer_type_expression *type) { type->base().accept(this); @@ -1143,7 +1143,7 @@ namespace gcc } } - void generic_visitor::visit(boot::record_type *type) + void generic_visitor::visit(boot::record_type_expression *type) { std::set field_names; tree record_type_node = make_node(RECORD_TYPE); @@ -1172,7 +1172,7 @@ namespace gcc this->current_expression = record_type_node; } - void generic_visitor::visit(boot::union_type *type) + void generic_visitor::visit(boot::union_type_expression *type) { std::set field_names; tree union_type_node = make_node(UNION_TYPE); @@ -1201,7 +1201,7 @@ namespace gcc this->current_expression = union_type_node; } - void generic_visitor::visit(boot::procedure_type *type) + void generic_visitor::visit(boot::procedure_type_expression *type) { tree procedure_type_node = build_procedure_type(*type); this->current_expression = build_pointer_type_for_mode(procedure_type_node, VOIDmode, true); diff --git a/gcc/elna1.cc b/gcc/elna1.cc index a6d8331..3979a68 100644 --- a/gcc/elna1.cc +++ b/gcc/elna1.cc @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include #include "elna/boot/driver.h" +#include "elna/boot/semantic.h" #include "elna/gcc/elna-tree.h" #include "elna/gcc/elna-generic.h" #include "elna/gcc/elna-diagnostic.h" @@ -88,8 +89,10 @@ static void elna_parse_file(const char *filename) } else { + elna::boot::name_analysis_visitor name_analysis_visitor{ std::make_shared>() }; elna::gcc::generic_visitor generic_visitor{ std::make_shared() }; + name_analysis_visitor.visit(driver.tree.get()); generic_visitor.visit(driver.tree.get()); } linemap_add(line_table, LC_LEAVE, 0, NULL, 0); diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index 9bc523f..1911123 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -69,12 +69,12 @@ namespace boot class program; class binary_expression; class unary_expression; - class basic_type; - class array_type; - class pointer_type; - class record_type; - class union_type; - class procedure_type; + class primitive_type_expression; + class array_type_expression; + class pointer_type_expression; + class record_type_expression; + class union_type_expression; + class procedure_type_expression; class variable_expression; class array_access_expression; class field_access_expression; @@ -104,16 +104,16 @@ namespace boot virtual void visit(program *) = 0; virtual void visit(binary_expression *) = 0; virtual void visit(unary_expression *) = 0; - virtual void visit(basic_type *) = 0; - virtual void visit(array_type *) = 0; - virtual void visit(pointer_type *) = 0; - virtual void visit(record_type *) = 0; - virtual void visit(union_type *) = 0; - virtual void visit(procedure_type *) = 0; + virtual void visit(primitive_type_expression *) = 0; + virtual void visit(array_type_expression *) = 0; + virtual void visit(pointer_type_expression *) = 0; + virtual void visit(record_type_expression *) = 0; + virtual void visit(union_type_expression *) = 0; + virtual void visit(procedure_type_expression *) = 0; virtual void visit(variable_expression *) = 0; virtual void visit(array_access_expression *) = 0; - virtual void visit(field_access_expression *is_field_access) = 0; - virtual void visit(dereference_expression *is_dereference) = 0; + virtual void visit(field_access_expression *) = 0; + virtual void visit(dereference_expression *) = 0; virtual void visit(number_literal *) = 0; virtual void visit(number_literal *) = 0; virtual void visit(number_literal *) = 0; @@ -129,31 +129,31 @@ namespace boot struct empty_visitor : parser_visitor { virtual void visit(variable_declaration *) override; - virtual void visit(constant_definition *definition) override; - virtual void visit(procedure_definition *definition) override; - virtual void visit(type_definition *definition) override; - virtual void visit(traits_expression *trait) override; - virtual void visit(procedure_call *call) override; - virtual void visit(cast_expression *expression) override; - virtual void visit(assign_statement *statement) override; + virtual void visit(constant_definition *) override; + virtual void visit(procedure_definition *) override; + virtual void visit(type_definition *) override; + virtual void visit(traits_expression *) override; + virtual void visit(procedure_call *) override; + virtual void visit(cast_expression *) override; + virtual void visit(assign_statement *) override; virtual void visit(if_statement *) override; virtual void visit(while_statement *) override; virtual void visit(return_statement *) override; - virtual void visit(defer_statement *defer) override; - virtual void visit(block *block) override; - virtual void visit(program *program) override; - virtual void visit(binary_expression *expression) override; - virtual void visit(unary_expression *expression) override; - virtual void visit(basic_type *) override; - virtual void visit(array_type *expression) override; - virtual void visit(pointer_type *) override; - virtual void visit(record_type *expression) override; - virtual void visit(union_type *expression) override; - virtual void visit(procedure_type *expression) override; + virtual void visit(defer_statement *) override; + virtual void visit(block *) override; + virtual void visit(program *) override; + virtual void visit(binary_expression *) override; + virtual void visit(unary_expression *) override; + virtual void visit(primitive_type_expression *) override; + virtual void visit(array_type_expression *) override; + virtual void visit(pointer_type_expression *) override; + virtual void visit(record_type_expression *) override; + virtual void visit(union_type_expression *) override; + virtual void visit(procedure_type_expression *) override; virtual void visit(variable_expression *) override; - virtual void visit(array_access_expression *expression) override; - virtual void visit(field_access_expression *expression) override; - virtual void visit(dereference_expression *expression) override; + virtual void visit(array_access_expression *) override; + virtual void visit(field_access_expression *) override; + virtual void visit(dereference_expression *) override; virtual void visit(number_literal *) override; virtual void visit(number_literal *) override; virtual void visit(number_literal *) override; @@ -214,16 +214,16 @@ namespace boot /** * Some type expression. */ - class top_type : public node, public std::enable_shared_from_this + class type_expression : public node, public std::enable_shared_from_this { protected: - top_type(const struct position position); + type_expression(const struct position position); }; /** * Expression defining a basic type. */ - class basic_type : public top_type + class primitive_type_expression : public type_expression { const std::string m_name; @@ -232,55 +232,56 @@ namespace boot * \param position Source code position. * \param name Type name. */ - basic_type(const struct position position, const std::string& name); + primitive_type_expression(const struct position position, const std::string& name); virtual void accept(parser_visitor *visitor) override; const std::string& base_name(); }; - class array_type : public top_type + class array_type_expression : public type_expression { - std::shared_ptr m_base; + std::shared_ptr m_base; public: const std::uint32_t size; - array_type(const struct position position, std::shared_ptr base, const std::uint32_t size); + array_type_expression(const struct position position, + std::shared_ptr base, const std::uint32_t size); virtual void accept(parser_visitor *visitor) override; - top_type& base(); + type_expression& base(); }; - class pointer_type : public top_type + class pointer_type_expression : public type_expression { - std::shared_ptr m_base; + std::shared_ptr m_base; public: - pointer_type(const struct position position, std::shared_ptr base); + pointer_type_expression(const struct position position, std::shared_ptr base); virtual void accept(parser_visitor *visitor) override; - top_type& base(); + type_expression& base(); }; - using field_t = std::pair>; + using field_t = std::pair>; using fields_t = std::vector; - class record_type : public top_type + class record_type_expression : public type_expression { public: fields_t fields; - record_type(const struct position position, fields_t&& fields); + record_type_expression(const struct position position, fields_t&& fields); virtual void accept(parser_visitor *visitor) override; }; - class union_type : public top_type + class union_type_expression : public type_expression { public: fields_t fields; - union_type(const struct position position, fields_t&& fields); + union_type_expression(const struct position position, fields_t&& fields); virtual void accept(parser_visitor *visitor) override; }; @@ -290,14 +291,14 @@ namespace boot */ class variable_declaration : public definition { - std::shared_ptr m_type; + std::shared_ptr m_type; public: variable_declaration(const struct position position, const std::string& identifier, - std::shared_ptr type, const bool exported = false); + std::shared_ptr type, const bool exported = false); virtual void accept(parser_visitor *visitor) override; - top_type& variable_type(); + type_expression& variable_type(); }; /** @@ -342,19 +343,20 @@ namespace boot /** * Procedure type. */ - class procedure_type : public top_type + class procedure_type_expression : public type_expression { public: - const std::shared_ptr return_type; + const std::shared_ptr return_type; const bool no_return; std::vector parameters; - procedure_type(const struct position position, std::shared_ptr return_type = nullptr); - procedure_type(const struct position position, no_return_t); + procedure_type_expression(const struct position position, + std::shared_ptr return_type = nullptr); + procedure_type_expression(const struct position position, no_return_t); virtual void accept(parser_visitor *visitor) override; - virtual ~procedure_type() override; + virtual ~procedure_type_expression() override; }; /** @@ -362,16 +364,16 @@ namespace boot */ class procedure_definition : public definition { - std::shared_ptr m_heading; + std::shared_ptr m_heading; public: block *const body; procedure_definition(const struct position position, const std::string& identifier, - const bool exported, std::shared_ptr heading, block *body = nullptr); + const bool exported, std::shared_ptr heading, block *body = nullptr); virtual void accept(parser_visitor *visitor) override; - procedure_type& heading(); + procedure_type_expression& heading(); virtual ~procedure_definition() override; }; @@ -381,14 +383,14 @@ namespace boot */ class type_definition : public definition { - std::shared_ptr m_body; + std::shared_ptr m_body; public: type_definition(const struct position position, const std::string& identifier, - const bool exported, std::shared_ptr expression); + const bool exported, std::shared_ptr expression); virtual void accept(parser_visitor *visitor) override; - top_type& body(); + type_expression& body(); }; /** @@ -396,14 +398,14 @@ namespace boot */ class cast_expression : public expression { - std::shared_ptr m_target; + std::shared_ptr m_target; expression *m_value; public: - cast_expression(const struct position position, std::shared_ptr target, expression *value); + cast_expression(const struct position position, std::shared_ptr target, expression *value); virtual void accept(parser_visitor *visitor) override; - top_type& target(); + type_expression& target(); expression& value(); virtual ~cast_expression() override; @@ -411,15 +413,16 @@ namespace boot class traits_expression : public expression { - std::shared_ptr m_type; + std::shared_ptr m_type; public: const std::string name; - traits_expression(const struct position position, const std::string& name, std::shared_ptr type); + traits_expression(const struct position position, const std::string& name, + std::shared_ptr type); virtual void accept(parser_visitor *visitor) override; - top_type& type(); + type_expression& type(); }; /** diff --git a/include/elna/boot/semantic.h b/include/elna/boot/semantic.h new file mode 100644 index 0000000..fef5052 --- /dev/null +++ b/include/elna/boot/semantic.h @@ -0,0 +1,37 @@ +/* Semantic analysis visitors. + 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 +. */ + +#pragma once + +#include "elna/boot/ast.h" +#include "elna/boot/symbol.h" + +namespace elna +{ +namespace boot +{ + class name_analysis_visitor : public empty_visitor + { + std::shared_ptr> table; + + public: + name_analysis_visitor(std::shared_ptr> table); + + void visit(program *program) override; + }; +} +} diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h index 30bac72..c7aff3d 100644 --- a/include/elna/boot/symbol.h +++ b/include/elna/boot/symbol.h @@ -26,10 +26,27 @@ namespace elna { namespace boot { + class type + { + virtual ~type() = 0; + + protected: + type() = default; + }; + + class info + { + public: + virtual ~info() = 0; + + protected: + info() = default; + }; + /** * Symbol table. */ - template + template, typename U = std::nullptr_t, U nothing = nullptr> class symbol_table { public: diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index d3ddde9..55ff981 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -40,7 +40,7 @@ namespace gcc std::shared_ptr symbol_map; tree build_label_decl(const char *name, location_t loc); - tree build_procedure_type(boot::procedure_type& type); + tree build_procedure_type(boot::procedure_type_expression& type); void enter_scope(); tree leave_scope(); @@ -89,12 +89,12 @@ namespace gcc void visit(boot::assign_statement *statement) override; void visit(boot::if_statement *statement) override; void visit(boot::while_statement *statement) override; - void visit(boot::basic_type *type) override; - void visit(boot::array_type *type) override; - void visit(boot::pointer_type *type) override; - void visit(boot::record_type *type) override; - void visit(boot::union_type *type) override; - void visit(boot::procedure_type *type) override; + void visit(boot::primitive_type_expression *type) override; + void visit(boot::array_type_expression *type) override; + void visit(boot::pointer_type_expression *type) override; + void visit(boot::record_type_expression *type) override; + void visit(boot::union_type_expression *type) override; + void visit(boot::procedure_type_expression *type) override; void visit(boot::return_statement *statement) override; void visit(boot::defer_statement *statement) override; }; diff --git a/include/elna/gcc/elna-tree.h b/include/elna/gcc/elna-tree.h index 1f83b05..1a0092c 100644 --- a/include/elna/gcc/elna-tree.h +++ b/include/elna/gcc/elna-tree.h @@ -33,7 +33,7 @@ namespace elna { namespace gcc { - using symbol_table = boot::symbol_table; + using symbol_table = boot::symbol_table; bool is_pointer_type(tree type); bool is_integral_type(tree type);