shithub: martian9

Download patch

ref: 8b4ebe50739d76ce9591716e394ca68194f22245
parent: dc596842d658ab664a025d4e98c89b50cac465c4
author: McKay Marston <[email protected]>
date: Wed Nov 25 15:25:35 EST 2020

about to make big changes

--- a/macro.ml
+++ b/macro.ml
@@ -1,3 +1,13 @@
+(* The ⟨pattern⟩ in a ⟨syntax rule⟩ is a list ⟨pattern⟩ whose first element is an identifier.
+ * A ⟨pattern⟩ is either an identifier, a constant, or one of the following
+ *   (⟨pattern⟩ ...)
+ *     ((_) #t) => ⟨pattern⟩: (_), ...: #t   
+ *   (⟨pattern⟩ ⟨pattern⟩ ... . ⟨pattern⟩)
+ *   (⟨pattern⟩ ... ⟨pattern⟩ ⟨ellipsis⟩ ⟨pattern⟩ ...) (⟨pattern⟩ ... ⟨pattern⟩ ⟨ellipsis⟩ ⟨pattern⟩ ... . ⟨pattern⟩)
+ *   #(⟨pattern⟩ ...) => same, only vector
+ *   #(⟨pattern⟩ ... ⟨pattern⟩ ⟨ellipsis⟩ ⟨pattern⟩ ...)
+ *)
+
 module T = Types.Types
 
 let gen_sym root =
@@ -27,13 +37,13 @@
     if ph = "_" || ph = Printer.print sym true
     then is_matching_pattern sym pt [] matched && true
     else ph = "..." || List.hd pt = "..."
-  | [], ah :: at ->
+  | [], _ :: _ ->
     (* print_endline "    [] <-> LIST"; *)
     false
   | _, _ -> matched
 ;;
 
-let rec ellipsis pattern template args =
+let ellipsis pattern template args =
   let has_ellipsis =
     try
       ignore (Str.search_forward (Str.regexp "...") (Printer.stringify pattern true) 0);
@@ -43,6 +53,7 @@
   in
   let ellipsis_substitutions = ref [] in
   let missing = List.length args - List.length pattern + if has_ellipsis then 1 else 0 in
+  print_endline ("args: " ^ String.concat " " (List.map (fun x -> Printer.print x true) args));
   print_endline ("missing: " ^ string_of_int missing);
   (* print_endline (" NEED TO ADD " ^ string_of_int missing ^ " PLACEHOLDERS"); *)
   match missing with
@@ -49,7 +60,7 @@
   | _ when missing = 0 || missing > 0 ->
     (* add arguments *)
     print_endline ("ADD " ^ string_of_int missing ^ " arguments");
-    for i = 1 to missing do
+    for _ = 1 to missing do
       ellipsis_substitutions := !ellipsis_substitutions @ [ Printer.print (gen_sym "x") true ]
     done;
     let pattern_str =
@@ -62,35 +73,102 @@
       Str.global_replace
         (Str.regexp "\\.\\.\\.")
         (String.concat " " !ellipsis_substitutions)
-        (Printer.print template true)
+        (Printer.stringify template true)
     in
     (* let args_str = Printer.stringify args true in *)
     (* print_endline ("ellipsis: template: " ^ template_str ^ "  args: " ^ args_str); *)
     "(" ^ pattern_str ^ ") " ^ template_str ^ ")"
-  | _ when missing < 0 ->
-    (* remove ellipsis and arg *)
-    print_endline "REMOVE arguments";
-    (* let rgx = Str.regexp "[a-zA-Z0-9]+ \\.\\.\\." in *)
-    let rgx = Str.regexp "[a-zA-Z0-9]+ \\.\\.\\." in
-    let pattern_str = Str.global_replace rgx "" (Printer.stringify pattern true) in
-    let template_str = Str.global_replace rgx "" (Printer.stringify pattern true) in
-    print_endline ("  pattern:  " ^ Printer.dump pattern);
-    print_endline ("    pattern_str:  " ^ pattern_str);
-    print_endline ("  template: " ^ Printer.print template true);
-    print_endline ("    template_str: " ^ template_str);
-    print_endline ("(" ^ pattern_str ^ ") " ^ template_str ^ ")");
+  (* | _ when missing < 0 ->
+   *   (\* remove ellipsis and arg *\)
+   *   print_endline "REMOVE arguments";
+   *   (\* let rgx = Str.regexp "[a-zA-Z0-9]+ \\.\\.\\." in *\)
+   *   let rgx = Str.regexp "[a-zA-Z0-9]+ \\.\\.\\." in
+   *   let pattern_str = Str.global_replace rgx "" (Printer.stringify pattern true) in
+   *   let template_str = Str.global_replace rgx "" (Printer.stringify pattern true) in
+   *   print_endline ("  pattern:  " ^ Printer.dump pattern);
+   *   print_endline ("    pattern_str:  " ^ pattern_str);
+   *   print_endline ("  template: " ^ Printer.dump template);
+   *   print_endline ("    template_str: " ^ template_str);
+   *   print_endline ("(" ^ pattern_str ^ ") " ^ template_str ^ ")");
+   *   "(" ^ pattern_str ^ ") " ^ template_str ^ ")" *)
+  | _ -> "(" ^ Printer.dump pattern ^ ") " ^ Printer.dump template ^ ")"
+;;
+
+let sanitize_macro pattern template =
+  try
+    ignore (Str.search_forward (Str.regexp "...") (Printer.stringify pattern true) 0);
+    let substitution = Printer.print (gen_sym "x") true in
+    let pattern_str =
+      Str.global_replace
+        (Str.regexp "\\.\\.\\.")
+        substitution
+        (Printer.stringify pattern true)
+    in
+    let template_str =
+      Str.global_replace
+        (Str.regexp "\\.\\.\\.")
+        substitution
+        (Printer.stringify template true)
+    in
+    (* let args_str = Printer.stringify args true in *)
+    (* print_endline ("ellipsis: template: " ^ template_str ^ "  args: " ^ args_str); *)
     "(" ^ pattern_str ^ ") " ^ template_str ^ ")"
-  | _ -> "(" ^ Printer.dump pattern ^ ") " ^ Printer.print template true ^ ")"
+  with
+  | Not_found -> "(" ^ Printer.dump pattern ^ ") " ^ Printer.dump template ^ ")"
 ;;
 
-let rec parse ast macros =
+let parse ast _ =
   print_endline ("\n\nREADING MACRO: " ^ String.concat " " ast);
   match ast with
   | [] -> raise End_of_file
-  | macro :: tokens -> print_endline ("   macro: " ^ macro)
+  | macro :: _ -> print_endline ("   macro: " ^ macro)
 ;;
 
-let generate_variants sym literals patterns =
+let hack_ellipsis prefix clause =
+  let clauses = ref [] in
+  (match clause with
+  (* ((_ test1 test2 ...) (if test1 (_ test2 ...) #f)) *)
+  (* | T.List { T.value = [ T.List { T.value = pattern; meta = _ }; T.List {T.value = [ transform ]; meta = _ } ]; meta = _ } -> *)
+  | T.List { T.value = [ T.List { T.value = pattern; meta = _ }; T.List { T.value = transform; meta = _ } ]; meta = _ }
+    ->
+    let args = ref [] in
+    for _ = 1 to 5 do
+      args := !args @ [ gen_sym prefix ];
+      print_endline ("HAXXOR: " ^ prefix ^ ":: " ^ Printer.dump pattern ^ " :: " ^ Printer.dump transform);
+      clauses := !clauses @ [ sanitize_macro pattern transform !args ]
+    done
+  (* needs to match ((_) #t) : LIST(LIST() ATOM) *)
+  | T.List { T.value = [ T.List { T.value = pattern; meta = _ }; atom ]; meta = _ } ->
+    print_endline ("FOUND CLAUSE WITH ATOM: " ^ Printer.print atom true ^ "   pattern: " ^ Printer.dump pattern)
+  | _ as x -> print_endline ("nope: " ^ Printer.print x true));
+  !clauses
+;;
+
+(* print_endline ("   head: " ^ Printer.print (List.hd clause) true);
+ * print_endline ("   tail: " ^ Printer.dump (List.tl clause)); *)
+(* print_endline ("H4CK3LL!P5!5: " ^ Printer.print (gen_sym prefix) true ^ ": " ^ Printer.dump clause); *)
+(* print_endline ("H4CK3LL!P5!5: " ^ Printer.print (gen_sym prefix) true ^ ": " ^ Printer.print clause true); *)
+(* clause *)
+
+(* this is a dirty hack *)
+let generate_patterns sym clauses =
+  let prefix = Printer.print sym true in
+  let sanitized = ref [] in
+  let rec sanitize_clauses unsanitized =
+    match unsanitized with
+    | [ clause ] ->
+      print_endline ("CLAUSE: " ^ Printer.print clause true);
+      sanitized := !sanitized @ [ hack_ellipsis prefix clause ];
+      !sanitized
+    | clause :: rest ->
+      sanitized := !sanitized @ [ hack_ellipsis prefix clause ];
+      sanitize_clauses rest
+    | [] -> !sanitized
+  in
+  sanitize_clauses clauses
+;;
+
+let generate_variants sym _ patterns =
   let symbol = Printer.print sym true in
   let variants = ref Types.M9map.empty in
   let rec register_variants clauses =
@@ -110,14 +188,14 @@
 let match_variant macro args =
   let vmatch = ref "" in
   (match macro with
-  | T.Map { T.value = meta } ->
+  | T.Map { T.value = meta; meta = _ } ->
     (match Types.M9map.find Types.macro_variants meta with
-    | T.Map { T.value = variant_list } ->
+    | T.Map { T.value = variant_list; meta = _ } ->
       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 } ->
+          | T.List { T.value = T.List { T.value = x; meta = _ } :: z; meta = _ } ->
             print_endline
               (" >>>> ["
               ^ string_of_int (List.length args)
--- a/reader.ml
+++ b/reader.ml
@@ -18,11 +18,11 @@
   List.map
     (function
       | Str.Delim x -> String.trim x (* move trim to regex for speed? *)
-      | Str.Text x -> "tokenize botch")
+      | Str.Text _ -> "tokenize botch")
     (List.filter
        (function
-         | Str.Delim x -> true
-         | Str.Text x -> false)
+         | Str.Delim _ -> true
+         | Str.Text _ -> false)
        (Str.full_split token_re str))
 ;;
 
@@ -87,7 +87,7 @@
       try Env.get registered_macros (Types.symbol (List.nth list_reader.tokens 1)) with
       | _ -> T.Nil
     with
-    | T.List { T.value = xs; T.meta } ->
+    | T.List { T.value = _; T.meta } ->
       print_endline "XXXX MACRO FOUND";
       let rec collect_args tokens args =
         match tokens with
@@ -103,7 +103,7 @@
   | [] ->
     print_endline ("ERROR: " ^ Printer.dump list_reader.list_form);
     raise (Utils.Syntax_error ("unterminated '" ^ eol ^ "'"))
-  | [ token ] -> { list_form = list_reader.list_form; tokens = [ ")" ] }
+  | [ _ ] -> { 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 }
@@ -134,8 +134,10 @@
     print_endline ("  sym: " ^ Printer.print sym true);
     print_endline ("    rest: " ^ Printer.dump rest);
     (match rest with
-    | [ T.List { T.value = T.Symbol { T.value = "syntax-rules" } :: literals :: clauses } ] ->
-      let variants = Macro.generate_variants sym literals clauses in
+    | [ T.List { T.value = T.Symbol { T.value = "syntax-rules"; meta = _ } :: literals :: clauses; meta = _ } ] ->
+      let sanitized_clauses = Macro.generate_patterns sym clauses in
+      print_endline ("sanitized: " ^ String.concat " " (List.map (fun x -> String.concat " " x) sanitized_clauses));
+      let variants = Macro.generate_variants sym literals sanitized_clauses in
       let macro_entry = Types.macro sym literals (Types.list clauses) variants in
       Env.set registered_macros sym macro_entry;
       Types.M9map.iter