diff options
| -rw-r--r-- | boot/ast.cc | 45 | ||||
| -rw-r--r-- | boot/parser.yy | 6 | ||||
| -rw-r--r-- | boot/semantic.cc | 93 | ||||
| -rw-r--r-- | gcc/gcc/elna-generic.cc | 97 | ||||
| -rw-r--r-- | include/elna/boot/ast.h | 24 | ||||
| -rw-r--r-- | include/elna/boot/semantic.h | 18 | ||||
| -rw-r--r-- | include/elna/gcc/elna-generic.h | 1 |
7 files changed, 122 insertions, 162 deletions
diff --git a/boot/ast.cc b/boot/ast.cc index 3599308..b6ce4b3 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -39,11 +39,6 @@ namespace elna::boot not_implemented(); } - void empty_visitor::visit(program *) - { - not_implemented(); - } - void empty_visitor::visit(type_declaration *) { not_implemented(); @@ -383,8 +378,14 @@ namespace elna::boot } record_type_expression::record_type_expression(const struct position position, - std::vector<field_declaration>&& fields, std::optional<std::string> base) - : node(position), fields(std::move(fields)), base(base) + std::vector<field_declaration>&& fields) + : node(position), fields(std::move(fields)) + { + } + + record_type_expression::record_type_expression(const struct position position, + std::vector<field_declaration>&& fields, std::string&& base) + : node(position), fields(std::move(fields)), base(std::make_optional<std::string>(std::move(base))) { } @@ -493,7 +494,8 @@ namespace elna::boot return this; } - enumeration_type_expression::enumeration_type_expression(const struct position position, std::vector<std::string>&& members) + enumeration_type_expression::enumeration_type_expression(const struct position position, + std::vector<std::string>&& members) : node(position), members(members) { } @@ -510,13 +512,13 @@ namespace elna::boot procedure_declaration::procedure_declaration(const struct position position, identifier_definition identifier, procedure_type_expression *heading, block&& body) - : declaration(position, identifier), m_heading(heading), body(std::move(body)) + : declaration(position, identifier), m_heading(heading), body(std::make_optional<block>(std::move(body))) { } procedure_declaration::procedure_declaration(const struct position position, identifier_definition identifier, procedure_type_expression *heading) - : declaration(position, identifier), m_heading(heading), body(std::nullopt) + : declaration(position, identifier), m_heading(heading) { } @@ -618,6 +620,11 @@ namespace elna::boot { } + unit::unit(const struct position position, std::vector<statement *>&& body) + : node(position), body(std::make_optional<std::vector<statement *>>(std::move(body))) + { + } + void unit::accept(parser_visitor *visitor) { visitor->visit(this); @@ -647,24 +654,6 @@ namespace elna::boot } } - program::program(const struct position position) - : unit(position) - { - } - - void program::accept(parser_visitor *visitor) - { - visitor->visit(this); - } - - program::~program() - { - for (statement *body_statement : this->body) - { - delete body_statement; - } - } - literal_expression *literal_expression::is_literal() { return this; diff --git a/boot/parser.yy b/boot/parser.yy index 7797dd1..42840ff 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -164,8 +164,8 @@ program: { if ($6) { - boot::program *tree = new boot::program(boot::make_position(@1)); - std::swap(tree->body, *$6.release()); + boot::unit *tree = new boot::unit(boot::make_position(@1)); + tree->body = std::make_optional<std::vector<boot::statement *>>(std::move(*$6.release())); driver.tree.reset(tree); } @@ -460,7 +460,7 @@ type_expression: } | "record" optional_fields "end" { - $$ = new boot::record_type_expression(boot::make_position(@1), std::move($2), std::nullopt); + $$ = new boot::record_type_expression(boot::make_position(@1), std::move($2)); } | "record" "(" IDENTIFIER ")" optional_fields "end" { diff --git a/boot/semantic.cc b/boot/semantic.cc index a48226b..0530448 100644 --- a/boot/semantic.cc +++ b/boot/semantic.cc @@ -96,11 +96,6 @@ namespace elna::boot { } - void type_analysis_visitor::visit(program *program) - { - visit(static_cast<unit *>(program)); - } - void type_analysis_visitor::visit(procedure_declaration *definition) { if (definition->body.has_value() && definition->heading().return_type.proper_type != nullptr) @@ -195,17 +190,17 @@ namespace elna::boot } std::pair<procedure_type, std::vector<std::string>> name_analysis_visitor::build_procedure( - procedure_type_expression& type_expression) + procedure_type_expression& expression) { procedure_type::return_t result_return; - if (type_expression.return_type.no_return) + if (expression.return_type.no_return) { result_return = procedure_type::return_t(std::monostate{}); } - else if (type_expression.return_type.proper_type != nullptr) + else if (expression.return_type.proper_type != nullptr) { - type_expression.return_type.proper_type->accept(this); + expression.return_type.proper_type->accept(this); result_return = procedure_type::return_t(this->current_type); } else @@ -215,7 +210,7 @@ namespace elna::boot std::pair<procedure_type, std::vector<std::string>> result_type{ procedure_type(result_return), std::vector<std::string>() }; - for (auto& [parameter_names, parameters_type] : type_expression.parameters) + for (auto& [parameter_names, parameters_type] : expression.parameters) { parameters_type->accept(this); for (auto& parameter_name : parameter_names) @@ -227,26 +222,6 @@ namespace elna::boot return result_type; } - void name_analysis_visitor::visit(program *program) - { - visit(static_cast<unit *>(program)); - - this->bag.enter(); - auto variable_type = this->bag.lookup("Int")->is_type()->symbol; - this->bag.enter("count", std::make_shared<variable_info>(variable_type, false)); - - variable_type = this->bag.lookup("Char")->is_type()->symbol; - variable_type = type(std::make_shared<pointer_type>(variable_type)); - variable_type = type(std::make_shared<pointer_type>(variable_type)); - this->bag.enter("parameters", std::make_shared<variable_info>(variable_type, false)); - - for (statement *const statement : program->body) - { - statement->accept(this); - } - this->bag.leave(); - } - void name_analysis_visitor::visit(type_declaration *definition) { definition->body().accept(this); @@ -261,16 +236,16 @@ namespace elna::boot { } - void name_analysis_visitor::visit(pointer_type_expression *type_expression) + void name_analysis_visitor::visit(pointer_type_expression *expression) { - type_expression->base().accept(this); + expression->base().accept(this); this->current_type = type(std::make_shared<pointer_type>(this->current_type)); } - void name_analysis_visitor::visit(array_type_expression *type_expression) + void name_analysis_visitor::visit(array_type_expression *expression) { - type_expression->base().accept(this); - auto result_type{ std::make_shared<array_type>(this->current_type, type_expression->size) }; + expression->base().accept(this); + auto result_type = std::make_shared<array_type>(this->current_type, expression->size); this->current_type = type(result_type); } @@ -299,16 +274,16 @@ namespace elna::boot return result; } - void name_analysis_visitor::visit(record_type_expression *type_expression) + void name_analysis_visitor::visit(record_type_expression *expression) { std::shared_ptr<record_type> result_type; - if (type_expression->base.has_value()) + if (expression->base.has_value()) { - if (auto unresolved_alias = this->bag.declared(type_expression->base.value())) + if (auto unresolved_alias = this->bag.declared(expression->base.value())) { result_type = std::make_shared<record_type>(type(unresolved_alias)); } - else if (auto base_symbol = this->bag.lookup(type_expression->base.value())) + else if (auto base_symbol = this->bag.lookup(expression->base.value())) { if (auto base_type_info = base_symbol->is_type()) { @@ -316,14 +291,14 @@ namespace elna::boot } else { - add_error<base_type_error>(type_expression->base.value(), type_expression->position()); + add_error<base_type_error>(expression->base.value(), expression->position()); this->current_type = type(); return; } } else { - add_error<undeclared_error>(type_expression->base.value(), type_expression->position()); + add_error<undeclared_error>(expression->base.value(), expression->position()); this->current_type = type(); return; } @@ -332,31 +307,31 @@ namespace elna::boot { result_type = std::make_shared<record_type>(); } - result_type->fields = build_composite_type(type_expression->fields); + result_type->fields = build_composite_type(expression->fields); this->current_type = type(result_type); } - void name_analysis_visitor::visit(union_type_expression *type_expression) + void name_analysis_visitor::visit(union_type_expression *expression) { auto result_type = std::make_shared<union_type>(); - result_type->fields = build_composite_type(type_expression->fields); + result_type->fields = build_composite_type(expression->fields); this->current_type = type(result_type); } - void name_analysis_visitor::visit(procedure_type_expression *type_expression) + void name_analysis_visitor::visit(procedure_type_expression *expression) { std::shared_ptr<procedure_type> result_type = - std::make_shared<procedure_type>(std::move(build_procedure(*type_expression).first)); + std::make_shared<procedure_type>(std::move(build_procedure(*expression).first)); this->current_type = type(result_type); } - void name_analysis_visitor::visit(enumeration_type_expression *type_expression) + void name_analysis_visitor::visit(enumeration_type_expression *expression) { - std::shared_ptr<enumeration_type> result_type = std::make_shared<enumeration_type>(type_expression->members); + std::shared_ptr<enumeration_type> result_type = std::make_shared<enumeration_type>(expression->members); this->current_type = type(result_type); } @@ -561,6 +536,23 @@ namespace elna::boot { procedure->accept(this); } + if (unit->body.has_value()) + { + this->bag.enter(); + auto variable_type = this->bag.lookup("Int")->is_type()->symbol; + this->bag.enter("count", std::make_shared<variable_info>(variable_type, false)); + + variable_type = this->bag.lookup("Char")->is_type()->symbol; + variable_type = type(std::make_shared<pointer_type>(variable_type)); + variable_type = type(std::make_shared<pointer_type>(variable_type)); + this->bag.enter("parameters", std::make_shared<variable_info>(variable_type, false)); + + for (statement *const statement : unit->body.value()) + { + statement->accept(this); + } + this->bag.leave(); + } } void name_analysis_visitor::visit(traits_expression *trait) @@ -666,11 +658,6 @@ namespace elna::boot { } - void declaration_visitor::visit(program *program) - { - visit(static_cast<unit *>(program)); - } - void declaration_visitor::visit(import_declaration *) { } diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index eb30b4d..a3d022d 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -235,56 +235,6 @@ namespace elna::gcc } } - void generic_visitor::visit(boot::program *program) - { - visit(static_cast<boot::unit *>(program)); - - tree declaration_type = build_function_type_list(elna_int_type_node, - elna_int_type_node, - build_global_pointer_type(build_global_pointer_type(elna_char_type_node)), - NULL_TREE); - tree fndecl = build_fn_decl("main", declaration_type); - - tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, integer_type_node); - DECL_CONTEXT(resdecl) = fndecl; - DECL_RESULT(fndecl) = resdecl; - - push_struct_function(fndecl, false); - DECL_STRUCT_FUNCTION(fndecl)->language = ggc_cleared_alloc<language_function>(); - - enter_scope(); - - tree parameter_type = TYPE_ARG_TYPES(declaration_type); - for (const char *argument_name : std::array<const char *, 2>{ "count", "parameters" }) - { - tree declaration_tree = build_decl(UNKNOWN_LOCATION, PARM_DECL, - get_identifier(argument_name), TREE_VALUE(parameter_type)); - DECL_CONTEXT(declaration_tree) = fndecl; - DECL_ARG_TYPE(declaration_tree) = TREE_VALUE(parameter_type); - - this->symbols->enter(argument_name, declaration_tree); - DECL_ARGUMENTS(fndecl) = chainon(DECL_ARGUMENTS(fndecl), declaration_tree); - parameter_type = TREE_CHAIN(parameter_type); - } - visit_statements(program->body); - tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(fndecl), - build_int_cst_type(integer_type_node, 0)); - tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result); - append_statement(return_stmt); - tree mapping = leave_scope(); - - BLOCK_SUPERCONTEXT(BIND_EXPR_BLOCK(mapping)) = fndecl; - DECL_INITIAL(fndecl) = BIND_EXPR_BLOCK(mapping); - DECL_SAVED_TREE(fndecl) = mapping; - - DECL_EXTERNAL(fndecl) = 0; - DECL_PRESERVE_P(fndecl) = 1; - - pop_cfun(); - gimplify_function_tree(fndecl); - cgraph_node::finalize_function(fndecl, true); - } - void generic_visitor::visit(boot::unit *unit) { for (boot::import_declaration *const declaration : unit->imports) @@ -303,6 +253,53 @@ namespace elna::gcc { procedure->accept(this); } + if (unit->body.has_value()) + { + tree declaration_type = build_function_type_list(elna_int_type_node, + elna_int_type_node, + build_global_pointer_type(build_global_pointer_type(elna_char_type_node)), + NULL_TREE); + tree fndecl = build_fn_decl("main", declaration_type); + + tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, integer_type_node); + DECL_CONTEXT(resdecl) = fndecl; + DECL_RESULT(fndecl) = resdecl; + + push_struct_function(fndecl, false); + DECL_STRUCT_FUNCTION(fndecl)->language = ggc_cleared_alloc<language_function>(); + + enter_scope(); + + tree parameter_type = TYPE_ARG_TYPES(declaration_type); + for (const char *argument_name : std::array<const char *, 2>{ "count", "parameters" }) + { + tree declaration_tree = build_decl(UNKNOWN_LOCATION, PARM_DECL, + get_identifier(argument_name), TREE_VALUE(parameter_type)); + DECL_CONTEXT(declaration_tree) = fndecl; + DECL_ARG_TYPE(declaration_tree) = TREE_VALUE(parameter_type); + + this->symbols->enter(argument_name, declaration_tree); + DECL_ARGUMENTS(fndecl) = chainon(DECL_ARGUMENTS(fndecl), declaration_tree); + parameter_type = TREE_CHAIN(parameter_type); + } + visit_statements(unit->body.value()); + tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(fndecl), + build_int_cst_type(integer_type_node, 0)); + tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result); + append_statement(return_stmt); + tree mapping = leave_scope(); + + BLOCK_SUPERCONTEXT(BIND_EXPR_BLOCK(mapping)) = fndecl; + DECL_INITIAL(fndecl) = BIND_EXPR_BLOCK(mapping); + DECL_SAVED_TREE(fndecl) = mapping; + + DECL_EXTERNAL(fndecl) = 0; + DECL_PRESERVE_P(fndecl) = 1; + + pop_cfun(); + gimplify_function_tree(fndecl); + cgraph_node::finalize_function(fndecl, true); + } } void generic_visitor::visit(boot::procedure_declaration *definition) diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index 6942ca5..fe502a4 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -68,7 +68,6 @@ namespace elna::boot class case_statement; class traits_expression; class unit; - class program; class binary_expression; class unary_expression; class type_expression; @@ -110,7 +109,6 @@ namespace elna::boot virtual void visit(case_statement *) = 0; virtual void visit(empty_statement *) = 0; virtual void visit(unit *) = 0; - virtual void visit(program *) = 0; virtual void visit(binary_expression *) = 0; virtual void visit(unary_expression *) = 0; virtual void visit(type_expression *) = 0; @@ -144,7 +142,6 @@ namespace elna::boot [[noreturn]] virtual void visit(type_expression *) override; [[noreturn]] virtual void visit(array_type_expression *) override; [[noreturn]] virtual void visit(pointer_type_expression *) override; - [[noreturn]] virtual void visit(program *) override; [[noreturn]] virtual void visit(type_declaration *) override; [[noreturn]] virtual void visit(record_type_expression *) override; [[noreturn]] virtual void visit(union_type_expression *) override; @@ -290,7 +287,9 @@ namespace elna::boot const std::optional<std::string> base; record_type_expression(const struct position position, - std::vector<field_declaration>&& fields, std::optional<std::string> base); + std::vector<field_declaration>&& fields); + record_type_expression(const struct position position, + std::vector<field_declaration>&& fields, std::string&& base); void accept(parser_visitor *visitor) override; record_type_expression *is_record() override; @@ -315,7 +314,8 @@ namespace elna::boot public: const std::vector<std::string> members; - enumeration_type_expression(const struct position, std::vector<std::string>&& members); + enumeration_type_expression(const struct position, + std::vector<std::string>&& members); void accept(parser_visitor *visitor) override; enumeration_type_expression *is_enumeration() override; @@ -710,6 +710,8 @@ namespace elna::boot class unit : public node { public: + std::optional<std::vector<statement *>> body; + std::vector<import_declaration *> imports; std::vector<constant_declaration *> constants; std::vector<type_declaration *> types; @@ -717,22 +719,12 @@ namespace elna::boot std::vector<procedure_declaration *> procedures; unit(const struct position position); + unit(const struct position position, std::vector<statement *>&& body); virtual void accept(parser_visitor *visitor) override; virtual ~unit() override; }; - class program : public unit - { - public: - std::vector<statement *> body; - - program(const struct position position); - void accept(parser_visitor *visitor) override; - - virtual ~program() override; - }; - template<typename T> class literal : public literal_expression { diff --git a/include/elna/boot/semantic.h b/include/elna/boot/semantic.h index 6bc7fe0..c6ad19d 100644 --- a/include/elna/boot/semantic.h +++ b/include/elna/boot/semantic.h @@ -102,8 +102,6 @@ namespace elna::boot public: explicit type_analysis_visitor(symbol_bag bag); - void visit(program *program) override; - void visit(procedure_declaration *definition) override; void visit(assign_statement *) override; void visit(if_statement *) override; @@ -128,7 +126,7 @@ namespace elna::boot symbol_bag bag; std::pair<procedure_type, std::vector<std::string>> build_procedure( - procedure_type_expression& type_expression); + procedure_type_expression& expression); std::vector<type_field> build_composite_type(const std::vector<field_declaration>& fields); std::shared_ptr<variable_info> register_variable(const std::string& name, const bool is_extern, const struct position position); @@ -137,14 +135,13 @@ namespace elna::boot name_analysis_visitor(symbol_bag bag); void visit(type_expression *) override; - void visit(array_type_expression *type_expression) override; - void visit(pointer_type_expression *type_expression) override; - void visit(program *program) override; + void visit(array_type_expression *expression) override; + void visit(pointer_type_expression *expression) override; void visit(type_declaration *definition) override; - void visit(record_type_expression *type_expression) override; - void visit(union_type_expression *type_expression) override; - void visit(procedure_type_expression *type_expression) override; - void visit(enumeration_type_expression *type_expression) override; + void visit(record_type_expression *expression) override; + void visit(union_type_expression *expression) override; + void visit(procedure_type_expression *expression) override; + void visit(enumeration_type_expression *expression) override; void visit(variable_declaration *declaration) override; void visit(constant_declaration *definition) override; @@ -186,7 +183,6 @@ namespace elna::boot explicit declaration_visitor(); - void visit(program *program) override; void visit(import_declaration *) override; void visit(unit *unit) override; void visit(type_declaration *definition) override; diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index 77fd792..7ee251b 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -65,7 +65,6 @@ namespace elna::gcc public: generic_visitor(std::shared_ptr<symbol_table> symbol_table, elna::boot::symbol_bag bag); - void visit(boot::program *program) override; void visit(boot::procedure_declaration *definition) override; void visit(boot::procedure_call *call) override; void visit(boot::cast_expression *expression) override; |
