Allow only one return
This commit is contained in:
@ -106,7 +106,6 @@ along with GCC; see the file COPYING3. If not see
|
||||
RETURN "return"
|
||||
BEGIN_BLOCK "begin"
|
||||
END_BLOCK "end"
|
||||
DEFER "defer"
|
||||
%token OR "or" AND "and" XOR "xor"
|
||||
EQUALS "=" NOT_EQUAL "<>" LESS_THAN "<" GREATER_THAN ">" LESS_EQUAL "<=" GREATER_EQUAL ">="
|
||||
SHIFT_LEFT "<<" SHIFT_RIGHT ">>"
|
||||
@ -134,12 +133,12 @@ along with GCC; see the file COPYING3. If not see
|
||||
%type <elna::boot::procedure_call*> call_expression;
|
||||
%type <elna::boot::while_statement *> while_statement;
|
||||
%type <elna::boot::if_statement *> if_statement;
|
||||
%type <elna::boot::return_statement *> return_statement;
|
||||
%type <elna::boot::expression *> return_statement;
|
||||
%type <elna::boot::statement *> statement;
|
||||
%type <std::vector<elna::boot::statement *>> statements optional_statements;
|
||||
%type <std::vector<elna::boot::statement *>> statements statement_part;
|
||||
%type <elna::boot::procedure_definition *> procedure_definition;
|
||||
%type <std::shared_ptr<elna::boot::procedure_type>> procedure_heading;
|
||||
%type <std::vector<elna::boot::procedure_definition *>> procedure_definitions procedure_part;
|
||||
%type <std::vector<elna::boot::procedure_definition *>> procedure_definitions;
|
||||
%type <elna::boot::type_definition *> type_definition;
|
||||
%type <std::vector<elna::boot::type_definition *>> type_definitions type_part;
|
||||
%type <elna::boot::block *> block;
|
||||
@ -147,12 +146,11 @@ along with GCC; see the file COPYING3. If not see
|
||||
%type <std::vector<std::pair<std::string, std::shared_ptr<elna::boot::top_type>>>> optional_fields fields;
|
||||
%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;
|
||||
%%
|
||||
program:
|
||||
constant_part type_part variable_part procedure_part "begin" optional_statements "end" "."
|
||||
constant_part type_part variable_part procedure_definitions "begin" statements "end" "."
|
||||
{
|
||||
auto tree = new elna::boot::program(elna::boot::make_position(@5));
|
||||
|
||||
@ -164,13 +162,13 @@ program:
|
||||
|
||||
driver.tree.reset(tree);
|
||||
}
|
||||
block: constant_part variable_part "begin" optional_statements "end"
|
||||
block: constant_part variable_part statement_part
|
||||
{
|
||||
$$ = new elna::boot::block(elna::boot::make_position(@3));
|
||||
$$ = new elna::boot::block(elna::boot::make_position(@1));
|
||||
|
||||
std::swap($$->constants, $1);
|
||||
std::swap($$->variables, $2);
|
||||
std::swap($$->body, $4);
|
||||
std::swap($$->body, $3);
|
||||
}
|
||||
identifier_definition:
|
||||
IDENTIFIER "*"
|
||||
@ -205,9 +203,10 @@ procedure_heading:
|
||||
std::swap($1, $$->parameters);
|
||||
}
|
||||
procedure_definition:
|
||||
"proc" identifier_definition procedure_heading ";" block
|
||||
"proc" identifier_definition procedure_heading ";" block return_statement "end"
|
||||
{
|
||||
$$ = 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, $5, $6);
|
||||
}
|
||||
| "proc" identifier_definition procedure_heading ";" "extern"
|
||||
{
|
||||
@ -219,10 +218,7 @@ procedure_definitions:
|
||||
std::swap($$, $2);
|
||||
$$.emplace($$.cbegin(), std::move($1));
|
||||
}
|
||||
| procedure_definition { $$.emplace_back(std::move($1)); }
|
||||
procedure_part:
|
||||
/* no procedure definitions */ {}
|
||||
| procedure_definitions { std::swap($$, $1); }
|
||||
| /* no procedure definitions */ {}
|
||||
assign_statement: designator_expression ":=" expression
|
||||
{
|
||||
$$ = new elna::boot::assign_statement(elna::boot::make_position(@1), $1, $3);
|
||||
@ -237,7 +233,7 @@ cast_expression: "cast" "(" expression ":" type_expression ")"
|
||||
$$ = new elna::boot::cast_expression(elna::boot::make_position(@1), $5, $3);
|
||||
}
|
||||
elsif_do_statements:
|
||||
"elsif" expression "do" optional_statements elsif_do_statements
|
||||
"elsif" expression "do" statements elsif_do_statements
|
||||
{
|
||||
elna::boot::conditional_statements *branch = new elna::boot::conditional_statements($2);
|
||||
std::swap(branch->statements, $4);
|
||||
@ -245,7 +241,7 @@ elsif_do_statements:
|
||||
$$.emplace($$.begin(), branch);
|
||||
}
|
||||
| {}
|
||||
while_statement: "while" expression "do" optional_statements elsif_do_statements "end"
|
||||
while_statement: "while" expression "do" statements elsif_do_statements "end"
|
||||
{
|
||||
auto body = new elna::boot::conditional_statements($2);
|
||||
std::swap($4, body->statements);
|
||||
@ -253,7 +249,7 @@ while_statement: "while" expression "do" optional_statements elsif_do_statements
|
||||
std::swap($5, $$->branches);
|
||||
}
|
||||
elsif_then_statements:
|
||||
"elsif" expression "then" optional_statements elsif_then_statements
|
||||
"elsif" expression "then" statements elsif_then_statements
|
||||
{
|
||||
elna::boot::conditional_statements *branch = new elna::boot::conditional_statements($2);
|
||||
std::swap(branch->statements, $4);
|
||||
@ -262,14 +258,14 @@ elsif_then_statements:
|
||||
}
|
||||
| {}
|
||||
if_statement:
|
||||
"if" expression "then" optional_statements elsif_then_statements "end"
|
||||
"if" expression "then" statements elsif_then_statements "end"
|
||||
{
|
||||
auto then = new elna::boot::conditional_statements($2);
|
||||
std::swap($4, then->statements);
|
||||
$$ = new elna::boot::if_statement(elna::boot::make_position(@1), then);
|
||||
std::swap($5, $$->branches);
|
||||
}
|
||||
| "if" expression "then" optional_statements elsif_then_statements "else" optional_statements "end"
|
||||
| "if" expression "then" statements elsif_then_statements "else" statements "end"
|
||||
{
|
||||
auto then = new elna::boot::conditional_statements($2);
|
||||
std::swap($4, then->statements);
|
||||
@ -277,15 +273,12 @@ if_statement:
|
||||
$$ = new elna::boot::if_statement(elna::boot::make_position(@1), then, _else);
|
||||
std::swap($5, $$->branches);
|
||||
}
|
||||
return_statement: "return" expression
|
||||
return_statement:
|
||||
"return" expression
|
||||
{
|
||||
$$ = new elna::boot::return_statement(elna::boot::make_position(@1), $2);
|
||||
}
|
||||
defer_statement: DEFER optional_statements "end"
|
||||
{
|
||||
$$ = new elna::boot::defer_statement(elna::boot::make_position(@1));
|
||||
std::swap($2, $$->statements);
|
||||
$$ = $2;
|
||||
}
|
||||
| /* no return statement */ { $$ = nullptr; }
|
||||
literal:
|
||||
INTEGER
|
||||
{
|
||||
@ -454,19 +447,17 @@ statement:
|
||||
assign_statement { $$ = $1; }
|
||||
| while_statement { $$ = $1; }
|
||||
| if_statement { $$ = $1; }
|
||||
| return_statement { $$ = $1; }
|
||||
| call_expression { $$ = $1; }
|
||||
| defer_statement { $$ = $1; }
|
||||
statements:
|
||||
statement statements
|
||||
{
|
||||
std::swap($$, $2);
|
||||
$$.emplace($$.cbegin(), $1);
|
||||
}
|
||||
| statement { $$.push_back($1); }
|
||||
optional_statements:
|
||||
statements { std::swap($$, $1); }
|
||||
| /* no statements */ {}
|
||||
statement_part:
|
||||
"begin" statements { std::swap($$, $2); }
|
||||
| {}
|
||||
field_declaration:
|
||||
IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
|
||||
fields:
|
||||
|
Reference in New Issue
Block a user