62
boot/ast.cc
62
boot/ast.cc
@ -86,6 +86,24 @@ namespace boot
|
||||
}
|
||||
}
|
||||
|
||||
void empty_visitor::visit(return_statement *statement)
|
||||
{
|
||||
expression *return_expression = statement->return_expression();
|
||||
|
||||
if (return_expression != nullptr)
|
||||
{
|
||||
return_expression->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void empty_visitor::visit(defer_statement *defer)
|
||||
{
|
||||
for (statement *const body_statement : defer->statements)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void empty_visitor::visit(block *block)
|
||||
{
|
||||
for (constant_definition *const constant : block->constants)
|
||||
@ -370,9 +388,8 @@ namespace boot
|
||||
}
|
||||
|
||||
procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
|
||||
const bool exported, std::shared_ptr<procedure_type> heading,
|
||||
block *const body, expression *const returning)
|
||||
: definition(position, identifier, exported), m_heading(heading), body(body), returning(returning)
|
||||
const bool exported, std::shared_ptr<procedure_type> heading, block *body)
|
||||
: definition(position, identifier, exported), m_heading(heading), body(body)
|
||||
{
|
||||
}
|
||||
|
||||
@ -389,7 +406,6 @@ namespace boot
|
||||
procedure_definition::~procedure_definition()
|
||||
{
|
||||
delete body;
|
||||
delete returning;
|
||||
}
|
||||
|
||||
type_definition::type_definition(const struct position position, const std::string& identifier,
|
||||
@ -460,6 +476,24 @@ namespace boot
|
||||
{
|
||||
}
|
||||
|
||||
defer_statement::defer_statement(const struct position position)
|
||||
: node(position)
|
||||
{
|
||||
}
|
||||
|
||||
void defer_statement::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
defer_statement::~defer_statement()
|
||||
{
|
||||
for (statement *body_statement : statements)
|
||||
{
|
||||
delete body_statement;
|
||||
}
|
||||
}
|
||||
|
||||
designator_expression::designator_expression()
|
||||
{
|
||||
}
|
||||
@ -711,6 +745,26 @@ namespace boot
|
||||
}
|
||||
}
|
||||
|
||||
return_statement::return_statement(const struct position position, expression *return_expression)
|
||||
: node(position), m_return_expression(return_expression)
|
||||
{
|
||||
}
|
||||
|
||||
void return_statement::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
expression *return_statement::return_expression()
|
||||
{
|
||||
return m_return_expression;
|
||||
}
|
||||
|
||||
return_statement::~return_statement()
|
||||
{
|
||||
delete m_return_expression;
|
||||
}
|
||||
|
||||
void assign_statement::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
|
@ -125,6 +125,9 @@ return {
|
||||
cast {
|
||||
return yy::parser::make_CAST(this->location);
|
||||
}
|
||||
defer {
|
||||
return yy::parser::make_DEFER(this->location);
|
||||
}
|
||||
[A-Za-z_][A-Za-z0-9_]* {
|
||||
return yy::parser::make_IDENTIFIER(yytext, this->location);
|
||||
}
|
||||
|
@ -106,6 +106,7 @@ 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 ">>"
|
||||
@ -135,12 +136,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::expression *> return_statement;
|
||||
%type <elna::boot::return_statement *> return_statement;
|
||||
%type <elna::boot::statement *> statement;
|
||||
%type <std::vector<elna::boot::statement *>> statements statement_part;
|
||||
%type <std::vector<elna::boot::statement *>> statements;
|
||||
%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;
|
||||
%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;
|
||||
@ -148,11 +149,12 @@ 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 required_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_definitions "begin" statements "end" "."
|
||||
constant_part type_part variable_part procedure_part "begin" statements "end" "."
|
||||
{
|
||||
auto tree = new elna::boot::program(elna::boot::make_position(@5));
|
||||
|
||||
@ -164,13 +166,13 @@ program:
|
||||
|
||||
driver.tree.reset(tree);
|
||||
}
|
||||
block: constant_part variable_part statement_part
|
||||
block: constant_part variable_part "begin" statements "end"
|
||||
{
|
||||
$$ = new elna::boot::block(elna::boot::make_position(@1));
|
||||
$$ = new elna::boot::block(elna::boot::make_position(@3));
|
||||
|
||||
std::swap($$->constants, $1);
|
||||
std::swap($$->variables, $2);
|
||||
std::swap($$->body, $3);
|
||||
std::swap($$->body, $4);
|
||||
}
|
||||
identifier_definition:
|
||||
IDENTIFIER "*"
|
||||
@ -205,10 +207,9 @@ procedure_heading:
|
||||
std::swap($1, $$->parameters);
|
||||
}
|
||||
procedure_definition:
|
||||
"proc" identifier_definition procedure_heading ";" block return_statement "end"
|
||||
"proc" identifier_definition procedure_heading ";" block
|
||||
{
|
||||
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1), $2.first, $2.second,
|
||||
$3, $5, $6);
|
||||
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1), $2.first, $2.second, $3, $5);
|
||||
}
|
||||
| "proc" identifier_definition procedure_heading ";" "extern"
|
||||
{
|
||||
@ -220,7 +221,10 @@ procedure_definitions:
|
||||
std::swap($$, $2);
|
||||
$$.emplace($$.cbegin(), std::move($1));
|
||||
}
|
||||
| /* no procedure definitions */ {}
|
||||
| procedure_definition { $$.emplace_back(std::move($1)); }
|
||||
procedure_part:
|
||||
/* no procedure definitions */ {}
|
||||
| procedure_definitions { std::swap($$, $1); }
|
||||
assign_statement: designator_expression ":=" expression
|
||||
{
|
||||
$$ = new elna::boot::assign_statement(elna::boot::make_position(@1), $1, $3);
|
||||
@ -275,12 +279,15 @@ 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
|
||||
{
|
||||
$$ = $2;
|
||||
$$ = new elna::boot::return_statement(elna::boot::make_position(@1), $2);
|
||||
}
|
||||
defer_statement: DEFER statements "end"
|
||||
{
|
||||
$$ = new elna::boot::defer_statement(elna::boot::make_position(@1));
|
||||
std::swap($2, $$->statements);
|
||||
}
|
||||
| /* no return statement */ { $$ = nullptr; }
|
||||
literal:
|
||||
INTEGER
|
||||
{
|
||||
@ -451,21 +458,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($$, $3);
|
||||
$$.emplace($$.cbegin(), $1);
|
||||
}
|
||||
| statement
|
||||
{
|
||||
$$.push_back($1);
|
||||
$$.insert($$.cbegin(), $1);
|
||||
}
|
||||
| statement { $$.push_back($1); }
|
||||
| /* no statements */ {}
|
||||
statement_part:
|
||||
"begin" statements { std::swap($$, $2); }
|
||||
| {}
|
||||
field_declaration:
|
||||
IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
|
||||
required_fields:
|
||||
|
Reference in New Issue
Block a user