shithub: martian9

Download patch

ref: dc596842d658ab664a025d4e98c89b50cac465c4
parent: b6f4824d97a68ecfa763e1edcbef629ff3ba1cfc
author: McKay Marston <[email protected]>
date: Fri Nov 20 14:56:03 EST 2020

macro update

--- a/env.ml
+++ b/env.ml
@@ -12,13 +12,14 @@
 
 let set env sym value =
   match sym with
-  | T.Symbol { T.value = key } -> (* print_endline ("Env.set: " ^ key); *) env.data := Data.add key value !(env.data)
+  | T.Symbol { T.value = key; T.meta = _ } ->
+    (* print_endline ("Env.set: " ^ key); *) env.data := Data.add key value !(env.data)
   | _ -> raise (Invalid_argument "set: not a symbol")
 ;;
 
 let rec find env sym =
   match sym with
-  | T.Symbol { T.value = key } ->
+  | T.Symbol { T.value = key; T.meta = _ } ->
     if Data.mem key !(env.data)
     then Some env
     else (
@@ -30,9 +31,17 @@
 
 let get env sym =
   match sym with
-  | T.Symbol { T.value = key } ->
+  | T.Symbol { T.value = key; T.meta = _ } ->
     (match find env sym with
     | Some found_env -> Data.find key !(found_env.data)
     | None -> raise (Runtime_error ("unknown symbol '" ^ key ^ "'")))
   | _ -> raise (Invalid_argument "get: not a symbol")
 ;;
+
+(* let string_of_env env =
+ *   let string = ref "" in
+ *   (match env with
+ *   | { outer; data = data } ->
+ *      Data.iter (fun k v -> string := !string ^ "[" ^ k ^ "|" ^ v ^ "]") !data;
+ *   | _ -> ());
+ *   !string *)
--- a/eval.ml
+++ b/eval.ml
@@ -16,51 +16,15 @@
   (* print_endline ("EVAL_AST: " ^ Printer.print ast true); *)
   match ast with
   | T.Symbol s -> Env.get env ast
-  (* | T.Symbol s -> let foo = Env.get env ast in(\* (match Env.get env ast with *\)
-   *                 print_endline ("EVAL_AST: " ^ Printer.print foo true);
-   *                 (match foo with
-   *                  | T.Macro { T.value = sym; meta } -> raise (Utils.Syntax_error ("EVAL_AST MACRO: ast: " ^ Printer.print ast true))
-   *                  | T.List { T.value = xs; meta } -> raise (Utils.Syntax_error "EVAL_AST LIST")
-   *                  | _ as x -> print_endline ("EVAL_AST UNKNOWN: " ^ Printer.print ast true ^ ":" ^ Printer.print x true); foo)
-   *)
   | T.List { T.value = xs; T.meta } ->
     (match
        try Env.get env (List.hd xs) with
        | _ -> T.Nil
      with
-    (* disabled for macro_read development *)
-
-    (* | T.Macro { T.value = sym; meta } as om ->
-     *   print_endline ("  EVAL_AST: the rest: " ^ Printer.dump (List.tl xs));
-     *   print_endline ("  EVAL_AST: AST: " ^ Printer.print ast true);
-     *   let foo = Macro.expand ast env (List.tl xs) sym meta in
-     *   print_endline (" expanded: " ^ Printer.print foo true);
-     *   T.List { T.value = [ om; foo ]; T.meta } *)
-
-    (* T.List { T.value = [foo]; T.meta } *)
-    (* T.List { T.value = [ Types.symbol (Printer.print sym true); foo; T.List { T.value = (List.tl xs); T.meta } ]; T.meta } *)
-    (* T.List { T.value = [eval foo env]; T.meta } *)
-    (* eval foo env *)
-    (* raise (Utils.Syntax_error ("EVAL_AST MACRO: ast: " ^ Printer.print ast true)) *)
     | _ -> T.List { T.value = List.map (fun x -> eval x env) xs; T.meta })
-  (* | T.List { T.value = xs; T.meta } -> T.List { T.value = List.map (fun x -> eval x env) xs; T.meta } *)
   | T.Vector { T.value = xs; T.meta } -> T.Vector { T.value = List.map (fun x -> eval x env) xs; T.meta }
   | _ -> 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 =
   print_endline ("AST: " ^ Printer.print ast true);
   match ast with
@@ -72,6 +36,8 @@
     let func =
       eval (Reader.read ("(lambda (" ^ Printer.stringify rest false ^ ") " ^ Printer.print body true ^ ")")) env
     in
+    print_endline ("DEFINE: " ^ Printer.print sym true);
+    print_endline ("  => " ^ "(lambda (" ^ Printer.stringify rest false ^ ") " ^ Printer.print body true ^ ")");
     Env.set env sym func;
     func
   | T.List { T.value = [ T.Symbol { T.value = "define" }; key; expr ] } ->
@@ -78,13 +44,6 @@
     let value = eval expr env in
     Env.set env key value;
     value
-  (* | T.List { T.value = [ T.Symbol { T.value = "define-syntax" }; keyword; T.List { T.value = macro } ] } ->
-   *   (match macro with
-   *   | _ :: literals :: groups ->
-   *     let macro_entry = Types.macro (Printer.print keyword true) literals (Types.list groups) in
-   *     Env.set env keyword macro_entry;
-   *     macro_entry
-   *   | _ -> T.Nil) *)
   | T.List { T.value = [ T.Symbol { T.value = "lambda" }; T.Vector { T.value = arg_names }; expr ] }
   | T.List { T.value = [ T.Symbol { T.value = "lambda" }; T.List { T.value = arg_names }; expr ] } ->
     Types.proc (function args ->
@@ -96,7 +55,14 @@
             Env.set sub_env name arg;
             bind_args names args
           | [], [] -> ()
-          | _ -> raise (Utils.Syntax_error ("wrong parameter count for lambda: " ^ Printer.dump arg_names))
+          | _ ->
+            raise
+              (Utils.Syntax_error
+                 ("wrong parameter count for lambda: arg_names:["
+                 ^ Printer.dump arg_names
+                 ^ "]  args:["
+                 ^ Printer.dump args
+                 ^ "]"))
         in
         bind_args arg_names args;
         eval expr sub_env)
@@ -127,11 +93,6 @@
     | T.List { T.value = T.Macro { T.value = _ } :: macro :: _ } ->
       print_endline "MACRO EVALUATION";
       eval macro env
-    (* | 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 (Utils.Syntax_error ("'" ^ Printer.print x true ^ "' not a function")))
   | _ -> eval_ast ast env
 ;;
--- a/macro.ml
+++ b/macro.ml
@@ -83,115 +83,6 @@
   | _ -> "(" ^ Printer.dump pattern ^ ") " ^ Printer.print template true ^ ")"
 ;;
 
-(* let lambdaize pattern template args =
- *   match pattern, args with
- *   | ph :: pt, ah :: at :: rest ->
- *     let expr = "((lambda " ^ ellipsis pt template args ^ Printer.stringify args false ^ ")" in
- *     print_endline ("  lambdaize list list: " ^ expr);
- *     Reader.read expr
- *   | ph :: pt, ah :: at ->
- *     let expr =
- *       "((lambda ("
- *       ^ Printer.stringify pt true
- *       ^ ")"
- *       ^ Printer.print template true
- *       ^ ")"
- *       ^ Printer.stringify args true
- *       ^ ")"
- *     in
- *     print_endline ("  lambdaize short list: " ^ expr);
- *     Reader.read expr
- *   | ph :: pt, [] ->
- *     let expr = "((lambda (" ^ Printer.stringify pt false ^ ") " ^ Printer.print template false ^ "))" in
- *     print_endline ("  lambdaize empty list: " ^ expr);
- *     Reader.read expr
- *   | _ ->
- *     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);
- *   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 } ->
- *     ((\* let literals = Types.M9map.find Types.macro_literals m in *\)
- *     try
- *       let transformers = Types.M9map.find Types.macro_transformers m in
- *       print_endline
- *         ("  -- EVAL_MACRO: "
- *         (\*  ^ " literals: "
- *          * ^ Printer.print literals true *\)
- *         ^ "     transformers: "
- *         ^ Printer.print transformers true);
- *       let rec match_transform transforms =
- *         match transforms with
- *         | hd :: tl ->
- *           (\* 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";
- *              * print_endline ("     - template: " ^ Printer.dump template); *\)
- *             print_endline
- *               ("      matched (m)?: "
- *               ^ (if is_matching_pattern sym (List.map (fun x -> Printer.print x true) pattern) (Core.seq ast) true
- *                 then "yes"
- *                 else "no")
- *               ^ " ::> "
- *               ^ Printer.dump pattern);
- *             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"; *\)
- *             print_endline
- *               ("      matched (s)?: "
- *               ^ (if is_matching_pattern sym (List.map (fun x -> Printer.print x true) pattern) (Core.seq ast) true
- *                 then "yes"
- *                 else "no")
- *               ^ " ::> "
- *               ^ Printer.dump pattern);
- *             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
- *           | _ -> raise (Utils.Syntax_error "Unknown"))
- *           (\* errors? *\)
- *         | [] -> raise (Utils.Syntax_error ("No matching transform for macro: '" ^ Printer.print sym true))
- *       in
- *       match_transform (Core.seq transformers)
- *     with
- *     | Not_found -> raise (Utils.Syntax_error ("'" ^ Printer.print sym true ^ "' is not a known macro")))
- *   | _ -> raise (Utils.Syntax_error "syntax error with defined macro")
- * ;; *)
-
-(* let rec parse ast env args sym meta =
- *   print_endline("\n\nREADING MACRO: " ^ Printer.print sym true);
- *   match meta with
- *   | T.Map { T.value = m } ->
- *      (try
- *         let transformers = Types.M9map.find Types.macro_transformers m in
- *         let rec match_transform transforms =
- *           match transforms with
- *           | hd :: tl ->
- *              (match hd with
- *               | T.List { T.value = [ T.List { T.value = pattern }; T.List {T.value = template } ] } ->
- *                  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 ] } ->
- *                  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
- *               | _ -> raise (Utils.Syntax_error "no transform match"))
- *           | [] -> raise (Utils.Syntax_error ("No matching transform for macro: '" ^ Printer.print sym true))
- *         in
- *         match_transform (Core.seq transformers)
- *       with
- *       | Not_found -> raise (Utils.Syntax_error ("'" ^ Printer.print sym true ^ "' is not a known macro")))
- *   | _ -> raise (Utils.Syntax_error "syntax error with defined macro") *)
-
 let rec parse ast macros =
   print_endline ("\n\nREADING MACRO: " ^ String.concat " " ast);
   match ast with
@@ -199,33 +90,6 @@
   | macro :: tokens -> print_endline ("   macro: " ^ macro)
 ;;
 
-(* let add_variant sym variant env =
- *   let new_variant = gen_sym sym in
- *   match
- *     try Env.get env (Types.symbol sym) with
- *     | _ -> T.Nil
- *   with
- *   | T.Macro { T.value = sym; meta } ->
- *      (match meta with
- *       | T.Map { T.value = m } ->
- *          let variants = ref (Types.M9map.find Types.macro_variants m) in
- *          Types.M9map.add new_variant variant !variants;
- *          print_endline ("ADD_VARIANT: " ^ (Printer.print new_variant true) ^ ": " ^ Printer.print meta true);
- *          print_endline ("    variants: " ^ Printer.print !variants true)
- *       | _ -> raise (Utils.Runtime_error ("macro " ^ (Printer.print sym true) ^ " is missing its variants")))
- *   | _ -> raise (Utils.Syntax_error "add_variant botch") *)
-
-(* let macro = Env.get env (Types.symbol sym) in
- * let variants = Types.M9map.find Types.macro_variants macro.meta *)
-(* match
- *   try Env.get env (Types.symbol sym) with
- *   | _ -> T.Nil
- * with
- * | T.Macro { T.value = sym; meta } ->
- *    let variants = Types.M9map.find Types.macro_variants meta in
- *    Types.M9map.add Types.macro_variants (new_variant :: variants) meta
- * | _ -> raise (Utils.Runtime_error ("wayward variant of " ^ sym ^ ": " ^ variant)) *)
-
 let generate_variants sym literals patterns =
   let symbol = Printer.print sym true in
   let variants = ref Types.M9map.empty in
