ref: ad64b64a877a8ade76ab155b61931aa2f18a3ee5
parent: 64583452c2d9c394432b2490c67ea17875ea65aa
author: smazga <smazga@greymanlabs.com>
date: Fri Aug 28 10:21:40 EDT 2020
closer on the macro question
--- a/eval.ml
+++ b/eval.ml
@@ -26,21 +26,23 @@
T.Vector { T.value = List.map (fun x -> eval x env) xs; T.meta }| _ -> ast
-and preparse ast env =
- match ast with
- | T.List { T.value = s :: args } ->- (match
- try Env.get env s with
- | _ -> T.Nil
- with
- | T.Macro { T.value = sym; meta = meta } ->- let foo = Macro.expand ast env args sym meta in
- print_endline ("PREPARSE: " ^ (Printer.print foo true)); foo (* eval foo env *)- | _ -> ast)
- | _ -> ast
-
+(* and preparse ast env =
+ * print_endline ("preparse: " ^ Printer.print ast true);+ * match ast with
+ * | T.List { T.value = s :: args } ->+ * (match
+ * try Env.get env s with
+ * | _ -> T.Nil
+ * with
+ * | T.Macro { T.value = sym; meta } ->+ * let foo = Macro.expand ast env args sym meta in
+ * print_endline (" expanded: " ^ Printer.print foo true);+ * eval foo env
+ * | _ -> ast)
+ * | _ -> ast *)
and eval ast env =
- match preparse ast env with
+ (* match preparse ast env with *)
+ match ast with
| T.List { T.value = [] } -> ast(* Can this be replaced with a define-syntax thing? *)
| T.List
@@ -123,10 +125,15 @@
if Types.to_bool (eval cond env) then eval then_expr env else T.Nil
| T.List { T.value = [ T.Symbol { T.value = "quote" }; ast ] } -> ast | T.List { T.value = [ T.Symbol { T.value = "quasiquote" }; ast ] } ->- eval (quasiquote ast) env
+ eval (quasiquote ast) env
| T.List _ ->
(match eval_ast ast env with
| T.List { T.value = T.Proc { T.value = f } :: args } -> f args+ | T.List { T.value = T.Macro { T.value = sym; meta } :: args } ->+ (* eval (Macro.expand ast env args sym meta) env *)
+ let foo = Macro.expand ast env args sym meta in
+ print_endline (":::: " ^ Printer.print foo true);+ eval foo env
| _ as x ->
raise (Reader.Syntax_error ("'" ^ Printer.print x true ^ "' not a function")))| _ -> eval_ast ast env
--- a/m9.ml
+++ b/m9.ml
@@ -13,7 +13,6 @@
module T = Types.Types
let repl_env = Env.make (Some Core.base)
-
let nameplate = "Martian9 Scheme v0.1"
let read str = Reader.read str
let print exp = Printer.print exp true
--- a/macro.ml
+++ b/macro.ml
@@ -10,21 +10,54 @@
let rec is_matching_pattern sym pattern args matched =
match pattern, args with
- (* literals not handled, yet *)
- | ph :: pt, ah :: at -> print_endline " LIST <-> LIST";
- if (ph = "_" || (ph = (Printer.print sym true) && ph = (Printer.print ah true))) then is_matching_pattern sym pt at matched && true else (print_endline " ------> foo"; is_matching_pattern sym pt at matched)
- | ph :: pt, [] -> print_endline " LIST <-> []";
- if (ph = "_" || ph = (Printer.print sym true)) then is_matching_pattern sym pt [] matched && true else false
- | [], ah :: at -> print_endline " [] <-> LIST"; false
- | _, _ -> matched
+ (* literals and ellipses not handled, yet *)
+ | ph :: pt, ah :: at ->
+ print_endline " LIST <-> LIST";
+ if ph = "_" || (ph = Printer.print sym true && sym = ah)
+ then is_matching_pattern sym pt at matched && true
+ else (
+ print_endline (" ------> " ^ ph ^ " vs " ^ Printer.print ah true);+ is_matching_pattern sym pt at matched)
+ | ph :: pt, [] ->
+ print_endline " LIST <-> []";
+ if ph = "_" || ph = Printer.print sym true
+ then is_matching_pattern sym pt [] matched && true
+ else (List.hd pt = "...")
+ | [], ah :: at ->
+ print_endline " [] <-> LIST";
+ false
+ | _, _ -> matched
+;;
let lambdaize pattern template args =
match pattern, args with
+ | ph :: pt, ah :: at :: rest ->
+ print_endline "lambdaize: list list";
+ Reader.read
+ ("((lambda ("+ ^ Printer.stringify pt false
+ ^ ") ("+ ^ Printer.print template true
+ ^ ")"
+ ^ Printer.stringify args false
+ ^ "))")
| ph :: pt, ah :: at ->
- Reader.read ("(lambda (" ^ (Printer.stringify pt false) ^ ") (" ^ (Printer.print template true) ^ ")" ^ (Printer.stringify args false) ^ ")")+ print_endline "lambdaize: list short";
+ Reader.read ("((lambda (" ^ Printer.stringify pt true ^ ")"+ ^ Printer.print template true ^ ")"
+ ^ Printer.stringify args true ^ ")")
| ph :: pt, [] ->
- Reader.read ("((lambda (" ^ (Printer.stringify pt false) ^ ") " ^ (Printer.print template true) ^ "))")- | _ -> Reader.read ("((lambda () " ^ (Printer.print template true) ^ "))")+ print_endline "lambdaize: list empty";
+ Reader.read
+ ("((lambda ("+ ^ Printer.stringify pt false
+ ^ ") "
+ ^ Printer.print template true
+ ^ "))")
+ | _ ->
+ print_endline "lambdaize: empty";
+ Reader.read ("((lambda () " ^ Printer.print template true ^ "))")+;;
let rec expand ast env args sym meta =
print_endline ("\n\nTHIS IS A MACRO: " ^ Printer.print sym true);@@ -31,7 +64,6 @@
print_endline (" META: " ^ Printer.print meta true); print_endline (" ARGS: " ^ Printer.dump args); print_endline (" AST: " ^ Printer.print ast true);-
match meta with
| T.Map { T.value = m } ->(try
@@ -49,16 +81,48 @@
print_endline (" transform: " ^ Printer.print hd true);(match hd with
| T.List
- { T.value = [ T.List { T.value = pattern }; T.List { T.value = template } ] }- ->
- print_endline (" _ multi pattern: " ^ Printer.dump pattern); match_transform tl+ { T.value = [ T.List { T.value = pattern }; T.List { T.value = template } ]+ } ->
+ print_endline (" _ multi pattern: " ^ Printer.dump pattern);+ print_endline (" - template: " ^ Printer.dump template);+ print_endline
+ ("matched?: "+ ^
+ if is_matching_pattern
+ sym
+ (List.map (fun x -> Printer.print x true) pattern)
+ (Core.seq ast)
+ true
+ then "yes"
+ else "no");
+ if is_matching_pattern
+ sym
+ (List.map (fun x -> Printer.print x true) pattern)
+ (Core.seq ast)
+ true
+ then lambdaize pattern (Types.list template) args
+ else match_transform tl
| T.List { T.value = [ T.List { T.value = pattern }; atom ] } ->- print_endline (" _ single pattern: " ^ Printer.dump pattern);- print_endline ("matched?: " ^ (if is_matching_pattern sym (List.map (fun x -> Printer.print x true) pattern) args true then "yes" else "no"));- if is_matching_pattern sym (List.map (fun x -> Printer.print x true) pattern) args true
- then atom else match_transform tl
- (* then lambdaize pattern atom args else match_transform tl *)
- | _ -> T.Nil) (* errors? *)
+ print_endline (" _ single pattern: " ^ Printer.dump pattern);+ print_endline
+ ("matched?: "+ ^
+ if is_matching_pattern
+ sym
+ (List.map (fun x -> Printer.print x true) pattern)
+ (Core.seq ast)
+ true
+ then "yes"
+ else "no");
+ if is_matching_pattern
+ sym
+ (List.map (fun x -> Printer.print x true) pattern)
+ (Core.seq ast)
+ true
+ then lambdaize pattern atom args
+ else match_transform tl
+ | _ -> T.Nil)
+ (* errors? *)
| [] -> T.Nil
in
match_transform (Core.seq transformers)
@@ -65,3 +129,4 @@
with
| Not_found -> T.Nil)
| _ -> T.Nil
+;;
--- a/notes.org
+++ b/notes.org
@@ -35,3 +35,5 @@
- substitute args for non-literals (in order)
- compare result with ast - if it's a match, return a lamba with the matching args and the transformer
...but what about ellipsis??
+** Thoughts
+Eval seems too late to handle it, so maybe try to do expansion at read?
--
⑨