aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/ast.cc15
-rw-r--r--boot/parser.yy28
-rw-r--r--boot/semantic.cc8
3 files changed, 36 insertions, 15 deletions
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 <elna::boot::procedure_call*> call_expression;
%type <elna::boot::return_statement *> return_statement;
%type <elna::boot::statement *> statement;
-%type <std::vector<elna::boot::statement *>> required_statements optional_statements;
+%type <std::vector<elna::boot::statement *>> statements;
%type <std::unique_ptr<std::vector<elna::boot::statement *>>> statement_part;
%type <elna::boot::procedure_declaration *> procedure_declaration;
%type <std::pair<std::vector<std::string>, 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::vector<boot::statement *>>(std::move($2));; }
+ | "begin" statements { $$ = std::make_unique<std::vector<boot::statement *>>(std::move($2));; }
| return_statement
{
$$ = std::make_unique<std::vector<boot::statement *>>(std::vector<boot::statement *>{ $1 });
}
- | "begin" required_statements ";" return_statement
+ | "begin" statements ";" return_statement
{
$$ = std::make_unique<std::vector<boot::statement *>>(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<boot::statement *>(std::move($2)); }
+ "else" statements { $$ = new std::vector<boot::statement *>(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);