Add eval-rules.sx and sx_explain tool
Machine-readable SX semantics reference with 35 evaluation rules
covering literals, lookup, special forms, definitions, higher-order
forms, scopes, continuations, and reactive primitives.
New sx_explain MCP tool: query by form name ("let", "map") or
category ("special-form", "higher-order") to get pattern, rule,
effects, and examples.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -222,7 +222,10 @@ let setup_env () =
|
||||
(* Load harness *)
|
||||
(try load_sx_file e (Filename.concat spec_dir "harness.sx")
|
||||
with exn -> Printf.eprintf "[mcp] Warning: harness.sx load failed: %s\n%!" (Printexc.to_string exn));
|
||||
Printf.eprintf "[mcp] SX tree-tools + harness loaded\n%!";
|
||||
(* Load eval-rules *)
|
||||
(try load_sx_file e (Filename.concat spec_dir "eval-rules.sx")
|
||||
with exn -> Printf.eprintf "[mcp] Warning: eval-rules.sx load failed: %s\n%!" (Printexc.to_string exn));
|
||||
Printf.eprintf "[mcp] SX tree-tools + harness + eval-rules loaded\n%!";
|
||||
env := e
|
||||
|
||||
(* ------------------------------------------------------------------ *)
|
||||
@@ -1204,6 +1207,53 @@ let rec handle_tool name args =
|
||||
ignore (Unix.close_process_in ic);
|
||||
text_result (Buffer.contents buf))
|
||||
|
||||
| "sx_explain" ->
|
||||
let form_name = args |> member "name" |> to_string in
|
||||
let e = !env in
|
||||
let result = try
|
||||
let find_fn = env_get e "find-rule" in
|
||||
Sx_ref.cek_call find_fn (List [String form_name])
|
||||
with _ -> Nil in
|
||||
(match result with
|
||||
| Dict d ->
|
||||
let get_str k = match Hashtbl.find_opt d k with
|
||||
| Some (String s) -> s | Some v -> value_to_string v | None -> "" in
|
||||
let effects = match Hashtbl.find_opt d "effects" with
|
||||
| Some (List items) -> String.concat ", " (List.map value_to_string items)
|
||||
| Some Nil -> "none" | _ -> "none" in
|
||||
let examples = match Hashtbl.find_opt d "examples" with
|
||||
| Some (String s) -> " " ^ s
|
||||
| Some (List items) ->
|
||||
String.concat "\n" (List.map (fun ex -> " " ^ value_to_string ex) items)
|
||||
| _ -> " (none)" in
|
||||
text_result (Printf.sprintf "%s\n Category: %s\n Pattern: %s\n Effects: %s\n\n%s\n\nExamples:\n%s"
|
||||
(get_str "name") (get_str "category") (get_str "pattern") effects
|
||||
(get_str "rule") examples)
|
||||
| _ ->
|
||||
(* Try listing by category *)
|
||||
let cats_fn = try env_get e "rules-by-category" with _ -> Nil in
|
||||
let cat_results = try Sx_ref.cek_call cats_fn (List [String form_name]) with _ -> Nil in
|
||||
(match cat_results with
|
||||
| List items when items <> [] ->
|
||||
let lines = List.map (fun rule ->
|
||||
match rule with
|
||||
| Dict rd ->
|
||||
let name = match Hashtbl.find_opt rd "name" with Some (String s) -> s | _ -> "?" in
|
||||
let pattern = match Hashtbl.find_opt rd "pattern" with Some (String s) -> s | _ -> "" in
|
||||
Printf.sprintf " %-16s %s" name pattern
|
||||
| _ -> " " ^ value_to_string rule
|
||||
) items in
|
||||
text_result (Printf.sprintf "Category: %s (%d rules)\n\n%s"
|
||||
form_name (List.length items) (String.concat "\n" lines))
|
||||
| _ ->
|
||||
(* List all categories *)
|
||||
let all_cats = try Sx_ref.cek_call (env_get e "rule-categories") Nil with _ -> Nil in
|
||||
let cat_str = match all_cats with
|
||||
| List items -> String.concat ", " (List.filter_map (fun v ->
|
||||
match v with String s -> Some s | _ -> None) items)
|
||||
| _ -> "?" in
|
||||
error_result (Printf.sprintf "No rule found for '%s'. Categories: %s" form_name cat_str)))
|
||||
|
||||
| _ -> error_result ("Unknown tool: " ^ name)
|
||||
|
||||
and write_edit file result =
|
||||
@@ -1276,6 +1326,8 @@ let tool_definitions = `List [
|
||||
[("expr", `Assoc [("type", `String "string"); ("description", `String "SX expression to trace")]);
|
||||
("file", `Assoc [("type", `String "string"); ("description", `String "Optional .sx file to load for definitions")]);
|
||||
("max_steps", `Assoc [("type", `String "integer"); ("description", `String "Max CEK steps to show (default: 200)")])] ["expr"];
|
||||
tool "sx_explain" "Explain SX evaluation rules. Pass a form name (if, let, map, ...) or category (literal, special-form, higher-order, ...)."
|
||||
[("name", `Assoc [("type", `String "string"); ("description", `String "Form name or category to explain")])] ["name"];
|
||||
tool "sx_deps" "Dependency analysis for a component or file. Shows all referenced symbols and where they're defined."
|
||||
[file_prop;
|
||||
("name", `Assoc [("type", `String "string"); ("description", `String "Specific define/defcomp/defisland to analyze")]);
|
||||
|
||||
Reference in New Issue
Block a user