aboutsummaryrefslogtreecommitdiff
path: root/boot/ast.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-18 12:19:13 +0200
committerEugen Wissner <belka@caraus.de>2026-09-18 12:19:13 +0200
commitdc9d03915c4b169fec749081b45d56f722105813 (patch)
tree0a0719bc95f942b675fb52865d9c5bac9e105767 /boot/ast.cc
parentb575036fe804f14b78da74897a74b010cc94f730 (diff)
downloadelna-dc9d03915c4b169fec749081b45d56f722105813.tar.gz
Allow block-local variables
Diffstat (limited to 'boot/ast.cc')
-rw-r--r--boot/ast.cc157
1 files changed, 57 insertions, 100 deletions
diff --git a/boot/ast.cc b/boot/ast.cc
index 4a596e5..b38e8d1 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -253,81 +253,66 @@ namespace elna::boot
statement->rvalue().accept(this);
}
- void walking_visitor::visit(if_statement *statement)
+ void walking_visitor::traverse_block(block& body)
{
- statement->branch().prerequisite().accept(this);
- for (auto *branch_statement : statement->branch().statements)
+ for (variable_declaration *const variable : body.variables)
{
- branch_statement->accept(this);
+ variable->accept(this);
+ }
+ for (statement *const body_statement : body.statements)
+ {
+ body_statement->accept(this);
}
+ }
+
+ void walking_visitor::visit(if_statement *statement)
+ {
+ statement->branch().prerequisite().accept(this);
+ traverse_block(statement->branch().body);
+
for (conditional_statements *branch : statement->branches)
{
branch->prerequisite().accept(this);
-
- for (auto *branch_statement : branch->statements)
- {
- branch_statement->accept(this);
- }
+ traverse_block(branch->body);
}
if (statement->alternative != nullptr)
{
- for (auto *branch_statement : *statement->alternative)
- {
- branch_statement->accept(this);
- }
+ traverse_block(*statement->alternative);
}
}
void walking_visitor::visit(while_statement *statement)
{
statement->branch().prerequisite().accept(this);
- for (auto *branch_statement : statement->branch().statements)
- {
- branch_statement->accept(this);
- }
+ traverse_block(statement->branch().body);
+
for (conditional_statements *branch : statement->branches)
{
branch->prerequisite().accept(this);
-
- for (auto *branch_statement : branch->statements)
- {
- branch_statement->accept(this);
- }
+ traverse_block(branch->body);
}
}
void walking_visitor::visit(repeat_statement *statement)
{
statement->condition().accept(this);
- for (auto *body_statement : statement->body)
- {
- body_statement->accept(this);
- }
+ traverse_block(statement->body);
}
void walking_visitor::visit(for_statement *statement)
{
statement->range().accept(this);
- for (auto *body_statement : statement->body)
- {
- body_statement->accept(this);
- }
+ traverse_block(statement->body);
}
void walking_visitor::visit(defer_statement *statement)
{
- for (auto *body_statement : statement->statements)
- {
- body_statement->accept(this);
- }
+ traverse_block(statement->body);
}
void walking_visitor::visit(block_statement *statement)
{
- for (auto *body_statement : statement->statements)
- {
- body_statement->accept(this);
- }
+ traverse_block(statement->body);
}
void walking_visitor::visit(break_statement *)
@@ -341,23 +326,17 @@ namespace elna::boot
void walking_visitor::visit(case_statement *statement)
{
statement->condition().accept(this);
- for (const switch_case& case_block : statement->cases)
+ for (switch_case& case_block : statement->cases)
{
for (expression *case_label : case_block.labels)
{
case_label->accept(this);
}
- for (auto *body_statement : case_block.statements)
- {
- body_statement->accept(this);
- }
+ traverse_block(case_block.body);
}
if (statement->alternative != nullptr)
{
- for (auto *body_statement : *statement->alternative)
- {
- body_statement->accept(this);
- }
+ traverse_block(*statement->alternative);
}
}
@@ -1091,21 +1070,12 @@ namespace elna::boot
return *m_underlying_type;
}
- procedure_body::procedure_body(std::vector<variable_declaration *>&& variables,
- std::vector<statement *>&& entry_point, expression *return_expression)
- : variables(std::move(variables)),
- statements(std::move(entry_point)), return_expression(return_expression)
+ block::block(std::vector<variable_declaration *>&& variables, std::vector<statement *>&& statements)
+ : variables(std::move(variables)), statements(std::move(statements))
{
}
- procedure_body::procedure_body(procedure_body&& that) noexcept
- : variables(std::move(const_cast<std::vector<variable_declaration *>&>(that.variables))),
- statements(std::move(const_cast<std::vector<statement *>&>(that.statements))),
- return_expression(that.return_expression)
- {
- }
-
- procedure_body::~procedure_body()
+ block::~block()
{
for (const statement *body_statement : this->statements)
{
@@ -1117,6 +1087,11 @@ namespace elna::boot
}
}
+ procedure_body::procedure_body(block&& body, expression *return_expression)
+ : block(std::move(body)), return_expression(return_expression)
+ {
+ }
+
void traverse_body(parser_visitor *visitor, const procedure_body& body)
{
for (variable_declaration *variable : body.variables)
@@ -1175,8 +1150,8 @@ namespace elna::boot
return this;
}
- defer_statement::defer_statement(const source_position position, std::vector<statement *>&& statements)
- : node(position), statements(std::move(statements))
+ defer_statement::defer_statement(const source_position position, block&& body)
+ : node(position), body(std::move(body))
{
}
@@ -1185,17 +1160,8 @@ namespace elna::boot
visitor->visit(this);
}
- defer_statement::~defer_statement()
- {
- for (const statement *body_statement : statements)
- {
- delete body_statement;
- }
- }
-
- block_statement::block_statement(const source_position position, identifier&& name,
- std::vector<statement *>&& statements)
- : node(position), name(std::move(name)), statements(std::move(statements))
+ block_statement::block_statement(const source_position position, identifier&& name, block&& body)
+ : node(position), name(std::move(name)), body(std::move(body))
{
}
@@ -1204,14 +1170,6 @@ namespace elna::boot
visitor->visit(this);
}
- block_statement::~block_statement()
- {
- for (const statement *body_statement : statements)
- {
- delete body_statement;
- }
- }
-
break_statement::break_statement(const source_position position, identifier&& label)
: node(position), label(std::move(label))
{
@@ -1618,8 +1576,8 @@ namespace elna::boot
return this;
}
- conditional_statements::conditional_statements(expression *prerequisite, std::vector<statement *>&& statements)
- : m_prerequisite(prerequisite), statements(std::move(statements))
+ conditional_statements::conditional_statements(expression *prerequisite, block&& body)
+ : m_prerequisite(prerequisite), body(std::move(body))
{
}
@@ -1631,14 +1589,10 @@ namespace elna::boot
conditional_statements::~conditional_statements()
{
delete m_prerequisite;
- for (auto *statement : statements)
- {
- delete statement;
- }
}
case_statement::case_statement(const source_position position,
- expression *condition, std::vector<switch_case>&& cases, std::vector<statement *> *alternative)
+ expression *condition, std::vector<switch_case>&& cases, block *alternative)
: node(position), m_condition(condition), cases(std::move(cases)), alternative(alternative)
{
}
@@ -1653,6 +1607,19 @@ namespace elna::boot
return *m_condition;
}
+ case_statement::~case_statement()
+ {
+ delete m_condition;
+ for (const switch_case& case_block : this->cases)
+ {
+ for (const expression *case_label : case_block.labels)
+ {
+ delete case_label;
+ }
+ }
+ delete this->alternative;
+ }
+
assign_statement::assign_statement(const source_position position, designator_expression *lvalue,
expression *rvalue)
: node(position), m_lvalue(lvalue), m_rvalue(rvalue)
@@ -1705,8 +1672,7 @@ namespace elna::boot
}
if_statement::if_statement(const source_position position, conditional_statements *branch,
- std::vector<conditional_statements *>&& branches,
- std::vector<statement *> *alternative)
+ std::vector<conditional_statements *>&& branches, block *alternative)
: node(position), m_branch(branch), branches(std::move(branches)), alternative(alternative)
{
}
@@ -1766,7 +1732,7 @@ namespace elna::boot
}
}
- repeat_statement::repeat_statement(const source_position position, std::vector<statement *>&& body,
+ repeat_statement::repeat_statement(const source_position position, block&& body,
expression *condition)
: node(position), m_condition(condition), body(std::move(body))
{
@@ -1775,10 +1741,6 @@ namespace elna::boot
repeat_statement::~repeat_statement()
{
delete this->m_condition;
- for (const statement *body_statement : this->body)
- {
- delete body_statement;
- }
}
void repeat_statement::accept(parser_visitor *visitor)
@@ -1792,7 +1754,7 @@ namespace elna::boot
}
for_statement::for_statement(const source_position position, identifier&& control_variable,
- expression *range, std::vector<statement *>&& body, identifier *const counter = nullptr)
+ expression *range, block&& body, identifier *const counter = nullptr)
: node(position), m_range(range), control_variable(std::move(control_variable)),
counter(counter), body(std::move(body))
{
@@ -1802,11 +1764,6 @@ namespace elna::boot
{
delete this->m_range;
delete this->counter;
-
- for (const statement *body_statement : this->body)
- {
- delete body_statement;
- }
}
void for_statement::accept(parser_visitor *visitor)