shithub: martian9

Download patch

ref: b2beb0311ec840da0eafa95888d816af0353436e
parent: 24cf0e8cd6799c80652dd2f7ecf41e0209dfe159
author: McKay Marston <[email protected]>
date: Thu Dec 3 16:08:18 EST 2020

macros are _almost_ there

--- a/env.ml
+++ b/env.ml
@@ -10,7 +10,7 @@
 let set env sym value =
   match sym with
   | T.Symbol {T.value= key; T.meta= _} ->
-     print_endline ("Env.set: " ^ key); env.data := Data.add key value !(env.data)
+      (* 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 =
@@ -26,6 +26,11 @@
     | Some found_env -> Data.find key !(found_env.data)
     | None -> raise (Runtime_error ("unknown symbol '" ^ key ^ "'")) )
   | _ -> raise (Invalid_argument "get: not a symbol")
+
+let dump env =
+  let str = ref "" in
+  Data.iter (fun k v -> str := !str ^ k ^ ": " ^ Printer.to_string v) !(env.data) ;
+  !str
 
 (* let string_of_env env =
  *   let string = ref "" in
--- a/m9.ml
+++ b/m9.ml
@@ -13,7 +13,7 @@
 module T = Types.Types
 
 let repl_env = Env.make (Some Core.base)
-let nameplate = "Martian9 Scheme v0.2"
+let nameplate = "Martian9 Scheme v0.3"
 let read str = Reader.read str
 let print exp = Printer.print exp true
 let rep str env = print (Eval.eval (read str) env)
--- a/macro.ml
+++ b/macro.ml
@@ -158,14 +158,13 @@
   register_variants clauses
 
 let rec collect_args tokens args =
-  match tokens with
-  | [t] -> args @ [t]
-  | t :: ts -> if t = ")" then args else collect_args ts args @ [t]
-  | _ -> []
+  match tokens with [t] -> args @ [t] | t :: ts -> if t = ")" then args else collect_args ts args @ [t] | _ -> []
 
-let match_variant macro args =
+let match_variant original_sym macro args =
+  let args = if List.hd args = original_sym then List.tl args else args in
   let vmatch = ref "" in
-  print_endline ("match_variant: " ^ Printer.to_string macro);
+  (* print_endline (" >>>> match_variant: " ^ Printer.to_string macro) ; *)
+  print_endline (" >>>> match_variant with args: " ^ String.concat " " args);
   ( match macro with
   | T.Map {T.value= meta; meta= _} -> (
     match Types.M9map.find Types.macro_variants meta with
@@ -172,22 +171,28 @@
     | T.Map {T.value= variant_list; meta= _} ->
         Types.M9map.iter
           (fun k v ->
-            print_endline ("   >>>  " ^ Printer.to_string k ^ ": " ^ Printer.to_string v) ;
+            print_endline ("  >>>  " ^ Printer.to_string k ^ ": " ^ Printer.to_string v) ;
             let wrong = Utils.tokenize (Printer.to_string v) in
-            print_endline ("->->-> " ^ String.concat "*" wrong);
-            (match wrong with
-             | "(" :: "define" :: sym :: "(":: "lambda" :: rest ->
-                print_endline ("SYM: " ^ sym ^ "  REST: " ^ String.concat " " rest);
+            ( match wrong with
+            | "(" :: "define" :: sym :: "(" :: "lambda" :: rest ->
+                print_endline ("    SYM: " ^ sym ^ "  REST: " ^ String.concat " " rest) ;
                 let new_args = collect_args (List.tl rest) [] in
-                print_endline ("  ARGS: " ^ String.concat " " new_args ^ " [" ^ string_of_int (List.length new_args) ^ "]  args:[" ^ string_of_int (List.length args - 1) ^ "]");
-                if List.length new_args = List.length args - 1 then vmatch := sym
-             | _ -> print_endline "no rest");
-            (* match v with
-             * | T.List { T.value = [T.Symbol { T.value = "define"; meta = _ }; T.Symbol { T.value = sym; meta = _ } ]; meta = _ }  -> *)
-                print_endline ( " >>>> sym: " ^ Printer.to_string k);
-                print_endline ( " >>>> args: " ^ String.concat " " args);
-                print_endline ( " >>>> v: " ^ Printer.to_string v))
-            (* | _ -> () ) *)
+                print_endline
+                  ( "    ARGS: " ^ String.concat " " new_args ^ " ["
+                  ^ string_of_int (List.length new_args)
+                  ^ "]  args: " ^ String.concat " " args ^ " ["
+                  ^ string_of_int (List.length args)
+                  ^ "]" ) ;
+                (match (List.length new_args, List.length args) with
+                 | 0, 0
+                   | 1, 1 -> vmatch := sym
+                   | x, y when x = y -> vmatch := sym
+                 | _, _ -> ())
+                (* if List.length new_args = List.length args - 1 then vmatch := sym *)
+            | _ -> print_endline "no rest" ) ;
+            print_endline ("     >>>> sym: " ^ Printer.to_string k) ;
+            print_endline ("     >>>> args: " ^ String.concat " " args) ;
+            print_endline ("     >>>> v: " ^ Printer.to_string v) )
           variant_list
     | _ -> () )
   | _ -> () ) ;