@@ -246,47 +110,27 @@
 let match_variant macro args =
   let vmatch = ref "" in
   (match macro with
-   | T.Map { T.value = meta } ->
-      (match Types.M9map.find Types.macro_variants meta with
-       | T.Map { T.value = variant_list } ->
-          Types.M9map.iter
-            (fun k v ->
-              print_endline (Printer.print k true ^ ": " ^ Printer.print v true);
-              match v with
-              | T.List { T.value = T.List { T.value = x } :: z } ->
-                 print_endline
-                   (" >>>> [" ^ string_of_int (List.length args) ^ "|"
-                    ^ string_of_int (List.length x) ^ "] "
-                    ^ Printer.dump x ^ " :: " ^ Printer.dump z);
-                 if List.length args = List.length x
-                 then vmatch := (Printer.print (List.hd x) true)
-              | _ -> ())
-            variant_list
-       | _ -> ())
-   | _ -> ());
+  | T.Map { T.value = meta } ->
+    (match Types.M9map.find Types.macro_variants meta with
+    | T.Map { T.value = variant_list } ->
+      Types.M9map.iter
+        (fun k v ->
+          print_endline (Printer.print k true ^ ": " ^ Printer.print v true);
+          match v with
+          | T.List { T.value = T.List { T.value = x } :: z } ->
+            print_endline
+              (" >>>> ["
+              ^ string_of_int (List.length args)
+              ^ "|"
+              ^ string_of_int (List.length x)
+              ^ "] "
+              ^ Printer.dump x
+              ^ " :: "
+              ^ Printer.dump z);
+            if List.length args = List.length x then vmatch := Printer.print (List.hd x) true
+          | _ -> ())
+        variant_list
+    | _ -> ())
+  | _ -> ());
   !vmatch
 ;;
