From 265e6d6a27eebbcafbd73f0da76e516a139f21d1 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 4 Jul 2026 22:29:49 +0200 Subject: Allow empty statements --- boot/ast.cc | 15 +++++++++++++++ boot/parser.yy | 28 +++++++++++++--------------- boot/semantic.cc | 8 ++++++++ 3 files changed, 36 insertions(+), 15 deletions(-) (limited to 'boot') diff --git a/boot/ast.cc b/boot/ast.cc index e4c46a4..91b46a4 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -114,6 +114,11 @@ namespace elna::boot not_implemented(); } + void empty_visitor::visit(empty_statement *) + { + not_implemented(); + } + void empty_visitor::visit(case_statement *) { not_implemented(); @@ -702,6 +707,16 @@ namespace elna::boot } } + void empty_statement::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + empty_statement::empty_statement(const struct position position) + : node(position) + { + } + designator_expression::~designator_expression() { } diff --git a/boot/parser.yy b/boot/parser.yy index 1a5364b..4d4f038 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -140,7 +140,7 @@ along with GCC; see the file COPYING3. If not see %type call_expression; %type return_statement; %type statement; -%type > required_statements optional_statements; +%type > statements; %type >> statement_part; %type procedure_declaration; %type , elna::boot::procedure_type_expression *>> procedure_heading; @@ -193,12 +193,12 @@ block: constant_part variable_part statement_part "end" } statement_part: /* no statements */ {} - | "begin" required_statements { $$ = std::make_unique>(std::move($2));; } + | "begin" statements { $$ = std::make_unique>(std::move($2));; } | return_statement { $$ = std::make_unique>(std::vector{ $1 }); } - | "begin" required_statements ";" return_statement + | "begin" statements ";" return_statement { $$ = std::make_unique>(std::move($2)); $$->push_back($4); @@ -253,7 +253,7 @@ call_expression: designator_expression actual_parameter_list cast_expression: "cast" "(" expression ":" type_expression ")" { $$ = new boot::cast_expression(boot::make_position(@1), $5, $3); } elsif_do_statements: - "elsif" expression "do" optional_statements elsif_do_statements + "elsif" expression "do" statements elsif_do_statements { boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4)); std::swap($5, $$); @@ -261,10 +261,10 @@ elsif_do_statements: } | {} else_statements: - "else" optional_statements { $$ = new std::vector(std::move($2)); } + "else" statements { $$ = new std::vector(std::move($2)); } | { $$ = nullptr; } elsif_then_statements: - "elsif" expression "then" optional_statements elsif_then_statements + "elsif" expression "then" statements elsif_then_statements { boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4)); std::swap($5, $$); @@ -406,22 +406,23 @@ designator_expression: statement: designator_expression ":=" expression { $$ = new boot::assign_statement(boot::make_position(@1), $1, $3); } - | "while" expression "do" optional_statements elsif_do_statements "end" + | "while" expression "do" statements elsif_do_statements "end" { boot::conditional_statements *body = new boot::conditional_statements($2, std::move($4)); $$ = new boot::while_statement(boot::make_position(@1), body, std::move($5)); } - | "if" expression "then" optional_statements elsif_then_statements else_statements "end" + | "if" expression "then" statements elsif_then_statements else_statements "end" { boot::conditional_statements *then = new boot::conditional_statements($2, std::move($4)); $$ = new boot::if_statement(boot::make_position(@1), then, std::move($5), $6); } | call_expression { $$ = $1; } - | "defer" optional_statements "end" + | "defer" statements "end" { $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); } | "case" expression "of" switch_cases else_statements "end" { $$ = new boot::case_statement(boot::make_position(@1), $2, std::move($4), $5); } -switch_case: case_labels ":" optional_statements + | { $$ = new boot::empty_statement(boot::make_position(@$)); } +switch_case: case_labels ":" statements { $$ = { .labels = std::move($1), .statements = std::move($3) }; } switch_cases: switch_case "|" switch_cases @@ -437,16 +438,13 @@ case_labels: $$.emplace($$.cbegin(), $1); } | expression { $$.push_back($1); } -required_statements: - required_statements ";" statement +statements: + statements ";" statement { std::swap($$, $1); $$.insert($$.cend(), $3); } | statement { $$.push_back($1); } -optional_statements: - required_statements { std::swap($$, $1); } - | /* no statements */ {} field_declaration: IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); } required_fields: diff --git a/boot/semantic.cc b/boot/semantic.cc index 3ccc81b..300c91d 100644 --- a/boot/semantic.cc +++ b/boot/semantic.cc @@ -139,6 +139,10 @@ namespace elna::boot { } + void type_analysis_visitor::visit(empty_statement *) + { + } + void type_analysis_visitor::visit(case_statement *) { } @@ -463,6 +467,10 @@ namespace elna::boot } } + void name_analysis_visitor::visit(empty_statement *) + { + } + void name_analysis_visitor::visit(case_statement *statement) { statement->condition().accept(this); -- cgit v1.2.3