diff --git a/hosts/ocaml/lib/sx_vm.ml b/hosts/ocaml/lib/sx_vm.ml index 7888fde5..033e27bd 100644 --- a/hosts/ocaml/lib/sx_vm.ml +++ b/hosts/ocaml/lib/sx_vm.ml @@ -410,21 +410,23 @@ and run vm = | 20 (* OP_GLOBAL_GET *) -> let idx = read_u16 frame in let name = match consts.(idx) with String s -> s | _ -> "" in - let v = try Hashtbl.find vm.globals name with Not_found -> - (* Walk the closure env chain for inner functions *) - let id = Sx_types.intern name in - let rec env_lookup e = - try Hashtbl.find e.bindings id - with Not_found -> - match e.parent with Some p -> env_lookup p | None -> - try Sx_primitives.get_primitive name - with _ -> raise (Eval_error ("VM undefined: " ^ name)) - in - match frame.closure.vm_closure_env with - | Some env -> env_lookup env + (* Check closure env first (matches OP_GLOBAL_SET priority) *) + let id = Sx_types.intern name in + let found_in_env = match frame.closure.vm_closure_env with + | Some env -> + let rec env_lookup e = + try Some (Hashtbl.find e.bindings id) + with Not_found -> + match e.parent with Some p -> env_lookup p | None -> None + in env_lookup env + | None -> None + in + let v = match found_in_env with + | Some v -> v | None -> - try Sx_primitives.get_primitive name - with _ -> raise (Eval_error ("VM undefined: " ^ name)) + try Hashtbl.find vm.globals name with Not_found -> + try Sx_primitives.get_primitive name + with _ -> raise (Eval_error ("VM undefined: " ^ name)) in push vm v | 21 (* OP_GLOBAL_SET *) -> diff --git a/hosts/ocaml/lib/sx_vm_ref.ml b/hosts/ocaml/lib/sx_vm_ref.ml index 6a7b9041..fe7113a6 100644 --- a/hosts/ocaml/lib/sx_vm_ref.ml +++ b/hosts/ocaml/lib/sx_vm_ref.ml @@ -198,32 +198,31 @@ let vm_globals_ref v = let m = unwrap_vm v in Dict m.vm_globals let vm_global_get vm_val frame_val name = let m = unwrap_vm vm_val in let n = value_to_string name in - (* Try globals table first *) - match Hashtbl.find_opt m.vm_globals n with + let f = unwrap_frame frame_val in + (* Check closure env first (matches vm_global_set priority) *) + let found_in_env = match f.vf_closure.vm_closure_env with + | Some env -> + let id = intern n in + let rec find_env e = + match Hashtbl.find_opt e.bindings id with + | Some v -> Some v + | None -> (match e.parent with Some p -> find_env p | None -> None) + in find_env env + | None -> None + in + match found_in_env with | Some v -> v | None -> - (* Walk closure env chain *) - let f = unwrap_frame frame_val in - let not_found () = - (* Try evaluator's primitive table *) + match Hashtbl.find_opt m.vm_globals n with + | Some v -> v + | None -> try prim_call n [] with _ -> - (* Try symbol resolve hook — transparent lazy module loading *) match !_symbol_resolve_hook with | Some hook -> (match hook n with | Some v -> v | None -> raise (Eval_error ("VM undefined: " ^ n))) | None -> raise (Eval_error ("VM undefined: " ^ n)) - in - (match f.vf_closure.vm_closure_env with - | Some env -> - let id = intern n in - let rec find_env e = - match Hashtbl.find_opt e.bindings id with - | Some v -> v - | None -> (match e.parent with Some p -> find_env p | None -> not_found ()) - in find_env env - | None -> not_found ()) let vm_global_set vm_val frame_val name v = let m = unwrap_vm vm_val in diff --git a/hosts/ocaml/sx_vm_ref.ml b/hosts/ocaml/sx_vm_ref.ml index 4c9e4c2a..e665d0e6 100644 --- a/hosts/ocaml/sx_vm_ref.ml +++ b/hosts/ocaml/sx_vm_ref.ml @@ -432,7 +432,7 @@ let rec vm_call vm f args = (* vm-resolve-ho-form *) and vm_resolve_ho_form vm name = - (if sx_truthy ((prim_call "=" [name; (String "for-each")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (List.iter (fun x -> ignore ((vm_call_external (vm) (f) ((List [x]))))) (sx_to_list coll); Nil)) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [name; (String "map")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (List (List.map (fun x -> (vm_call_external (vm) (f) ((List [x])))) (sx_to_list coll)))) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [name; (String "map-indexed")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (List (List.mapi (fun i x -> let i = Number (float_of_int i) in (vm_call_external (vm) (f) ((List [i; x])))) (sx_to_list coll)))) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [name; (String "filter")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (List (List.filter (fun x -> sx_truthy ((vm_call_external (vm) (f) ((List [x]))))) (sx_to_list coll)))) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [name; (String "reduce")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; init; coll] -> (fun f init coll -> (List.fold_left (fun acc x -> (vm_call_external (vm) (f) ((List [acc; x])))) init (sx_to_list coll))) f init coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [name; (String "some")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (Bool (List.exists (fun x -> sx_truthy ((vm_call_external (vm) (f) ((List [x]))))) (sx_to_list coll)))) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [name; (String "every?")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (Bool (List.for_all (fun x -> sx_truthy ((vm_call_external (vm) (f) ((List [x]))))) (sx_to_list coll)))) f coll | _ -> Nil)) else (raise (Eval_error (value_to_str (String (sx_str [(String "VM undefined: "); name])))))))))))) + (let _match_val = name in (if sx_truthy ((prim_call "=" [_match_val; (String "for-each")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (List.iter (fun x -> ignore ((vm_call_external (vm) (f) ((List [x]))))) (sx_to_list coll); Nil)) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [_match_val; (String "map")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (List (List.map (fun x -> (vm_call_external (vm) (f) ((List [x])))) (sx_to_list coll)))) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [_match_val; (String "map-indexed")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (List (List.mapi (fun i x -> let i = Number (float_of_int i) in (vm_call_external (vm) (f) ((List [i; x])))) (sx_to_list coll)))) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [_match_val; (String "filter")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (List (List.filter (fun x -> sx_truthy ((vm_call_external (vm) (f) ((List [x]))))) (sx_to_list coll)))) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [_match_val; (String "reduce")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; init; coll] -> (fun f init coll -> (List.fold_left (fun acc x -> (vm_call_external (vm) (f) ((List [acc; x])))) init (sx_to_list coll))) f init coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [_match_val; (String "some")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (Bool (List.exists (fun x -> sx_truthy ((vm_call_external (vm) (f) ((List [x]))))) (sx_to_list coll)))) f coll | _ -> Nil)) else (if sx_truthy ((prim_call "=" [_match_val; (String "every?")])) then (NativeFn ("\206\187", fun _args -> match _args with [f; coll] -> (fun f coll -> (Bool (List.for_all (fun x -> sx_truthy ((vm_call_external (vm) (f) ((List [x]))))) (sx_to_list coll)))) f coll | _ -> Nil)) else (raise (Eval_error (value_to_str (String (sx_str [(String "VM undefined: "); name]))))))))))))) (* vm-call-external *) and vm_call_external vm f args = @@ -440,7 +440,7 @@ and vm_call_external vm f args = (* vm-run *) and vm_run vm = - (let () = ignore ((String "Execute bytecode until all frames are consumed.")) in (let rec loop = (fun () -> (if sx_truthy ((Bool (not (sx_truthy ((empty_p ((vm_frames (vm))))))))) then (let frame = (first ((vm_frames (vm)))) in let rest_frames = (rest ((vm_frames (vm)))) in (let bc = (code_bytecode ((closure_code ((frame_closure (frame)))))) in let consts = (code_constants ((closure_code ((frame_closure (frame)))))) in (if sx_truthy ((prim_call ">=" [(frame_ip (frame)); (len (bc))])) then (vm_set_frames_b (vm) ((List []))) else (let () = ignore ((vm_step (vm) (frame) (rest_frames) (bc) (consts))) in (if sx_truthy ((is_nil ((get ((vm_globals_ref (vm))) ((String "__io_request")))))) then (loop ()) else Nil))))) else Nil)) in (loop ()))) + (let () = ignore ((String "Execute bytecode until all frames are done or IO suspension.")) in (let rec loop = (fun () -> (if sx_truthy ((Bool (not (sx_truthy ((empty_p ((vm_frames (vm))))))))) then (let frame = (first ((vm_frames (vm)))) in let rest_frames = (rest ((vm_frames (vm)))) in (let bc = (_> (frame) (frame_closure) (closure_code) (code_bytecode)) in let consts = (_> (frame) (frame_closure) (closure_code) (code_constants)) in (if sx_truthy ((prim_call ">=" [(frame_ip (frame)); (len (bc))])) then (vm_set_frames_b (vm) ((List []))) else (let () = ignore ((vm_step (vm) (frame) (rest_frames) (bc) (consts))) in (if sx_truthy ((is_nil ((get ((vm_globals_ref (vm))) ((String "__io_request")))))) then (loop ()) else Nil))))) else Nil)) in (loop ()))) (* vm-step *) and vm_step vm frame rest_frames bc consts =