Unify scope mechanism: one world (hashtable stacks everywhere)
Replace continuation-based scope frames with hashtable stacks for all scope operations. The CEK evaluator's scope/provide/context/emit!/emitted now use scope-push!/pop!/peek/emit! primitives (registered in sx_primitives table) instead of walking continuation frames. This eliminates the two-world problem where the aser used hashtable stacks (scope-push!/pop!) but eval-expr used continuation frames (ScopeFrame/ScopeAccFrame). Now both paths share the same mechanism. Benefits: - scope/context works inside eval-expr calls (e.g. (str ... (context x))) - O(1) scope lookup vs O(n) continuation walking - Simpler — no ScopeFrame/ScopeAccFrame/ProvideFrame creation/dispatch - VM-compiled code and CEK code both see the same scope state Also registers scope-push!/pop!/peek/emit!/collect!/collected/ clear-collected! as real primitives (sx_primitives table) so the transpiled evaluator can call them directly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -129,6 +129,20 @@ let io_counter = ref 0
|
||||
scope-push!/pop!) and step-sf-context (via get-primitive "scope-peek"). *)
|
||||
let _scope_stacks : (string, value list) Hashtbl.t = Hashtbl.create 8
|
||||
|
||||
let () = Sx_primitives.register "scope-push!" (fun args ->
|
||||
match args with
|
||||
| [String name; value] ->
|
||||
let stack = try Hashtbl.find _scope_stacks name with Not_found -> [] in
|
||||
Hashtbl.replace _scope_stacks name (value :: stack); Nil
|
||||
| _ -> Nil)
|
||||
|
||||
let () = Sx_primitives.register "scope-pop!" (fun args ->
|
||||
match args with
|
||||
| [String name] ->
|
||||
let stack = try Hashtbl.find _scope_stacks name with Not_found -> [] in
|
||||
(match stack with _ :: rest -> Hashtbl.replace _scope_stacks name rest | [] -> ()); Nil
|
||||
| _ -> Nil)
|
||||
|
||||
let () = Sx_primitives.register "scope-peek" (fun args ->
|
||||
match args with
|
||||
| [String name] ->
|
||||
@@ -160,6 +174,22 @@ let () = Sx_primitives.register "collected" (fun args ->
|
||||
(match stack with List items :: _ -> List items | _ -> List [])
|
||||
| _ -> List [])
|
||||
|
||||
let () = Sx_primitives.register "scope-emit!" (fun args ->
|
||||
match args with
|
||||
| [String name; value] ->
|
||||
let stack = try Hashtbl.find _scope_stacks name with Not_found -> [] in
|
||||
(match stack with
|
||||
| List items :: rest ->
|
||||
Hashtbl.replace _scope_stacks name (List (items @ [value]) :: rest)
|
||||
| Nil :: rest ->
|
||||
Hashtbl.replace _scope_stacks name (List [value] :: rest)
|
||||
| [] ->
|
||||
(* Lazy root scope *)
|
||||
Hashtbl.replace _scope_stacks name [List [value]]
|
||||
| _ :: _ -> ());
|
||||
Nil
|
||||
| _ -> Nil)
|
||||
|
||||
let () = Sx_primitives.register "clear-collected!" (fun args ->
|
||||
match args with
|
||||
| [String name] ->
|
||||
|
||||
Reference in New Issue
Block a user