Transpiler native record support for VM types (Step 5.5 unblock)

- Add VmFrame/VmMachine types to sx_types.ml (alongside CekState/CekFrame)
- Add VmFrame/VmMachine value variants to the value sum type
- Extend get_val in sx_runtime.ml to dispatch on VmFrame/VmMachine fields
- Extend sx_dict_set_b for VmFrame/VmMachine field mutation
- Extend transpiler ml-emit-dict-native to detect VM dict patterns
  and emit native OCaml record construction (same mechanism as CekState)
- Retranspile evaluator — no diff (transpiler extension is additive)
- Update bootstrap_vm.py output location

The transpiler now handles 4 native record types:
  CekState (5 fields), CekFrame (10 fields),
  VmFrame (4 fields), VmMachine (5 fields)

Full VM replacement (sx_vm.ml → transpiled) still needs vm.sx
feature parity: JIT dispatch, CEK fallback, suspension handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-04 12:39:20 +00:00
parent fc2b5e502f
commit df89d8249b
3 changed files with 125 additions and 16 deletions

View File

@@ -80,6 +80,16 @@ let sx_dict_set_b d k v =
match d, k with
| Dict tbl, String key -> Hashtbl.replace tbl key v; v
| Dict tbl, Keyword key -> Hashtbl.replace tbl key v; v
| VmFrame f, String key ->
(match key with
| "ip" -> f.vf_ip <- val_to_int v; v
| _ -> raise (Eval_error ("dict-set! vm-frame: unknown field " ^ key)))
| VmMachine m, String key ->
(match key with
| "sp" -> m.vm_sp <- val_to_int v; v
| "frames" -> m.vm_frames <- (match v with List l -> List.map (fun x -> match x with VmFrame f -> f | _ -> raise (Eval_error "vm: frames must be vm-frame list")) l | _ -> []); v
| "stack" -> (match v with List _ -> v | _ -> raise (Eval_error "vm: stack must be array"))
| _ -> raise (Eval_error ("dict-set! vm-machine: unknown field " ^ key)))
| _ -> raise (Eval_error "dict-set!: expected dict and string key")
(** Get from dict or list. *)
@@ -107,6 +117,20 @@ let get_val container key =
| "first-render" -> f.cf_extra2 | "file" -> f.cf_env
| "extra" -> f.cf_extra | "extra2" -> f.cf_extra2
| _ -> Nil)
| VmFrame f, String k ->
(match k with
| "ip" -> Number (float_of_int f.vf_ip)
| "closure" -> VmClosure f.vf_closure
| "base" -> Number (float_of_int f.vf_base)
| "local-cells" -> Nil (* opaque — accessed via frame-local-get/set *)
| _ -> Nil)
| VmMachine m, String k ->
(match k with
| "sp" -> Number (float_of_int m.vm_sp)
| "stack" -> Nil (* opaque — accessed via vm-push/pop *)
| "frames" -> List (List.map (fun f -> VmFrame f) m.vm_frames)
| "globals" -> Dict m.vm_globals
| _ -> Nil)
| Dict d, String k -> dict_get d k
| Dict d, Keyword k -> dict_get d k
| (List l | ListRef { contents = l }), Number n ->