aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-07 22:02:15 +0200
committerEugen Wissner <belka@caraus.de>2026-09-07 23:39:53 +0200
commit72f5e82196d95008ed12c12de6bdccf24361e106 (patch)
tree8319324de8e2a5182dc3c1ddca00a837c2489ad2 /include
parent47521ad6d85f9bd6caee39696ce40dff82cfa50d (diff)
downloadelna-72f5e82196d95008ed12c12de6bdccf24361e106.tar.gz
Make module entry point more procedure like
Diffstat (limited to 'include')
-rw-r--r--include/elna/boot/ast.h7
-rw-r--r--include/elna/boot/dependency.h34
-rw-r--r--include/elna/boot/type_check.h5
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);