fix(compiler): translate Map/Set expression patterns to JavaScript (#18)

- x in someSet → someSet.has(x)
- x in someMap.keys → someMap.has(x)
- x notIn someMap.keys → !someMap.has(x)
- m[k] → m.get(k) for Map state variables
- s.size() → s.size (property, not method)
- Track Map-typed state variables via mapVarNames for accurate .get() translation
- Thread mapVarNames through emitAction and rewriteExpr

All 41 tests passing. TigerBeetleLedger now generates correct TypeScript
with .get() for Map access and .has() for Set membership.

Part of M0.1: Fix TS generator bugs (speckl#18)
This commit is contained in:
cos Agent 2026-05-09 22:07:32 -07:00 • committed by Scott Scoble
parent 03de892259
commit 1cbad9d756
20 changed files with 908 additions and 17 deletions

71
out/ToggleSwitch.wat Normal file
View file

@ -0,0 +1,71 @@
;; Auto-generated by speckl-compile from ToggleSwitch
;; Compile: wat2wasm ToggleSwitch.wat -o ToggleSwitch.wasm
(module
;; Host imports for Map/Set/alloc
(import "speckl" "map_create" (func $map_create (result i32)))
(import "speckl" "map_set" (func $map_set (param i32 i32 i32)))
(import "speckl" "map_get" (func $map_get (param i32 i32) (result i32)))
(import "speckl" "map_has" (func $map_has (param i32 i32) (result i32)))
(import "speckl" "map_remove" (func $map_remove (param i32 i32)))
(import "speckl" "set_create" (func $set_create (result i32)))
(import "speckl" "set_add" (func $set_add (param i32 i32)))
(import "speckl" "set_has" (func $set_has (param i32 i32) (result i32)))
(import "speckl" "set_size" (func $set_size (param i32) (result i32)))
(import "speckl" "alloc" (func $alloc (param i32) (result i32)))
(import "speckl" "write_i32" (func $write_i32 (param i32 i32)))
(import "speckl" "write_f64" (func $write_f64 (param i32 f64)))
;; Linear memory (exported so host can read state)
(memory (export "memory") 1)
;; State globals
(global $isOn (mut i32) (i32.const 0))
;; ---- init ----
(func $init (export "init")
(i32.const 0)
(global.set $isOn)
)
;; ---- Actions ----
;; action: TurnOn
(func $TurnOn (export "TurnOn") (result i32)
;; require: not isOn
;; Complex guard not compiled: not isOn
;; isOn := true
(i32.const 0) ;; uncompiled expr: true
(global.set $isOn)
(global.get $isOn)
(return)
)
;; action: TurnOff
(func $TurnOff (export "TurnOff") (result i32)
;; require: isOn
;; Complex guard not compiled: isOn
;; isOn := false
(i32.const 0) ;; uncompiled expr: false
(global.set $isOn)
(global.get $isOn)
(return)
)
;; ---- getState ----
(func $getState (export "getState") (result i32 i32)
(i32.const 0)
(global.get $isOn)
(i32.store)
(i32.const 0)
(i32.const 4)
)
;; checkConstraints — runtime constraint evaluation stub
(func $checkConstraints (export "checkConstraints") (result i32)
;; TODO: evaluate constraint expressions at runtime
(i32.const 1)
)
)