aboutsummaryrefslogtreecommitdiff
path: root/boot/parser.yy
diff options
context:
space:
mode:
Diffstat (limited to 'boot/parser.yy')
-rw-r--r--boot/parser.yy81
1 files changed, 44 insertions, 37 deletions
diff --git a/boot/parser.yy b/boot/parser.yy
index 01dfa80..1e732c6 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -95,12 +95,11 @@ along with GCC; see the file COPYING3. If not see
EXCLAMATION "!" ARROW "->"
AT "@" HAT "^"
COLON ":" SEMICOLON ";" DOT "." COMMA ","
-%token PROGRAM "program"
+%token PROGRAM "program" MODULE "module"
CAST "cast"
NIL "nil"
CONST "const"
- VAR "var"
- THREADVAR "threadvar"
+ VAR "var" THREADVAR "threadvar"
PROCEDURE "proc"
TYPE "type"
RECORD "record"
@@ -135,7 +134,7 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::switch_case> switch_case;
%type <std::vector<elna::boot::switch_case>> switch_cases;
%type <elna::boot::variable_declaration *> variable_declaration;
-%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part;
+%type <std::vector<elna::boot::variable_declaration *>> variable_declarations;
%type <elna::boot::type_expression *> type_expression;
%type <std::vector<elna::boot::type_expression *>> type_expressions;
%type <elna::boot::expression *> expression operand simple_expression procedure_return unary_expression;
@@ -144,14 +143,15 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::designator_expression *> designator_expression;
%type <std::unique_ptr<elna::boot::procedure_call>> call_expression;
%type <elna::boot::statement *> statement;
-%type <std::vector<elna::boot::statement *>> statements statement_part;
+%type <std::vector<elna::boot::statement *>> statements statement_part optional_begin_statements;
%type <elna::boot::block> block;
%type <elna::boot::procedure_declaration *> procedure_declaration;
%type <std::unique_ptr<elna::boot::procedure_type_expression>> procedure_heading;
%type <elna::boot::procedure_type_expression::return_t> return_declaration;
%type <std::unique_ptr<elna::boot::type_declaration>> type_declaration;
-%type <std::vector<elna::boot::declaration *>> type_declarations;
-%type <std::vector<elna::boot::declaration *>> module_declaration module_declarations;
+%type <std::vector<elna::boot::declaration *>> type_declarations sections section;
+%type <std::pair<std::vector<elna::boot::import_declaration *>, std::vector<elna::boot::declaration *>>>
+ required_declarations optional_declarations;
%type <std::unique_ptr<elna::boot::procedure_body>> procedure_body;
%type <elna::boot::field_declaration> field_declaration;
%type <std::vector<elna::boot::field_declaration>> field_declarations;
@@ -167,31 +167,38 @@ along with GCC; see the file COPYING3. If not see
%type <std::vector<std::string>> import_declaration;
%type <std::vector<elna::boot::identifier>> required_identifiers optional_identifiers generic_parameters;
%type <elna::boot::named_expression *> name_reference;
-%type <std::vector<elna::boot::import_declaration *>> import_declarations import_part;
+%type <std::vector<elna::boot::import_declaration *>> import_declarations;
%type <std::unique_ptr<elna::boot::array_type_expression>> array_type_expression;
+%type <std::unique_ptr<elna::boot::unit>> unit;
%%
-program:
- import_part module_declarations "end" "."
+program: unit
{
- driver.finished = true;
+ driver.tree = $1;
+ }
+unit:
+ "module" optional_declarations "end" "."
+ {
+ auto [modules, sections] = $2;
- boot::unit *tree = new boot::unit(boot::make_position(@$), $1, $2);
- driver.tree.reset(tree);
+ $$ = std::make_unique<boot::unit>(boot::make_position(@$), std::move(modules), std::move(sections));
}
- | import_part module_declarations
- "program" "(" optional_identifiers ")" procedure_body "end" "."
+ | "program" "(" optional_identifiers ")" required_declarations statement_part "end" "."
{
- driver.finished = true;
+ auto [modules, sections] = $5;
- boot::unit *tree = new boot::unit(boot::make_position(@$), $1, $2,
- std::move($5), boot::make_position(@3), std::move(*$7));
- driver.tree.reset(tree);
+ $$ = std::make_unique<boot::unit>(boot::make_position(@$), std::move(modules),
+ std::move(sections), $3, boot::make_position(@1), $6);
}
-module_declaration:
+ | "program" "(" optional_identifiers ")" optional_begin_statements "end" "."
+ {
+ $$ = std::make_unique<boot::unit>(boot::make_position(@$), std::vector<boot::import_declaration *>{},
+ std::vector<boot::declaration *>{}, $3, boot::make_position(@1), $5);
+ }
+section:
"type" type_declarations { $$ = $2; }
- | variable_part
+ | "var" variable_declarations
{
- std::vector<boot::variable_declaration *> variables = $1;
+ std::vector<boot::variable_declaration *> variables = $2;
$$.insert($$.end(), variables.begin(), variables.end());
}
@@ -206,33 +213,36 @@ module_declaration:
$$.insert($$.end(), variables.begin(), variables.end());
}
| procedure_declaration { $$.emplace_back($1); }
-module_declarations:
+required_declarations:
+ sections { $$ = { {}, $1 }; }
+ | "import" import_declarations { $$ = { $2, {} }; }
+ | "import" import_declarations sections { $$ = { $2, $3 }; }
+optional_declarations:
%empty {}
- | module_declaration module_declarations
+ | required_declarations { $$ = $1; }
+sections:
+ section sections
{
std::vector<boot::declaration *> appendix = $2;
$$ = $1;
$$.insert($$.end(), appendix.begin(), appendix.end());
}
+ | section { $$ = $1; }
procedure_body:
block procedure_return
{ $$ = std::make_unique<boot::procedure_body>(std::move($1), $2); }
-
-variable_part:
- "var" variable_declarations { $$ = $2; }
-
block:
- variable_part statement_part
- { $$ = boot::block(std::move($1), std::move($2)); }
- | "begin" statements
- { $$ = boot::block(std::vector<boot::variable_declaration *>(), std::move($2)); }
- | statements
+ "var" variable_declarations statement_part
+ { $$ = boot::block(std::move($2), std::move($3)); }
+ | optional_begin_statements
{ $$ = boot::block(std::vector<boot::variable_declaration *>(), std::move($1)); }
-
statement_part:
%empty {}
| "begin" statements { $$ = $2; }
+optional_begin_statements:
+ "begin" statements { $$ = $2; }
+ | statements { $$ = $1; }
identifier:
IDENTIFIER { $$ = std::make_unique<boot::identifier>($1, boot::make_position(@1)); }
identifier_definition:
@@ -739,9 +749,6 @@ import_declarations:
{
$$.emplace_back(new boot::import_declaration(boot::make_position(@$), $1));
}
-import_part:
- %empty {}
- | "import" import_declarations { $$ = $2; }
type_declaration: identifier_definition generic_parameters "=" type_expression
{
$$ = std::make_unique<boot::type_declaration>(boot::make_position(@$), std::move(*$1), $4);