Implement enumeration type

This commit is contained in:
2025-04-04 22:48:12 +02:00
parent 50970f3289
commit 18c4e79012
14 changed files with 612 additions and 416 deletions

View File

@ -111,31 +111,37 @@ along with GCC; see the file COPYING3. If not see
BEGIN_BLOCK "begin"
END_BLOCK "end"
DEFER "defer"
%token OR "|" AND "&" XOR "xor"
CASE "case"
OF "of"
PIPE "|"
%token OR "or" AND "&" XOR "xor"
EQUALS "=" NOT_EQUAL "<>" LESS_THAN "<" GREATER_THAN ">" LESS_EQUAL "<=" GREATER_EQUAL ">="
SHIFT_LEFT "<<" SHIFT_RIGHT ">>"
PLUS "+" MINUS "-"
MULTIPLICATION "*" DIVISION "/" REMAINDER "%"
%left "|" "&" "xor"
%left "or" "&" "xor"
%left "=" "<>" "<" ">" "<=" ">="
%left "<<" ">>"
%left "+" "-"
%left "*" "/" "%"
%type <elna::boot::literal_expression *> literal;
%type <std::vector<elna::boot::literal_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;
%type <std::vector<elna::boot::constant_definition *>> constant_part constant_definitions;
%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part variable_declaration;
%type <elna::boot::type_expression *> type_expression;
%type <std::vector<elna::boot::type_expression *>> type_expressions;
%type <elna::boot::traits_expression *> traits_expression;
%type <elna::boot::expression *> expression operand qualident;
%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;
%type <elna::boot::designator_expression *> designator_expression;
%type <elna::boot::assign_statement *> assign_statement;
%type <elna::boot::procedure_call*> call_expression;
%type <elna::boot::while_statement *> while_statement;
%type <elna::boot::if_statement *> if_statement;
@ -154,9 +160,9 @@ along with GCC; see the file COPYING3. If not see
optional_fields required_fields formal_parameters;
%type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements;
%type <elna::boot::cast_expression *> cast_expression;
%type <elna::boot::defer_statement *> defer_statement;
%type <std::pair<std::string, bool>> identifier_definition;
%type <std::vector<std::pair<std::string, bool>>> identifier_definitions;
%type <std::vector<std::string>> identifiers;
%%
program:
constant_part type_part variable_part procedure_part "begin" statements "end" "."
@ -230,10 +236,6 @@ procedure_definitions:
procedure_part:
/* no procedure definitions */ {}
| procedure_definitions { std::swap($$, $1); }
assign_statement: designator_expression ":=" expression
{
$$ = new boot::assign_statement(boot::make_position(@1), $1, $3);
}
call_expression: designator_expression actual_parameter_list
{
$$ = new boot::procedure_call(boot::make_position(@1), $1);
@ -293,11 +295,6 @@ return_statement:
{
$$ = new boot::return_statement(boot::make_position(@1));
}
defer_statement: DEFER statements "end"
{
$$ = new boot::defer_statement(boot::make_position(@1));
std::swap($2, $$->statements);
}
literal:
INTEGER
{
@ -333,7 +330,7 @@ traits_expression:
$$ = new boot::traits_expression(boot::make_position(@1), $1);
std::swap($3, $$->parameters);
}
qualident:
simple_expression:
literal { $$ = $1; }
| designator_expression { $$ = $1; }
| traits_expression { $$ = $1; }
@ -342,7 +339,7 @@ qualident:
| "(" expression ")" { $$ = $2; }
operand:
unary_expression { $$ = $1; }
| qualident { $$ = $1; }
| simple_expression { $$ = $1; }
expression:
binary_expression { $$ = $1; }
| operand { $$ = $1; }
@ -396,7 +393,7 @@ binary_expression:
{
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::conjunction);
}
| expression "|" expression
| expression "or" expression
{
$$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::disjunction);
}
@ -441,15 +438,12 @@ type_expressions:
}
| type_expression { $$.push_back($1); }
designator_expression:
qualident "[" expression "]"
simple_expression "[" expression "]"
{
$$ = new boot::array_access_expression(boot::make_position(@2), $1, $3);
}
| qualident "." IDENTIFIER
{
$$ = new boot::field_access_expression(boot::make_position(@2), $1, $3);
}
| qualident "^"
| qualident { $$ = $1; }
| simple_expression "^"
{
$$ = new boot::dereference_expression(boot::make_position(@1), $1);
}
@ -457,13 +451,37 @@ designator_expression:
{
$$ = new boot::variable_expression(boot::make_position(@1), $1);
}
qualident: simple_expression "." IDENTIFIER
{
$$ = new boot::field_access_expression(boot::make_position(@2), $1, $3);
}
statement:
assign_statement { $$ = $1; }
designator_expression ":=" expression
{
$$ = new boot::assign_statement(boot::make_position(@1), $1, $3);
}
| while_statement { $$ = $1; }
| if_statement { $$ = $1; }
| return_statement { $$ = $1; }
| call_expression { $$ = $1; }
| defer_statement { $$ = $1; }
| 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:
switch_case "|" switch_cases
{
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
}
| switch_case { $$.push_back($1); }
case_labels:
literal "," case_labels
{
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
}
| literal { $$.push_back($1); }
statements:
statement ";" statements
{
@ -507,10 +525,21 @@ type_expression:
std::swap(result->parameters, $3);
$$ = result;
}
| "(" identifiers ")"
{
$$ = new boot::enumeration_type_expression(boot::make_position(@1), std::move($2));
}
| IDENTIFIER
{
$$ = new boot::primitive_type_expression(boot::make_position(@1), $1);
$$ = new boot::named_type_expression(boot::make_position(@1), $1);
}
identifiers:
IDENTIFIER "," identifiers
{
std::swap($$, $3);
$$.emplace($$.cbegin(), std::move($1));
}
| IDENTIFIER { $$.emplace_back(std::move($1)); }
variable_declaration: identifier_definitions ":" type_expression
{
std::shared_ptr<boot::type_expression> shared_type{ $3 };
@ -561,16 +590,14 @@ type_definitions:
type_part:
/* no type definitions */ {}
| "type" type_definitions { std::swap($$, $2); }
formal_parameter: IDENTIFIER ":" type_expression
{
$$ = std::make_pair($1, $3);
}
formal_parameter:
IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
formal_parameters:
/* no formal parameters */ {}
| formal_parameter "," formal_parameters
{
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
$$.emplace($$.cbegin(), std::move($1));
}
| formal_parameter { $$.emplace_back(std::move($1)); }
actual_parameter_list: