shithub: martian9

Download patch

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?