End while and if statements with the end token
This commit is contained in:
@ -43,7 +43,7 @@ namespace source
|
||||
|
||||
void empty_visitor::visit(compound_statement *statement)
|
||||
{
|
||||
for (auto& nested_statement : statement->statements())
|
||||
for (const auto nested_statement : statement->statements)
|
||||
{
|
||||
nested_statement->accept(this);
|
||||
}
|
||||
@ -114,7 +114,15 @@ namespace source
|
||||
|
||||
void empty_visitor::visit(record_type_expression *expression)
|
||||
{
|
||||
for (auto& field : expression->fields())
|
||||
for (auto& field : expression->fields)
|
||||
{
|
||||
field.second->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void empty_visitor::visit(union_type_expression *expression)
|
||||
{
|
||||
for (auto& field : expression->fields)
|
||||
{
|
||||
field.second->accept(this);
|
||||
}
|
||||
@ -244,6 +252,11 @@ namespace source
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
union_type_expression *type_expression::is_union()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pointer_type_expression *type_expression::is_pointer()
|
||||
{
|
||||
return nullptr;
|
||||
@ -321,9 +334,23 @@ namespace source
|
||||
delete m_base;
|
||||
}
|
||||
|
||||
composite_type_expression::composite_type_expression(const struct position position,
|
||||
fields_t&& fields)
|
||||
: type_expression(position), fields(std::move(fields))
|
||||
{
|
||||
}
|
||||
|
||||
composite_type_expression::~composite_type_expression()
|
||||
{
|
||||
for (auto& field_declaration : fields)
|
||||
{
|
||||
delete field_declaration.second;
|
||||
}
|
||||
}
|
||||
|
||||
record_type_expression::record_type_expression(const struct position position,
|
||||
record_type_expression::fields_t&& fields)
|
||||
: type_expression(position), m_fields(std::move(fields))
|
||||
fields_t&& fields)
|
||||
: composite_type_expression(position, std::move(fields))
|
||||
{
|
||||
}
|
||||
|
||||
@ -332,22 +359,25 @@ namespace source
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
record_type_expression::fields_t& record_type_expression::fields()
|
||||
{
|
||||
return m_fields;
|
||||
}
|
||||
|
||||
record_type_expression *record_type_expression::is_record()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
record_type_expression::~record_type_expression()
|
||||
union_type_expression::union_type_expression(const struct position position,
|
||||
fields_t&& fields)
|
||||
: composite_type_expression(position, std::move(fields))
|
||||
{
|
||||
for (auto& field_declaration : fields())
|
||||
{
|
||||
delete field_declaration.second;
|
||||
}
|
||||
}
|
||||
|
||||
union_type_expression *union_type_expression::is_union()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void union_type_expression::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
variable_declaration::variable_declaration(const struct position position, const std::string& identifier,
|
||||
@ -766,8 +796,8 @@ namespace source
|
||||
}
|
||||
}
|
||||
|
||||
compound_statement::compound_statement(const struct position position)
|
||||
: statement(position)
|
||||
compound_statement::compound_statement(const struct position position, std::vector<statement *>&& statements)
|
||||
: statement(position), statements(std::move(statements))
|
||||
{
|
||||
}
|
||||
|
||||
@ -776,14 +806,9 @@ namespace source
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
std::vector<statement *>& compound_statement::statements()
|
||||
{
|
||||
return m_statements;
|
||||
}
|
||||
|
||||
compound_statement::~compound_statement()
|
||||
{
|
||||
for (auto statement : m_statements)
|
||||
for (auto statement : statements)
|
||||
{
|
||||
delete statement;
|
||||
}
|
||||
@ -836,7 +861,7 @@ namespace source
|
||||
}
|
||||
|
||||
if_statement::if_statement(const struct position position, expression *prerequisite,
|
||||
statement *body, statement *alternative)
|
||||
compound_statement *body, compound_statement *alternative)
|
||||
: statement(position), m_prerequisite(prerequisite), m_body(body),
|
||||
m_alternative(alternative)
|
||||
{
|
||||
@ -852,12 +877,12 @@ namespace source
|
||||
return *m_prerequisite;
|
||||
}
|
||||
|
||||
statement& if_statement::body()
|
||||
compound_statement& if_statement::body()
|
||||
{
|
||||
return *m_body;
|
||||
}
|
||||
|
||||
statement *if_statement::alternative()
|
||||
compound_statement *if_statement::alternative()
|
||||
{
|
||||
return m_alternative;
|
||||
}
|
||||
@ -874,7 +899,7 @@ namespace source
|
||||
}
|
||||
|
||||
while_statement::while_statement(const struct position position, expression *prerequisite,
|
||||
statement *body)
|
||||
compound_statement *body)
|
||||
: statement(position), m_prerequisite(prerequisite), m_body(body)
|
||||
{
|
||||
}
|
||||
@ -889,7 +914,7 @@ namespace source
|
||||
return *m_prerequisite;
|
||||
}
|
||||
|
||||
statement& while_statement::body()
|
||||
compound_statement& while_statement::body()
|
||||
{
|
||||
return *m_body;
|
||||
}
|
||||
|
@ -76,6 +76,15 @@ type {
|
||||
record {
|
||||
return yy::parser::make_RECORD(this->location);
|
||||
}
|
||||
union {
|
||||
return yy::parser::make_UNION(this->location);
|
||||
}
|
||||
pointer {
|
||||
return yy::parser::make_POINTER(this->location);
|
||||
}
|
||||
to {
|
||||
return yy::parser::make_TO(this->location);
|
||||
}
|
||||
true {
|
||||
return yy::parser::make_BOOLEAN(true, this->location);
|
||||
}
|
||||
|
@ -62,8 +62,8 @@
|
||||
%token <std::string> CHARACTER "character"
|
||||
%token <std::string> STRING "string"
|
||||
%token <bool> BOOLEAN
|
||||
%token IF WHILE DO
|
||||
%token CONST VAR PROCEDURE ARRAY OF TYPE RECORD
|
||||
%token IF WHILE DO THEN ELSE
|
||||
%token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO UNION
|
||||
%token BEGIN_BLOCK END_BLOCK EXTERN
|
||||
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA
|
||||
%token AND OR NOT
|
||||
@ -71,9 +71,6 @@
|
||||
%token PLUS MINUS MULTIPLICATION DIVISION
|
||||
%token ASSIGNMENT COLON HAT AT
|
||||
|
||||
%precedence THEN
|
||||
%precedence ELSE
|
||||
|
||||
%type <elna::source::literal *> literal;
|
||||
%type <elna::source::constant_definition *> constant_definition;
|
||||
%type <std::vector<elna::source::constant_definition *>> constant_part constant_definitions;
|
||||
@ -84,7 +81,6 @@
|
||||
%type <elna::source::expression *> expression pointer summand factor comparand logical_operand;
|
||||
%type <std::vector<elna::source::expression *>> expressions actual_parameter_list;
|
||||
%type <elna::source::designator_expression *> designator_expression;
|
||||
%type <elna::source::compound_statement *> compound_statement;
|
||||
%type <elna::source::assign_statement *> assign_statement;
|
||||
%type <elna::source::call_statement *> call_statement;
|
||||
%type <elna::source::while_statement *> while_statement;
|
||||
@ -167,11 +163,6 @@ procedure_definitions:
|
||||
procedure_part:
|
||||
/* no procedure definitions */ {}
|
||||
| procedure_definitions { std::swap($$, $1); }
|
||||
compound_statement: BEGIN_BLOCK optional_statements END_BLOCK
|
||||
{
|
||||
$$ = new elna::source::compound_statement(elna::source::make_position(@1));
|
||||
std::swap($$->statements(), $2);
|
||||
}
|
||||
assign_statement: designator_expression ASSIGNMENT expression
|
||||
{
|
||||
$$ = new elna::source::assign_statement(elna::source::make_position(@1), $1, $3);
|
||||
@ -181,21 +172,22 @@ call_statement: IDENTIFIER actual_parameter_list
|
||||
$$ = new elna::source::call_statement(elna::source::make_position(@1), $1);
|
||||
std::swap($$->arguments(), $2);
|
||||
}
|
||||
while_statement: WHILE expression DO statement
|
||||
while_statement: WHILE expression DO optional_statements END_BLOCK
|
||||
{
|
||||
$$ = new elna::source::while_statement(elna::source::make_position(@1),
|
||||
$2, $4);
|
||||
auto body = new elna::source::compound_statement(elna::source::make_position(@3), std::move($4));
|
||||
$$ = new elna::source::while_statement(elna::source::make_position(@1), $2, body);
|
||||
}
|
||||
if_statement:
|
||||
IF expression THEN statement
|
||||
IF expression THEN optional_statements END_BLOCK
|
||||
{
|
||||
$$ = new elna::source::if_statement(elna::source::make_position(@1),
|
||||
$2, $4);
|
||||
auto then = new elna::source::compound_statement(elna::source::make_position(@3), std::move($4));
|
||||
$$ = new elna::source::if_statement(elna::source::make_position(@1), $2, then);
|
||||
}
|
||||
| IF expression THEN statement ELSE statement
|
||||
| IF expression THEN optional_statements ELSE optional_statements END_BLOCK
|
||||
{
|
||||
$$ = new elna::source::if_statement(elna::source::make_position(@1),
|
||||
$2, $4, $6);
|
||||
auto then = new elna::source::compound_statement(elna::source::make_position(@3), std::move($4));
|
||||
auto _else = new elna::source::compound_statement(elna::source::make_position(@5), std::move($6));
|
||||
$$ = new elna::source::if_statement(elna::source::make_position(@1), $2, then, _else);
|
||||
}
|
||||
literal:
|
||||
INTEGER
|
||||
@ -315,8 +307,7 @@ designator_expression:
|
||||
$$ = new elna::source::variable_expression(elna::source::make_position(@1), $1);
|
||||
}
|
||||
statement:
|
||||
compound_statement { $$ = $1; }
|
||||
| assign_statement { $$ = $1; }
|
||||
assign_statement { $$ = $1; }
|
||||
| call_statement { $$ = $1; }
|
||||
| while_statement { $$ = $1; }
|
||||
| if_statement { $$ = $1; }
|
||||
@ -344,14 +335,18 @@ type_expression:
|
||||
{
|
||||
$$ = new elna::source::array_type_expression(elna::source::make_position(@1), $4, $2);
|
||||
}
|
||||
| HAT type_expression
|
||||
| POINTER TO type_expression
|
||||
{
|
||||
$$ = new elna::source::pointer_type_expression(elna::source::make_position(@1), $2);
|
||||
$$ = new elna::source::pointer_type_expression(elna::source::make_position(@1), $3);
|
||||
}
|
||||
| RECORD field_list END_BLOCK
|
||||
{
|
||||
$$ = new elna::source::record_type_expression(elna::source::make_position(@1), std::move($2));
|
||||
}
|
||||
| UNION field_list END_BLOCK
|
||||
{
|
||||
$$ = new elna::source::union_type_expression(elna::source::make_position(@1), std::move($2));
|
||||
}
|
||||
| IDENTIFIER
|
||||
{
|
||||
$$ = new elna::source::basic_type_expression(elna::source::make_position(@1), $1);
|
||||
@ -359,7 +354,7 @@ type_expression:
|
||||
variable_declaration: IDENTIFIER COLON type_expression
|
||||
{
|
||||
$$ = new elna::source::variable_declaration(elna::source::make_position(@1), $1, $3);
|
||||
};
|
||||
}
|
||||
variable_declarations:
|
||||
variable_declaration COMMA variable_declarations
|
||||
{
|
||||
|
Reference in New Issue
Block a user