diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-09-16 11:49:35 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-09-16 11:49:35 +0200 |
| commit | b575036fe804f14b78da74897a74b010cc94f730 (patch) | |
| tree | 054dcb6e932bc8cf5faf2a0158794913fc6e8be3 /include | |
| parent | 52c8ca2c06da93c8d14e80a256e8996c1fa1e885 (diff) | |
| download | elna-b575036fe804f14b78da74897a74b010cc94f730.tar.gz | |
Implement named blocks
Diffstat (limited to 'include')
| -rw-r--r-- | include/elna/boot/ast.h | 36 | ||||
| -rw-r--r-- | include/elna/boot/name_analysis.h | 9 | ||||
| -rw-r--r-- | include/elna/boot/symbol.h | 24 | ||||
| -rw-r--r-- | include/elna/boot/validation.h | 2 | ||||
| -rw-r--r-- | include/elna/gcc/elna-generic.h | 2 |
5 files changed, 72 insertions, 1 deletions
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index ffc57de..4eea412 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -148,6 +148,8 @@ namespace elna::boot template<literal_type T> class literal; class defer_statement; + class block_statement; + class break_statement; class empty_statement; /** @@ -171,6 +173,8 @@ namespace elna::boot virtual void visit(repeat_statement *) = 0; virtual void visit(for_statement *) = 0; virtual void visit(defer_statement *) = 0; + virtual void visit(block_statement *) = 0; + virtual void visit(break_statement *) = 0; virtual void visit(case_statement *) = 0; virtual void visit(empty_statement *) = 0; virtual void visit(unit *) = 0; @@ -223,6 +227,8 @@ namespace elna::boot [[noreturn]] void visit(repeat_statement *) override; [[noreturn]] void visit(for_statement *) override; [[noreturn]] void visit(defer_statement *) override; + [[noreturn]] void visit(block_statement *) override; + [[noreturn]] void visit(break_statement *) override; [[noreturn]] void visit(empty_statement *) override; [[noreturn]] void visit(case_statement *) override; [[noreturn]] void visit(procedure_call *) override; @@ -271,6 +277,8 @@ namespace elna::boot void visit(repeat_statement *statement) override; void visit(for_statement *statement) override; void visit(defer_statement *statement) override; + void visit(block_statement *statement) override; + void visit(break_statement *) override; void visit(empty_statement *) override; void visit(case_statement *statement) override; void visit(procedure_call *call) override; @@ -1104,6 +1112,34 @@ namespace elna::boot ~defer_statement() override; }; + /** + * Named block a break-statement can jump out of. + */ + class block_statement : public statement + { + public: + const identifier name; + const std::vector<statement *> statements; + + block_statement(const source_position position, identifier&& name, + std::vector<statement *>&& statements); + void accept(parser_visitor *visitor) override; + + ~block_statement() override; + }; + + /** + * Jump to the end of the named block. + */ + class break_statement : public statement + { + public: + const identifier label; + + break_statement(const source_position position, identifier&& label); + void accept(parser_visitor *visitor) override; + }; + class empty_statement : public statement { public: diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h index eff122b..67cd713 100644 --- a/include/elna/boot/name_analysis.h +++ b/include/elna/boot/name_analysis.h @@ -43,7 +43,10 @@ namespace elna::boot undeclared_type, undeclared_trait, undeclared_symbol, - not_a_type + undeclared_label, + not_a_type, + not_a_label, + break_leaves_defer }; struct redefinition { @@ -208,6 +211,8 @@ namespace elna::boot symbol_bag& bag; evaluator constant_evaluator; std::filesystem::path module_file; + /// Number of defer bodies the visited statement stands in. + std::size_t defer_depth{ 0 }; resolving_visitor(symbol_bag& bag, const target_info& target, const std::filesystem::path& module_path); @@ -310,6 +315,8 @@ namespace elna::boot void visit(while_statement *statement) override; void visit(repeat_statement *statement) override; void visit(defer_statement *statement) override; + void visit(block_statement *statement) override; + void visit(break_statement *statement) override; void visit(empty_statement *) override; void visit(case_statement *statement) override; diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h index 08292bc..5bbe2c6 100644 --- a/include/elna/boot/symbol.h +++ b/include/elna/boot/symbol.h @@ -271,6 +271,7 @@ namespace elna::boot class type_info; class procedure_info; class variable_info; + class label_info; class info : public std::enable_shared_from_this<info> { @@ -285,6 +286,7 @@ namespace elna::boot virtual std::shared_ptr<type_info> is_type(); virtual std::shared_ptr<procedure_info> is_procedure(); virtual std::shared_ptr<variable_info> is_variable(); + virtual std::shared_ptr<label_info> is_label(); }; /** @@ -501,6 +503,28 @@ namespace elna::boot std::shared_ptr<variable_info> is_variable() override; }; + /** + * Named block a break-statement can jump to. + */ + class label_info : public info + { + public: + /** + * Constructs a label symbol information. + * + * \param defer_depth Number of defer bodies enclosing the block. + */ + explicit label_info(std::size_t defer_depth); + + std::shared_ptr<label_info> is_label() override; + + /* + * A break may not leave the defer body it stands in, so a label + * declared outside that body is not a valid target. + */ + const std::size_t defer_depth; + }; + std::shared_ptr<symbol_table> builtin_symbol_table(const target_info& target); /** diff --git a/include/elna/boot/validation.h b/include/elna/boot/validation.h index 8598ada..87e0b18 100644 --- a/include/elna/boot/validation.h +++ b/include/elna/boot/validation.h @@ -65,6 +65,8 @@ namespace elna::boot void visit(repeat_statement *statement) override; void visit(for_statement *statement) override; void visit(defer_statement *statement) override; + void visit(block_statement *statement) override; + void visit(break_statement *) override; void visit(empty_statement *) override; void visit(procedure_call *) override; }; diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index dde883a..b05a8f9 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -103,6 +103,8 @@ namespace elna::gcc void visit(boot::for_statement *statement) override; void visit(boot::while_statement *statement) override; void visit(boot::defer_statement *statement) override; + void visit(boot::block_statement *statement) override; + void visit(boot::break_statement *statement) override; void visit(boot::empty_statement *) override; void visit(boot::case_statement *statement) override; }; |
