@@ -25,7 +25,7 @@ row_var = ".." lower_ident
2525### 1.2 Keywords
2626
2727```
28- fn let mut own ref type struct enum trait impl effect handle
28+ fn let const extern mut own ref type struct enum trait impl effect handle
2929resume handler match if else while for return break continue in
3030true false where total module use pub as unsafe assume transmute
3131forget Nat Int Bool Float String Type Row
@@ -68,6 +68,7 @@ Special: \ (row restriction)
6868``` ebnf
6969program = [module_decl] {import_decl} {top_level}
7070top_level = fn_decl | type_decl | trait_decl | impl_block | effect_decl
71+ | const_decl | extern_type_decl | extern_fn_decl
7172```
7273
7374### 2.2 Type Declarations
@@ -194,6 +195,27 @@ impl_block = "impl" [type_params] [trait_ref "for"] type_expr
194195 [where_clause] "{" {impl_item} "}"
195196```
196197
198+ ### 2.9 Constant Declarations
199+
200+ ``` ebnf
201+ const_decl = [visibility] "const" LOWER_IDENT ":" type_expr "=" expr ";"
202+ ```
203+
204+ Top-level ` const ` bindings are evaluated at compile time and emitted as
205+ immutable WebAssembly globals. Both function names and const names are
206+ registered in the codegen name environment (see §5.1).
207+
208+ ### 2.10 Extern Declarations
209+
210+ ``` ebnf
211+ extern_type_decl = "extern" "type" UPPER_IDENT ";"
212+ extern_fn_decl = "extern" "fn" LOWER_IDENT "(" [param_list] ")" ["->" type_expr] ";"
213+ ```
214+
215+ ` extern type ` declares an opaque host-provided type. ` extern fn ` declares a
216+ function whose implementation is supplied by the host environment at link time
217+ (a WebAssembly import). Both are top-level only and carry no body.
218+
197219## 3. Type System
198220
199221### 3.1 Judgement Forms
@@ -524,6 +546,42 @@ Compiles to (ownership removed):
524546 (call $close (local.get $file)))
525547```
526548
549+ ## 8. Codegen Module Environment
550+
551+ This section describes how the WebAssembly code generator (` lib/codegen.ml ` )
552+ builds its name environment. It is implementation documentation aimed at
553+ contributors; the language semantics are fully specified in §2–4.
554+
555+ ### 8.1 Name Environment (` func_indices ` )
556+
557+ The codegen context maintains a single association list `func_indices :
558+ (string * int) list` that maps every top-level name visible at call sites to an
559+ integer key. Two distinct kinds of binding share this table:
560+
561+ | Source declaration | Key value | Meaning |
562+ | --------------------| -----------| ---------|
563+ | ` fn f(…) { … } ` | ` k ≥ 0 ` | WebAssembly function index (import + defined functions combined) |
564+ | ` const C: T = e ` | ` -(g+1) ` where ` g ` is the global index | Negative sentinel; caller must emit ` global.get g ` not ` call k ` |
565+
566+ The negative-index encoding lets call-site code distinguish constants from
567+ functions with a single sign test before emitting the appropriate instruction.
568+
569+ ** Population order.** Both ` TopFn ` and ` TopConst ` are processed by ` gen_decl `
570+ in declaration order (the single pass in ` gen_program ` ). Each inserts its name
571+ into ` func_indices ` before any later declaration can reference it. Forward
572+ references to functions are therefore not supported in the current
573+ single-pass design.
574+
575+ ### 8.2 Extern Bindings
576+
577+ ` TopExternFn ` declarations are added to the WebAssembly import section and
578+ their names are registered in ` func_indices ` with the resulting import function
579+ index. ` TopExternType ` declarations register an opaque type name and generate
580+ no code.
581+
582+ The WebAssembly module name for an ` extern fn ` import defaults to ` "env" ` unless
583+ overridden by a ` @module("…") ` pragma on the declaration (not yet implemented).
584+
527585## Appendix: Grammar Reference
528586
529587See the full specification at ` affinescript-spec.md ` for:
0 commit comments