Bytecode module compiler: loadModule/compileModule APIs + build script
- sx_browser.ml: add api_load_module (execute pre-compiled bytecode on VM, copy defines back to env) and api_compile_module (compile SX source to bytecode via compile-module function) - compile-modules.js: Node.js build tool that loads the js_of_ocaml kernel, compiles all 23 .sx platform files to bytecode, writes .sxbc.json files - Serialization format: type-tagged JSON constants (s/n/b/nil/sym/kw/list/code) with nested code objects for lambda closures All 23 files compile successfully (430K total bytecode JSON). Next: wire up sx-platform.js to load bytecode instead of source. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -231,6 +231,34 @@ let api_load src_js =
|
||||
| Eval_error msg -> Js.Unsafe.inject (Js.string ("Error: " ^ msg))
|
||||
| Parse_error msg -> Js.Unsafe.inject (Js.string ("Parse error: " ^ msg))
|
||||
|
||||
let api_load_module module_js =
|
||||
try
|
||||
let code_val = js_to_value module_js in
|
||||
let code = Sx_vm.code_from_value code_val in
|
||||
let globals = Hashtbl.create 256 in
|
||||
Hashtbl.iter (fun id v -> Hashtbl.replace globals (unintern id) v) global_env.bindings;
|
||||
let _result = Sx_vm.execute_module code globals in
|
||||
(* Copy all globals back into env — new defines + unchanged values *)
|
||||
Hashtbl.iter (fun k v ->
|
||||
Hashtbl.replace global_env.bindings (intern k) v
|
||||
) globals;
|
||||
Js.Unsafe.inject (Hashtbl.length globals)
|
||||
with
|
||||
| Eval_error msg -> Js.Unsafe.inject (Js.string ("Error: " ^ msg))
|
||||
| exn -> Js.Unsafe.inject (Js.string ("Error: " ^ Printexc.to_string exn))
|
||||
|
||||
let api_compile_module src_js =
|
||||
let src = Js.to_string src_js in
|
||||
try
|
||||
let exprs = Sx_parser.parse_all src in
|
||||
let compile_fn = env_get global_env "compile-module" in
|
||||
let code = Sx_ref.eval_expr (List [compile_fn; List exprs]) (Env global_env) in
|
||||
return_via_side_channel (value_to_js code)
|
||||
with
|
||||
| Eval_error msg -> Js.Unsafe.inject (Js.string ("Error: " ^ msg))
|
||||
| Parse_error msg -> Js.Unsafe.inject (Js.string ("Parse error: " ^ msg))
|
||||
| Not_found -> Js.Unsafe.inject (Js.string "Error: compile-module not loaded")
|
||||
|
||||
let api_render_to_html expr_js =
|
||||
let expr = js_to_value expr_js in
|
||||
let prev = !_sx_render_mode in
|
||||
@@ -624,6 +652,8 @@ let () =
|
||||
Js.Unsafe.set sx (Js.string "evalExpr") (wrap api_eval_expr);
|
||||
Js.Unsafe.set sx (Js.string "renderToHtml") (Js.wrap_callback api_render_to_html);
|
||||
Js.Unsafe.set sx (Js.string "load") (Js.wrap_callback api_load);
|
||||
Js.Unsafe.set sx (Js.string "loadModule") (Js.wrap_callback api_load_module);
|
||||
Js.Unsafe.set sx (Js.string "compileModule") (wrap api_compile_module);
|
||||
Js.Unsafe.set sx (Js.string "typeOf") (Js.wrap_callback api_type_of);
|
||||
Js.Unsafe.set sx (Js.string "inspect") (Js.wrap_callback api_inspect);
|
||||
Js.Unsafe.set sx (Js.string "engine") (Js.wrap_callback api_engine);
|
||||
|
||||
Reference in New Issue
Block a user