--- a/reader.ml
+++ b/reader.ml
@@ -27,13 +27,14 @@
   | _ -> String.concat " " !block
 
 and fix_clause original sym clause =
-  print_endline (">>>>> fix_clause: incoming: " ^ Printer.print clause true) ;
+  print_endline (">>>>> fix_clause: incoming: " ^ Printer.to_string clause) ;
   match clause with
   | T.List {T.value= [T.List {T.value= pattern; meta= _}; T.List {T.value= transform; meta= _}]; meta= _} ->
       let pattern = Utils.tokenize (Printer.dump pattern) in
       let fixed_pattern = replace_token (List.tl pattern) (Printer.to_string sym) (ref []) in
-      let fixed_transform = replace_token (Utils.tokenize (Printer.dump transform)) (Printer.to_string original) (ref []) in
-      [ "("; "define"; Printer.print sym true; "("; "lambda"; "("; fixed_pattern; ")"; "("; fixed_transform; ")"; ")"; ")" ]
+      let fixed_transform =
+        replace_token (Utils.tokenize (Printer.dump transform)) (Printer.to_string original) (ref []) in
+      ["("; "define"; Printer.to_string sym; "("; "lambda"; "("; fixed_pattern; ")"; "("; fixed_transform; ")"; ")"; ")"]
   | T.List {T.value= [T.List {T.value= pattern; meta= _}; atom]; meta= _} ->
       let pattern = Utils.tokenize (Printer.dump pattern) in
       let fixed_pattern = replace_token (List.tl pattern) (Printer.to_string sym) (ref []) in
@@ -63,32 +64,32 @@
   (* we need to replace macro calls with their variant symbols *)
   let tweaked_tokens =
     if List.length list_reader.tokens > 1 && List.hd list_reader.tokens = "(" then
-      let symbol = Types.symbol (List.nth list_reader.tokens 1) in
+      let symbol_str = List.nth list_reader.tokens 1 in
+      let symbol = Types.symbol symbol_str in
       match try Env.get registered_macros symbol with _ -> T.Nil with
       | T.Macro {T.value= m; meta} ->
-          print_endline "XXXX MACRO FOUND" ;
+          (* print_endline "XXXX MACRO FOUND" ; *)
           print_endline ("XXXX MACRO: " ^ Printer.to_string m) ;
-          print_endline ("XXXX META: " ^ Printer.to_string meta);
-          print_endline ("XXXX TOKENS: " ^ String.concat " " list_reader.tokens);
+          (* print_endline ("XXXX META: " ^ Printer.to_string meta); *)
+          (* print_endline ("XXXX TOKENS: " ^ String.concat " " list_reader.tokens) ; *)
           let args = Macro.collect_args (List.tl list_reader.tokens) [] in
-          print_endline ("<><><> args: " ^ String.concat " " args) ;
-          let variant = Macro.match_variant meta args in
+          (* print_endline ("<><><> args: " ^ String.concat " " args) ; *)
+          let variant = Macro.match_variant symbol_str meta args in
           print_endline ("<><><><>: " ^ variant) ;
-          List.map (fun s -> if s = Printer.to_string symbol then variant else s) list_reader.tokens
+          (* List.map (fun s -> if s = Printer.to_string symbol then variant else s) (trim_end list_reader.tokens) *)
+          List.map (fun s -> if s = symbol_str then variant else s) (trim_end list_reader.tokens)
       | _ -> list_reader.tokens
     else list_reader.tokens in
-  (* print_endline ("TWEAKED_TOKENS: [" ^ String.concat " " tweaked_tokens ^ "]"); *)
+  (* print_endline ("TWEAKED_TOKENS: [" ^ String.concat " " tweaked_tokens ^ "]") ; *)
   match tweaked_tokens with
-  | [] ->
-      raise (Utils.Syntax_error ("read_list botch: '" ^ Printer.dump list_reader.list_form ^ "' eol: '" ^ eol ^ "'"))
+  | [] -> raise (Utils.Syntax_error ("read_list botch: '" ^ Printer.dump list_reader.list_form ^ "' eol: '" ^ eol ^ "'"))
   | [_] -> {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}
-     else
-       let reader = read_form tweaked_tokens in
-       print_endline ("token: " ^ token ^ "  tokens: " ^ String.concat " " tokens);
-       read_list eol {list_form= list_reader.list_form @ [reader.form]; tokens= reader.tokens}
+      if Str.string_match (Str.regexp eol) token 0 then {list_form= list_reader.list_form; tokens}
+      else
+        let reader = read_form tweaked_tokens in
+        (* print_endline ("token: " ^ token ^ "  tokens: " ^ String.concat " " tokens); *)
+        read_list eol {list_form= list_reader.list_form @ [reader.form]; tokens= reader.tokens}
 
 and read_quote sym tokens =
   let reader = read_form tokens in
