Skip parameter names in procedure type expressions

This commit is contained in:
2025-03-18 11:37:10 +01:00
parent 6eb4e91b2c
commit 5e8555b4f4
20 changed files with 469 additions and 490 deletions

View File

@ -87,7 +87,7 @@ along with GCC; see the file COPYING3. If not see
ARROW "->" EXCLAMATION "!"
AT "@" HAT "^"
COLON ":" SEMICOLON ";" DOT "." COMMA ","
%token NOT "not"
%token NOT "~"
CAST "cast"
NIL "nil"
CONST "const"
@ -107,27 +107,26 @@ along with GCC; see the file COPYING3. If not see
BEGIN_BLOCK "begin"
END_BLOCK "end"
DEFER "defer"
%token OR "or" AND "and" XOR "xor"
%token 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 "or" "and" "xor"
%left "|" "&" "xor"
%left "=" "<>" "<" ">" "<=" ">="
%left "<<" ">>"
%left "+" "-"
%left "*" "/" "%"
%type <elna::boot::literal *> literal;
%type <elna::boot::literal_expression *> literal;
%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
formal_parameters formal_parameter_list;
%type <elna::boot::variable_declaration *> formal_parameter
%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part variable_declaration;
%type <std::shared_ptr<elna::boot::type_expression>> type_expression;
%type <std::vector<std::shared_ptr<elna::boot::type_expression>>> type_expressions;
%type <elna::boot::traits_expression *> traits_expression;
%type <elna::boot::expression *> expression operand;
%type <elna::boot::expression *> expression operand 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;
@ -140,14 +139,15 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::statement *> statement;
%type <std::vector<elna::boot::statement *>> statements;
%type <elna::boot::procedure_definition *> procedure_definition;
%type <std::shared_ptr<elna::boot::procedure_type_expression>> procedure_heading;
%type <std::pair<std::vector<std::string>, std::shared_ptr<elna::boot::procedure_type_expression>>> procedure_heading;
%type <elna::boot::return_declaration> return_declaration;
%type <std::vector<elna::boot::procedure_definition *>> procedure_definitions procedure_part;
%type <elna::boot::type_definition *> type_definition;
%type <std::vector<elna::boot::type_definition *>> type_definitions type_part;
%type <elna::boot::block *> block;
%type <elna::boot::field_declaration> field_declaration;
%type <elna::boot::field_declaration> field_declaration formal_parameter;
%type <std::vector<std::pair<std::string, std::shared_ptr<elna::boot::type_expression>>>>
optional_fields required_fields;
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;
@ -191,31 +191,32 @@ identifier_definitions:
$$.emplace($$.cbegin(), $1);
}
| identifier_definition { $$.emplace_back(std::move($1)); }
return_declaration:
/* proper procedure */ {}
| "->" "!" { $$ = elna::boot::return_declaration(std::monostate{}); }
| "->" type_expression { $$ = elna::boot::return_declaration($2); }
procedure_heading:
formal_parameter_list
"(" formal_parameters ")" return_declaration
{
$$ = std::make_shared<elna::boot::procedure_type_expression>(elna::boot::make_position(@1));
std::swap($1, $$->parameters);
}
| formal_parameter_list "->" "!"
{
$$ = std::make_shared<elna::boot::procedure_type_expression>(elna::boot::make_position(@1),
elna::boot::no_return);
std::swap($1, $$->parameters);
}
| formal_parameter_list "->" type_expression
{
$$ = std::make_shared<elna::boot::procedure_type_expression>(elna::boot::make_position(@1), $3);
std::swap($1, $$->parameters);
$$.second = std::make_shared<elna::boot::procedure_type_expression>(elna::boot::make_position(@1),
std::move($4));
for (auto& [name, type] : $2)
{
$$.first.emplace_back(std::move(name));
$$.second->parameters.push_back(type);
}
}
procedure_definition:
"proc" identifier_definition procedure_heading ";" block
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1), $2.first, $2.second, $3, $5);
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1),
$2.first, $2.second, $3.second, $5);
std::swap($3.first, $$->parameter_names);
}
| "proc" identifier_definition procedure_heading ";" "extern"
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1), $2.first, $2.second, $3);
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1), $2.first, $2.second, $3.second);
std::swap($3.first, $$->parameter_names);
}
procedure_definitions:
procedure_definition procedure_definitions
@ -293,47 +294,50 @@ defer_statement: DEFER statements "end"
literal:
INTEGER
{
$$ = new elna::boot::number_literal<std::int32_t>(elna::boot::make_position(@1), $1);
$$ = new elna::boot::literal<std::int32_t>(elna::boot::make_position(@1), $1);
}
| WORD
{
$$ = new elna::boot::number_literal<std::uint32_t>(elna::boot::make_position(@1), $1);
$$ = new elna::boot::literal<std::uint32_t>(elna::boot::make_position(@1), $1);
}
| FLOAT
{
$$ = new elna::boot::number_literal<double>(elna::boot::make_position(@1), $1);
$$ = new elna::boot::literal<double>(elna::boot::make_position(@1), $1);
}
| BOOLEAN
{
$$ = new elna::boot::number_literal<bool>(elna::boot::make_position(@1), $1);
$$ = new elna::boot::literal<bool>(elna::boot::make_position(@1), $1);
}
| CHARACTER
{
$$ = new elna::boot::number_literal<unsigned char>(elna::boot::make_position(@1), $1.at(0));
$$ = new elna::boot::literal<unsigned char>(elna::boot::make_position(@1), $1.at(0));
}
| "nil"
{
$$ = new elna::boot::number_literal<std::nullptr_t>(elna::boot::make_position(@1), nullptr);
$$ = new elna::boot::literal<std::nullptr_t>(elna::boot::make_position(@1), nullptr);
}
| STRING
{
$$ = new elna::boot::number_literal<std::string>(elna::boot::make_position(@1), $1);
$$ = new elna::boot::literal<std::string>(elna::boot::make_position(@1), $1);
}
traits_expression:
TRAIT "(" type_expression ")"
TRAIT "(" type_expressions ")"
{
$$ = new elna::boot::traits_expression(elna::boot::make_position(@1), $1, $3);
$$ = new elna::boot::traits_expression(elna::boot::make_position(@1), $1);
std::swap($3, $$->parameters);
}
operand:
qualident:
literal { $$ = $1; }
| designator_expression { $$ = $1; }
| traits_expression { $$ = $1; }
| cast_expression { $$ = $1; }
| call_expression { $$ = $1; }
| "(" expression ")" { $$ = $2; }
expression:
operand:
unary_expression { $$ = $1; }
| binary_expression { $$ = $1; }
| qualident { $$ = $1; }
expression:
binary_expression { $$ = $1; }
| operand { $$ = $1; }
binary_expression:
expression "*" expression
@ -391,12 +395,12 @@ binary_expression:
$$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3,
elna::boot::binary_operator::greater_equal);
}
| expression "and" expression
| expression "&" expression
{
$$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3,
elna::boot::binary_operator::conjunction);
}
| expression "or" expression
| expression "|" expression
{
$$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3,
elna::boot::binary_operator::disjunction);
@ -422,7 +426,7 @@ unary_expression:
$$ = new elna::boot::unary_expression(elna::boot::make_position(@1), $2,
elna::boot::unary_operator::reference);
}
| "not" operand
| "~" operand
{
$$ = new elna::boot::unary_expression(elna::boot::make_position(@1), $2,
elna::boot::unary_operator::negation);
@ -438,17 +442,24 @@ expressions:
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
}
| expression { $$.emplace_back(std::move($1)); }
| expression { $$.push_back($1); }
type_expressions:
type_expression "," type_expressions
{
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
}
| type_expression { $$.push_back($1); }
designator_expression:
operand "[" expression "]"
qualident "[" expression "]"
{
$$ = new elna::boot::array_access_expression(elna::boot::make_position(@2), $1, $3);
}
| operand "." IDENTIFIER
| qualident "." IDENTIFIER
{
$$ = new elna::boot::field_access_expression(elna::boot::make_position(@2), $1, $3);
}
| operand "^"
| qualident "^"
{
$$ = new elna::boot::dereference_expression(elna::boot::make_position(@1), $1);
}
@ -500,9 +511,12 @@ type_expression:
{
$$ = std::make_shared<elna::boot::union_type_expression>(elna::boot::make_position(@1), std::move($2));
}
| "proc" procedure_heading
| "proc" "(" type_expressions ")" return_declaration
{
$$ = $2;
auto result = std::make_shared<elna::boot::procedure_type_expression>(elna::boot::make_position(@1),
std::move($5));
std::swap(result->parameters, $3);
$$ = result;
}
| IDENTIFIER
{
@ -559,18 +573,16 @@ type_part:
| "type" type_definitions { std::swap($$, $2); }
formal_parameter: IDENTIFIER ":" type_expression
{
$$ = new elna::boot::variable_declaration(elna::boot::make_position(@2), $1, $3);
$$ = std::make_pair($1, $3);
}
formal_parameters:
formal_parameter "," formal_parameters
/* no formal parameters */ {}
| formal_parameter "," formal_parameters
{
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
}
| formal_parameter { $$.emplace_back(std::move($1)); }
formal_parameter_list:
"(" ")" {}
| "(" formal_parameters ")" { std::swap($$, $2); }
actual_parameter_list:
"(" ")" {}
| "(" expressions ")" { std::swap($$, $2); }