diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/elna/boot/ast.h | 7 | ||||
| -rw-r--r-- | include/elna/boot/dependency.h | 34 | ||||
| -rw-r--r-- | include/elna/boot/type_check.h | 5 |
3 files changed, 41 insertions, 5 deletions
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index c485dc7..4919510 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -292,6 +292,10 @@ namespace elna::boot void visit(literal<std::uint32_t> *) override; void visit(literal<std::nullptr_t> *) override; void visit(literal<std::string> *) override; + + protected: + /// Passes needing the entry point's scope override this. + virtual void visit_entry_point(unit *unit); }; /** @@ -951,6 +955,7 @@ namespace elna::boot const std::vector<variable_declaration *> variables; const std::optional<procedure_body> entry_point; const std::vector<identifier> parameters; + const std::optional<source_position> entry_position; unit(const source_position position, std::vector<import_declaration *>&& imports, @@ -962,6 +967,8 @@ namespace elna::boot std::vector<type_declaration *>&& types, std::vector<variable_declaration *>&& variables, std::vector<procedure_declaration *>&& procedures, + std::vector<identifier>&& parameters, + const source_position entry_position, std::optional<procedure_body>&& body); void accept(parser_visitor *visitor) override; diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h index 9bc1adf..195d37a 100644 --- a/include/elna/boot/dependency.h +++ b/include/elna/boot/dependency.h @@ -104,16 +104,27 @@ namespace elna::boot }; /** - * An import that closes a cycle, e.g. a module importing itself. + * A module that cannot be imported. */ - class circular_import_error final : public diagnostic + class import_error final : public diagnostic { const std::string module_name; public: - circular_import_error(const source_position position, const std::string& module_name); + enum class kind + { + /// An import that closes a cycle, e.g. a module importing itself. + circular, + /// A program has an entry point and is not importable. + program + }; + + import_error(const source_position position, const std::string& module_name, kind payload); std::string what() const override; + + private: + const kind m_payload; }; /** @@ -249,6 +260,19 @@ namespace elna::boot std::vector<std::shared_ptr<symbol_table>> imports; diagnostic_list circular; + if (imported && tree->entry_point.has_value()) + { + diagnostic_list entry_point; + + entry_point.push_back(std::make_unique<import_error>(tree->entry_position.value(), + key.stem().string(), import_error::kind::program)); + result.append(key, std::move(entry_point)); + this->cache.insert({ key, symbol_bag({}, this->globals) }); + this->in_progress.erase(key); + + return result; + } + for (const import_declaration* sub_tree : tree->imports) { const std::filesystem::path module_path = loader.resolve( @@ -256,8 +280,8 @@ namespace elna::boot if (this->in_progress.contains(module_path)) { - circular.push_back(std::make_unique<circular_import_error>(sub_tree->position(), - module_path.stem().string())); + circular.push_back(std::make_unique<import_error>(sub_tree->position(), + module_path.stem().string(), import_error::kind::circular)); continue; } dependency sub = this->compile(module_path, loader, target, true); diff --git a/include/elna/boot/type_check.h b/include/elna/boot/type_check.h index 345ef9d..50b9225 100644 --- a/include/elna/boot/type_check.h +++ b/include/elna/boot/type_check.h @@ -214,6 +214,11 @@ namespace elna::boot static bool is_equality_compatible(const type& left, const type& right); void visit_and_validate_condition(expression& condition); + void check_return(const procedure_body& body, const source_position position, + const std::string& name); + + protected: + void visit_entry_point(unit *unit) override; public: explicit type_analysis_visitor(symbol_bag bag, const target_info& target); |
