Label loops

This commit is contained in:
2025-04-12 12:05:32 +02:00
parent 6fd1bda112
commit 8ec407515a
9 changed files with 134 additions and 103 deletions

View File

@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include <memory>
#include <string>
#include <vector>
#include <optional>
#include "elna/boot/result.h"
namespace elna::boot
@ -52,6 +53,12 @@ namespace elna::boot
minus
};
enum class escape_direction
{
begin,
end
};
class variable_declaration;
class constant_definition;
class procedure_definition;
@ -60,6 +67,7 @@ namespace elna::boot
class cast_expression;
class assign_statement;
class if_statement;
class escape_statement;
class while_statement;
class return_statement;
class case_statement;
@ -99,6 +107,7 @@ namespace elna::boot
virtual void visit(traits_expression *) = 0;
virtual void visit(assign_statement *) = 0;
virtual void visit(if_statement *) = 0;
virtual void visit(escape_statement *) = 0;
virtual void visit(while_statement *) = 0;
virtual void visit(return_statement *) = 0;
virtual void visit(defer_statement *) = 0;
@ -152,13 +161,6 @@ namespace elna::boot
class statement : public virtual node
{
public:
virtual assign_statement *is_assign();
virtual if_statement *is_if();
virtual while_statement *is_while();
virtual return_statement *is_return();
virtual defer_statement *is_defer();
virtual procedure_call *is_call_statement();
};
class expression : public virtual node
@ -428,9 +430,9 @@ namespace elna::boot
expression *m_prerequisite;
public:
std::vector<statement *> statements;
const std::vector<statement *> statements;
conditional_statements(expression *prerequisite);
conditional_statements(expression *prerequisite, std::vector<statement *>&& statements);
expression& prerequisite();
@ -444,7 +446,6 @@ namespace elna::boot
return_statement(const struct position position, expression *return_expression = nullptr);
void accept(parser_visitor *visitor) override;
virtual return_statement *is_return() override;
virtual ~return_statement() override;
};
@ -558,7 +559,6 @@ namespace elna::boot
procedure_call(const struct position position, designator_expression *callable);
void accept(parser_visitor *visitor) override;
virtual procedure_call *is_call_statement() override;
virtual procedure_call *is_call_expression() override;
designator_expression& callable();
@ -585,7 +585,6 @@ namespace elna::boot
expression& rvalue();
virtual ~assign_statement() override;
assign_statement *is_assign() override;
};
/**
@ -602,13 +601,23 @@ namespace elna::boot
if_statement(const struct position position, conditional_statements *body,
std::vector<statement *> *alternative = nullptr);
void accept(parser_visitor *visitor) override;
virtual if_statement *is_if() override;
conditional_statements& body();
virtual ~if_statement() override;
};
class escape_statement : public statement
{
public:
const escape_direction direction;
const std::string label;
escape_statement(const struct position position,
escape_direction direction, const std::string& label);
void accept(parser_visitor *visitor) override;
};
/**
* While-statement.
*/
@ -617,10 +626,14 @@ namespace elna::boot
conditional_statements *m_body;
public:
std::vector<conditional_statements *> branches;
while_statement(const struct position position, conditional_statements *body);
const std::vector<conditional_statements *> branches;
const std::optional<std::string> label;
while_statement(const struct position position, conditional_statements *body,
std::vector<conditional_statements *>&& branches);
while_statement(const struct position position, conditional_statements *body,
std::vector<conditional_statements *>&& branches, const std::string& label);
void accept(parser_visitor *visitor) override;
while_statement *is_while() override;
conditional_statements& body();
@ -676,7 +689,6 @@ namespace elna::boot
defer_statement(const struct position position, std::vector<statement *>&& statements);
void accept(parser_visitor *visitor) override;
defer_statement *is_defer() override;
virtual ~defer_statement() override;
};

View File

@ -75,6 +75,7 @@ namespace elna::boot
void visit(procedure_definition *definition) override;
void visit(assign_statement *statement) override;
void visit(if_statement *statement) override;
void visit(escape_statement *) override;
void visit(while_statement *statement) override;
void visit(return_statement *statement) override;
void visit(defer_statement *statement) override;

View File

@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include <string>
#include <forward_list>
namespace elna::gcc
{
@ -45,6 +46,7 @@ namespace elna::gcc
tree current_expression{ NULL_TREE };
std::shared_ptr<symbol_table> symbols;
std::unordered_map<std::string, tree> unresolved;
std::forward_list<std::pair<tree, tree>> loops;
void declare_procedure(boot::procedure_definition *const definition);
tree build_procedure_type(boot::procedure_type_expression& type);
@ -100,6 +102,7 @@ namespace elna::gcc
void visit(boot::block *block) override;
void visit(boot::assign_statement *statement) override;
void visit(boot::if_statement *statement) override;
void visit(boot::escape_statement *statement) override;
void visit(boot::while_statement *statement) override;
void visit(boot::named_type_expression *type) override;
void visit(boot::array_type_expression *type) override;