← Commit history

docs: describe module state in terms of the single IR unit

lennoxrose committed on Oct 18, 2026 at 00:50 UTC

d34035dparent2a78226

3 files changed+15−19

hearth/ashvm/src/compiler/H/module_state.hmodified

+5−7
@@ -1,13 +1,11 @@
11 #ifndef ASH_VM_COMPILER_MODULE_STATE_H
22 #define ASH_VM_COMPILER_MODULE_STATE_H
33
4-// Module-level state: every top-level `local NAME = <expression>;` of an
5-// imported file. The expression runs once, where the `@import` appears (so
6-// before the importing file's own code), and the value lives in a numbered
7-// global slot instead of a frame, so every function of that file -- and
8-// `ns.NAME` from the importer -- can read it, and `NAME = ...;`, `NAME += ...;`,
9-// `NAME[i] = ...;` update it. Names are qualified with the file's namespace
10-// ("ns.NAME"), like imported functions.
4+// Module-level state: every top-level `local NAME = <expression>;` of the IR unit
5+// (see ir/H/ir_lex.h). The expression runs once, at program start before `start` is
6+// called, and the value lives in a numbered global slot instead of a frame, so every
7+// function of the unit can read it, and `NAME = ...;`, `NAME += ...;`, `NAME[i] = ...;`
8+// update it. Names are qualified with the unit's namespace ("g.NAME").
119
1210 // Reserves a slot for NAME in the current import namespace; returns its index.
1311 int module_state_declare(const char *name, int len);

hearth/kiln/src/parser/C/core/parser.cmodified

+4−4
@@ -75,10 +75,10 @@ static void local_statement(void) {
7575 // that file's own functions -- the sibling guard further down in
7676 // statement() already gets this right, this one didn't.
7777 if (ns_len > 0 && block_depth == 0) {
78- // A top-level `local` of an imported file is a module-level variable: the
79- // expression runs once, at the point of the `@import`, and the value lives
80- // in a global slot every function of that file (and `ns.NAME`) can read,
81- // and `NAME = ...;` can update (see parser/H/declarations/module_state.h).
78+ // A top-level `local` of the IR unit is a module-level variable: the
79+ // expression runs once, at program start, and the value lives in a global
80+ // slot every function of the unit can read and `NAME = ...;` can update
81+ // (see parser/H/declarations/module_state.h).
8282 int state_slot = module_state_declare(name, len);
8383 codegen_expression();
8484 expect(TOKEN_SEMICOLON, "expected ';' after statement");

hearth/kiln/src/parser/H/declarations/module_state.hmodified

+6−8
@@ -1,14 +1,12 @@
11 #ifndef KILN_MODULE_STATE_H
22 #define KILN_MODULE_STATE_H
33
4-// Module-level state: a top-level `local NAME = <expression>;` in an imported
5-// file whose value is not a plain number/string literal. The expression runs
6-// once, where the `@import` appears (so before the importing file's own code),
7-// and the value lives in a numbered slot in the globals region instead of a
8-// frame, so every function of that file -- and `ns.NAME` from the importer --
9-// can read it, and `NAME = ...;`, `NAME += ...;`, `NAME[i] = ...;` update it.
10-// Slots are named under the file's namespace ("ns.NAME"), like imported
11-// functions and constants.
4+// Module-level state: a top-level `local NAME = <expression>;` of the IR unit (see
5+// ir/H/ir_lex.h) whose value is not a plain number/string literal. The expression runs
6+// once, at program start before `start` is called, and the value lives in a numbered
7+// slot in the globals region instead of a frame, so every function of the unit can
8+// read it, and `NAME = ...;`, `NAME += ...;`, `NAME[i] = ...;` update it. Slots are
9+// named under the unit's namespace ("g.NAME"), like its functions and constants.
1210
1311 // Reserves a slot for NAME in the current import namespace; returns its index.
1412 int module_state_declare(const char *name, int len);