@@ -119,39 +120,32 @@
           let variants = Macro.generate_variants sym literals sanitized_clauses in
           let fixed_variants = ref Types.M9map.empty in
           let transforms = ref Types.M9map.empty in
-          Types.M9map.iter
-            (fun k v -> transforms := Types.M9map.add k (Utils.tokenize v) !transforms)
-            variants ;
-
+          Types.M9map.iter (fun k v -> transforms := Types.M9map.add k (Utils.tokenize v) !transforms) variants ;
           let fixed_clauses = ref [] in
           Types.M9map.iter
             (fun k v ->
               let fixed_clause = fix_clause sym k (read_form (Utils.tokenize v)).form in
+              (* TODO: is this even used? *)
               print_endline
                 (">>>> registering variant: " ^ Printer.print k true ^ ":  " ^ String.concat " " fixed_clause) ;
-              macro := !macro @ fixed_clause;
+              macro := !macro @ fixed_clause ;
               let parsed = (read_form fixed_clause).form in
-              fixed_clauses := !fixed_clauses @ [ parsed ];
-              fixed_variants := Types.M9map.add k parsed !fixed_variants;
-              Env.set registered_macros k parsed)
-            variants;
-          print_endline ("trying to parse macro: " ^ String.concat " " !macro);
-          let macro_entry =
-            Types.macro sym literals
-              T.Nil
-              !fixed_variants in
-          Env.set registered_macros sym macro_entry;
-          print_endline ("finished")
+              fixed_clauses := !fixed_clauses @ [parsed] ;
+              fixed_variants := Types.M9map.add k parsed !fixed_variants ;
+              Env.set registered_macros k parsed )
+            variants ;
+          print_endline ("trying to parse macro: " ^ String.concat " " !macro) ;
+          let macro_entry = Types.macro sym literals T.Nil !fixed_variants in
+          Env.set registered_macros sym macro_entry ;
+          print_endline "finished"
       | _ -> raise (Utils.Syntax_error "read_macro botch") )
   | _ -> raise (Utils.Syntax_error "read_macro last rest botch") ) ;
   print_endline ("SO HERE ARE THE MACRO VARIANTS: " ^ String.concat " " !macro) ;
-
-  (* the first and last () because the parser makes the whole thing a bogus list *)
   let trimmed_macro = List.tl !macro in
   let trimmed_tokens = trim_end list_reader.tokens in
   print_endline ("TRIMMED_MACRO: " ^ String.concat " " trimmed_macro) ;
   print_endline ("TRIMMED_TOKENS: " ^ String.concat " " trimmed_tokens) ;
-  print_endline ("TRIMMED_MACRO: " ^ String.concat " " (trimmed_macro @ trimmed_tokens));
+  print_endline ("TRIMMED_MACRO: " ^ String.concat " " (trimmed_macro @ trimmed_tokens)) ;
   trimmed_macro @ trimmed_tokens
 
 and read_form all_tokens =
@@ -171,11 +165,7 @@
         let list_reader = read_list ")" {list_form= []; tokens} in
         {form= Types.list list_reader.list_form; tokens= list_reader.tokens}
     | "" | "\t" | "\n" -> read_form tokens
-    (* | "define-syntax" -> read_form (read_macro tokens) *)
-    | "define-syntax" ->
-       let list_reader = read_list ")" {list_form= []; tokens= read_macro tokens} in
-       print_endline ("macro: " ^ Printer.dump list_reader.list_form) ;
-       {form= T.Unspecified; tokens= list_reader.tokens}
+    | "define-syntax" -> read_form (read_macro tokens)
     | _ ->
         if token.[0] = ';' then (
           let list_reader = read_list "\\n" {list_form= []; tokens} in
@@ -195,5 +185,8 @@
   let tokenized = Utils.tokenize str in
   print_endline ("TOKENIZED: " ^ String.concat " " tokenized) ;
   let form = (read_form tokenized).form in
-  print_endline ("FORM: " ^ Printer.to_string form) ;
-  form
+  let retoken = Utils.tokenize (Printer.to_string form) in
+  print_endline ("\nRETOKENIZED: " ^ String.concat " " retoken ^ "\n") ;
+  let reform = (read_form retoken).form in
+  print_endline ("\nFORM: " ^ Printer.to_string form) ;
+  reform
--- a/utils.ml
+++ b/utils.ml
@@ -11,4 +11,3 @@
   List.map
     (function Str.Delim x -> String.trim x (* move trim to regex for speed? *) | Str.Text _ -> "tokenize botch")
     (List.filter (function Str.Delim _ -> true | Str.Text _ -> false) (Str.full_split token_re str))
-