Implement case statements

This commit is contained in:
2025-04-10 23:55:56 +02:00
parent 18c4e79012
commit f68667d5e5
10 changed files with 135 additions and 94 deletions

View File

@ -127,7 +127,7 @@ along with GCC; see the file COPYING3. If not see
%left "*" "/" "%"
%type <elna::boot::literal_expression *> literal;
%type <std::vector<elna::boot::literal_expression *>> case_labels;
%type <std::vector<elna::boot::expression *>> case_labels;
%type <elna::boot::switch_case> switch_case;
%type <std::vector<elna::boot::switch_case>> switch_cases;
%type <elna::boot::constant_definition *> constant_definition;
@ -137,7 +137,6 @@ along with GCC; see the file COPYING3. If not see
%type <std::vector<elna::boot::type_expression *>> type_expressions;
%type <elna::boot::traits_expression *> traits_expression;
%type <elna::boot::expression *> expression operand simple_expression;
%type <elna::boot::field_access_expression *> qualident;
%type <elna::boot::unary_expression *> unary_expression;
%type <elna::boot::binary_expression *> binary_expression;
%type <std::vector<elna::boot::expression *>> expressions actual_parameter_list;
@ -296,34 +295,13 @@ return_statement:
$$ = new boot::return_statement(boot::make_position(@1));
}
literal:
INTEGER
{
$$ = new boot::literal<std::int32_t>(boot::make_position(@1), $1);
}
| WORD
{
$$ = new boot::literal<std::uint32_t>(boot::make_position(@1), $1);
}
| FLOAT
{
$$ = new boot::literal<double>(boot::make_position(@1), $1);
}
| BOOLEAN
{
$$ = new boot::literal<bool>(boot::make_position(@1), $1);
}
| CHARACTER
{
$$ = new boot::literal<unsigned char>(boot::make_position(@1), $1.at(0));
}
| "nil"
{
$$ = new boot::literal<std::nullptr_t>(boot::make_position(@1), nullptr);
}
| STRING
{
$$ = new boot::literal<std::string>(boot::make_position(@1), $1);
}
INTEGER { $$ = new boot::literal<std::int32_t>(boot::make_position(@1), $1); }
| WORD { $$ = new boot::literal<std::uint32_t>(boot::make_position(@1), $1); }
| FLOAT { $$ = new boot::literal<double>(boot::make_position(@1), $1); }
| BOOLEAN { $$ = new boot::literal<bool>(boot::make_position(@1), $1); }
| CHARACTER { $$ = new boot::literal<unsigned char>(boot::make_position(@1), $1.at(0)); }
| "nil" { $$ = new boot::literal<std::nullptr_t>(boot::make_position(@1), nullptr); }
| STRING { $$ = new boot::literal<std::string>(boot::make_position(@1), $1); }
traits_expression:
TRAIT "(" type_expressions ")"
{
@ -439,33 +417,22 @@ type_expressions:
| type_expression { $$.push_back($1); }
designator_expression:
simple_expression "[" expression "]"
{
$$ = new boot::array_access_expression(boot::make_position(@2), $1, $3);
}
| qualident { $$ = $1; }
{ $$ = new boot::array_access_expression(boot::make_position(@2), $1, $3); }
| simple_expression "." IDENTIFIER
{ $$ = new boot::field_access_expression(boot::make_position(@2), $1, $3); }
| simple_expression "^"
{
$$ = new boot::dereference_expression(boot::make_position(@1), $1);
}
{ $$ = new boot::dereference_expression(boot::make_position(@1), $1); }
| IDENTIFIER
{
$$ = new boot::variable_expression(boot::make_position(@1), $1);
}
qualident: simple_expression "." IDENTIFIER
{
$$ = new boot::field_access_expression(boot::make_position(@2), $1, $3);
}
{ $$ = new boot::variable_expression(boot::make_position(@1), $1); }
statement:
designator_expression ":=" expression
{
$$ = new boot::assign_statement(boot::make_position(@1), $1, $3);
}
{ $$ = new boot::assign_statement(boot::make_position(@1), $1, $3); }
| while_statement { $$ = $1; }
| if_statement { $$ = $1; }
| return_statement { $$ = $1; }
| call_expression { $$ = $1; }
| DEFER statements "end" { $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); }
| CASE expression "of" switch_cases "end"
| "defer" statements "end" { $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); }
| "case" expression "of" switch_cases "end"
{ $$ = new boot::case_statement(boot::make_position(@1), $2, std::move($4)); }
switch_case: case_labels ":" statements { $$ = { .labels = std::move($1), .statements = std::move($3) }; }
switch_cases:
@ -476,12 +443,12 @@ switch_cases:
}
| switch_case { $$.push_back($1); }
case_labels:
literal "," case_labels
expression "," case_labels
{
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
}
| literal { $$.push_back($1); }
| expression { $$.push_back($1); }
statements:
statement ";" statements
{
@ -562,7 +529,7 @@ variable_declarations:
variable_part:
/* no variable declarations */ {}
| "var" variable_declarations { std::swap($$, $2); }
constant_definition: identifier_definition "=" literal
constant_definition: identifier_definition "=" expression
{
$$ = new boot::constant_definition(boot::make_position(@1), $1.first, $1.second, $3);
}