← Commit history
docs: describe module state in terms of the single IR unit
lennoxrose committed on Oct 18, 2026 at 00:50 UTC
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_H22
#define ASH_VM_COMPILER_MODULE_STATE_H33
4
-// Module-level state: every top-level `local NAME = <expression>;` of an5
-// imported file. The expression runs once, where the `@import` appears (so6
-// before the importing file's own code), and the value lives in a numbered7
-// global slot instead of a frame, so every function of that file -- and8
-// `ns.NAME` from the importer -- can read it, and `NAME = ...;`, `NAME += ...;`,9
-// `NAME[i] = ...;` update it. Names are qualified with the file's namespace10
-// ("ns.NAME"), like imported functions.4
+// Module-level state: every top-level `local NAME = <expression>;` of the IR unit5
+// (see ir/H/ir_lex.h). The expression runs once, at program start before `start` is6
+// called, and the value lives in a numbered global slot instead of a frame, so every7
+// 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 in7676
// 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: the79
- // expression runs once, at the point of the `@import`, and the value lives80
- // 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: the79
+ // expression runs once, at program start, and the value lives in a global80
+ // slot every function of the unit can read and `NAME = ...;` can update81
+ // (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_H22
#define KILN_MODULE_STATE_H33
4
-// Module-level state: a top-level `local NAME = <expression>;` in an imported5
-// file whose value is not a plain number/string literal. The expression runs6
-// 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 a8
-// 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 imported11
-// functions and constants.4
+// Module-level state: a top-level `local NAME = <expression>;` of the IR unit (see5
+// ir/H/ir_lex.h) whose value is not a plain number/string literal. The expression runs6
+// once, at program start before `start` is called, and the value lives in a numbered7
+// slot in the globals region instead of a frame, so every function of the unit can8
+// read it, and `NAME = ...;`, `NAME += ...;`, `NAME[i] = ...;` update it. Slots are9
+// 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);