-
-(* match meta with
- * | T.Map { T.value = m } ->
- *    (try
- *       let transformers = Types.M9map.find Types.macro_transformers m in
- *       let rec match_transform transforms =
- *         match transforms with
- *         | hd :: tl ->
- *            (match hd with
- *             | T.List { T.value = [ T.List { T.value = pattern }; T.List {T.value = template } ] } ->
- *                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 ] } ->
- *                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
- *             | _ -> raise (Utils.Syntax_error "no transform match"))
- *         | [] -> raise (Utils.Syntax_error ("No matching transform for macro: '" ^ Printer.print sym true))
- *       in
- *       match_transform (Core.seq transformers)
- *     with
- *     | Not_found -> raise (Utils.Syntax_error ("'" ^ Printer.print sym true ^ "' is not a known macro")))
- * | _ -> raise (Utils.Syntax_error "syntax error with defined macro") *)
--- a/notes.org
+++ b/notes.org
@@ -44,6 +44,7 @@
 * Macros
 ** and
 (define-syntax and (syntax-rules ()
-  ((and) #t)
-  ((and test) test) ((and test1 test2 ...)
-    (if test1 (and test2 ...) #f))))
+  ((_) #t)
+  ((_ test) test)
+  ((_ test1 test2 ...)
+    (if test1 (_ test2 ...) #f))))
--- a/printer.ml
+++ b/printer.ml
@@ -2,11 +2,11 @@
 
 let meta obj =
   match obj with
-  | T.List { T.meta } -> meta
-  | T.Proc { T.meta } -> meta
-  | T.Symbol { T.meta } -> meta
-  | T.Vector { T.meta } -> meta
-  | T.Record { T.meta } -> meta
+  | T.List { T.value = _; T.meta } -> meta
+  | T.Proc { T.value = _; T.meta } -> meta
+  | T.Symbol { T.value = _; T.meta } -> meta
+  | T.Vector { T.value = _; T.meta } -> meta
+  | T.Record { T.value = _; T.meta } -> meta
   | _ -> T.Nil
 ;;
 
@@ -17,17 +17,17 @@
   | T.Bool false -> "#f"
   | T.Char c -> "#\\" ^ Char.escaped c
   | T.Nil -> "nil"
-  | T.Macro { T.value = xs } -> "#<macro>" ^ print xs r
-  | T.Map { T.value = xs } ->
+  | T.Macro { T.value = xs; T.meta = _ } -> "#<macro>" ^ print xs r
+  | T.Map { T.value = xs; T.meta = _ } ->
     "{" ^ Types.M9map.fold (fun k v s -> s ^ (if s = "" then "" else " ") ^ print k r ^ " " ^ print v r) xs "" ^ "}"
   | T.Unspecified -> "#unspecified"
   | T.Eof_object -> "#eof"
   (* | T.Pair ({ T.value = one }, { T.value = two }) -> "(" ^ (print one readable) ^ " . " ^ (print two readable) ^ ")" *)
-  | T.Proc p -> "#<proc>"
-  | T.Symbol { T.value = s } -> s
-  | T.Bytevector bv -> "<bytevector unsupported>"
+  | T.Proc _ -> "#<proc>"
+  | T.Symbol { T.value = s; T.meta = _ } -> s
+  | T.Bytevector _ -> "<bytevector unsupported>"
   | T.Number n -> if Types.is_float n.value then string_of_float n.value else string_of_int (int_of_float n.value)
-  | T.Port p -> "<port unsupported>"
+  | T.Port _ -> "<port unsupported>"
   | T.String s ->
     if r
     then
@@ -40,9 +40,9 @@
           s
       ^ "\""
     else s
-  | T.List { T.value = xs } -> "(" ^ stringify xs r ^ ")"
-  | T.Vector { T.value = v } -> "#(" ^ stringify v r ^ ")"
-  | T.Record r -> "<record unsupported>"
+  | T.List { T.value = xs; T.meta = _ } -> "(" ^ stringify xs r ^ ")"
+  | T.Vector { T.value = v; T.meta = _ } -> "#(" ^ stringify v r ^ ")"
+  | T.Record _ -> "<record unsupported>"
 
 and stringify obj human =
   String.concat
--- a/reader.ml
+++ b/reader.ml
@@ -87,21 +87,23 @@
       try Env.get registered_macros (Types.symbol (List.nth list_reader.tokens 1)) with
       | _ -> T.Nil
     with
-    | T.Macro { T.value = sym; meta } ->
-       print_endline ("XXXX MACRO FOUND");
-       let rec collect_args tokens args =
-         match tokens with
-         | [ t ] -> args @ [ t ]
-         | t :: ts -> if t = eol then args else collect_args ts args @ [ t ]
-         | _ -> []
-       in
-       let args = collect_args (List.tl list_reader.tokens) [] in
-       print_endline ("<><><><>: " ^ Macro.match_variant meta args)
+    | T.List { T.value = xs; T.meta } ->
+      print_endline "XXXX MACRO FOUND";
+      let rec collect_args tokens args =
+        match tokens with
+        | [ t ] -> args @ [ t ]
+        | t :: ts -> if t = eol then args else collect_args ts args @ [ t ]
+        | _ -> []
+      in
+      let args = collect_args (List.tl list_reader.tokens) [] in
+      print_endline ("<><><> args: " ^ String.concat " " args);
+      print_endline ("<><><><>: " ^ Macro.match_variant meta args)
     | _ -> ());
   match list_reader.tokens with
-  | [] -> print_endline ("ERROR: " ^ Printer.dump list_reader.list_form);
-          raise (Utils.Syntax_error ("unterminated '" ^ eol ^ "'"))
-  | token :: [] -> { list_form = list_reader.list_form; tokens = [")"] }
+  | [] ->
+    print_endline ("ERROR: " ^ Printer.dump list_reader.list_form);
+    raise (Utils.Syntax_error ("unterminated '" ^ eol ^ "'"))
+  | [ token ] -> { list_form = list_reader.list_form; tokens = [ ")" ] }
   | token :: tokens ->
     if Str.string_match (Str.regexp eol) token 0
     then { list_form = list_reader.list_form; tokens }
@@ -138,8 +140,10 @@
       Env.set registered_macros sym macro_entry;
       Types.M9map.iter
         (fun k v ->
-          print_endline ("   >>> " ^ Printer.print k true ^ ":  " ^ String.concat " " (fix_pattern k (Printer.print v true)));
-          macro := !macro @ (fix_pattern k (Printer.print v true)))
+          print_endline
+            ("   >>> " ^ Printer.print k true ^ ":  " ^ String.concat " " (fix_pattern k (Printer.print v true)));
+          macro := !macro @ fix_pattern k (Printer.print v true);
+          Env.set registered_macros k (read_form (fix_pattern k (Printer.print v true))).form)
         variants
     | _ -> raise (Utils.Syntax_error "read_macro botch"))
   | _ as x -> print_endline ("  last rest: " ^ Printer.dump x));
--- a/types.ml
+++ b/types.ml
@@ -37,11 +37,10 @@
 
 and M9map : (Map.S with type key = Value.t) = Map.Make (Value)
 
-let to_bool x =
-  match x with
-  | Types.Nil | Types.Bool false -> false
-  | _ -> true
-;;
+(* let to_bool x =
+ *   match x with
+ *   | Types.Nil | Types.Bool false -> false
+ *   | _ -> true *)
 
 type m9type = Value.t