ref: 083121b7a0857569d6562aa563055c19c9e2cece
parent: ae95184e6aa4685bbd13ed4b58df2fcc3e1f625c
author: smazga <smazga@greymanlabs.com>
date: Fri Aug 14 12:41:49 EDT 2020
working on macros
--- a/env.ml
+++ b/env.ml
@@ -12,7 +12,8 @@
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 } ->
+ (* print_endline ("Env.set: " ^ key); *) env.data := Data.add key value !(env.data)
| _ -> raise (Invalid_argument "set: not a symbol")
;;
--- a/m9.ml
+++ b/m9.ml
@@ -14,6 +14,8 @@
module T = Types.Types
let repl_env = Env.make (Some Core.base)
+let synext_literals = T.String "syntax literals"
+let synext_transformers = T.String "syntax transformers"
let rec quasiquote ast =
match ast with
@@ -42,25 +44,50 @@
| T.Proc { T.meta = T.Map { T.value = meta } } ->
Types.M9map.mem Core.kw_macro meta
&& Types.to_bool (Types.M9map.find Core.kw_macro meta)
- | T.List { T.value = macro } -> (match macro with
- | kw :: _ -> kw = Types.symbol "syntax-rules"
- | _ -> false)
+ | T.List { T.value = macro } ->
+ (match macro with
+ | kw :: _ -> kw = Types.symbol "syntax-rules"
+ | _ -> false)
| _ -> false)
| _ -> false
;;
+
let eval_macro sym args macro env =
- let parsed = Str.global_replace (Str.regexp "(_") ("(" ^ Printer.print sym true) (Printer.dump macro) in
- print_endline ("eval_macro: sym:" ^ Printer.print sym true ^ " args:" ^ Printer.dump args ^ " macro:" ^ Printer.dump macro);
- print_endline (" parsed: " ^ parsed)
-(* let sub_env = Env.make (Some env) in
- * match macro with
- * | _ :: literals :: cases ->
- * (match cases with
- * | hd :: tl ->
- * (\* TODO: handle literals *\)
- * )
- * | _ -> () *)
+ (match macro with
+ | _ :: literals :: groups ->
+ let sgroups = Str.global_replace
+ (Str.regexp "(_")
+ ("(" ^ Printer.print sym true)
+ (Printer.dump groups) in
+ print_endline ("BLARGH: " ^ sgroups);
+ print_endline ("TOKENIZED: " ^ String.concat " " (Reader.tokenize ("(" ^ sgroups ^ ")")));
+ let list_reader = Reader.read_list ")" {list_form = []; tokens = (Reader.tokenize (sgroups ^ ")")) } in
+ let slist = Types.list list_reader.list_form in
+ print_endline ("BLAAAARGH: " ^ Printer.print slist true)
+ | _ -> ());
+ let smacro =
+ Str.global_replace
+ (Str.regexp "(_")
+ ("(" ^ Printer.print sym true)
+ (Printer.dump macro)
+ in
+ print_endline
+ ("eval_macro: sym:"
+ ^ Printer.print sym true
+ ^ " args:"
+ ^ Printer.dump args
+ ^ " straight macro: "
+ ^ Printer.dump macro
+ ^ " subbed macro:"
+ ^ smacro);
+ (* let sub_env = Env.make (Some env) in *)
+ match Reader.read smacro with
+ | T.List { T.value = transformer } ->
+ print_endline (" TRANSFORMER: " ^ Printer.dump transformer)
+ | _ -> ()
+;;
+
let rec macroexpand ast env =
if is_macro_call ast env
then (
@@ -67,17 +94,18 @@
print_endline (" YES!: " ^ Printer.print ast true);
match ast with
| T.List { T.value = s :: args } ->
- print_endline ("one: s: " ^ Printer.print s true ^ " args: " ^ Printer.dump args);
+ print_endline ("macroexpand macro symbol: " ^ Printer.print s true ^ " args: " ^ Printer.dump args);
(match
try Env.get env s with
| _ -> T.Nil
with
- | T.Proc { T.value = f } -> macroexpand (f args) env
- | T.List { T.value = macro } -> eval_macro s args macro env; ast
+ | T.Proc { T.value = f } -> macroexpand (f args) env
+ | T.List { T.value = macro } ->
+ eval_macro s args macro env;
+ ast
| _ -> ast)
| _ -> ast)
- else
- ast
+ else ast
;;
let rec eval_ast ast env =
@@ -121,33 +149,14 @@
; T.List { T.value = transformer }
]
} ->
- print_endline ("define-syntax: " ^ Printer.print keyword true);
- print_endline (" transformer: " ^ String.concat " " (List.map (fun xs -> Printer.print xs true) transformer));
- let macro = T.List { T.value = transformer; meta = Core.link [ Core.kw_macro; T.Bool true ] } in
- Env.set env keyword macro; macro
- (* print_endline ("define-syntax: " ^ Printer.print keyword true);
- * print_endline
- * (" transformer: "
- * ^ String.concat " " (List.map (fun xs -> Printer.print xs true) transformer));
- * (match transformer with
- * | T.Symbol { T.value = "syntax-rules" } :: literals :: rest ->
- * print_endline (" literals (unsupported!): " ^ Printer.print literals true);
- * print_endline (" -- rest: " ^ String.concat ":" (List.map (fun x -> Printer.print x true) rest));
- * let proc = T.Proc {
- * T.Nil *)
-
-
- (* print_endline (" literals: " ^ String.concat " " (List.map (fun xs -> Printer.print xs true) literals)); *)
- (* print_endline (" body: " ^ String.concat " " (List.map (fun xs -> Printer.print xs true) body)); *)
- (* (match eval transformer env with
- * | T.Proc { T.value = p; T.meta } ->
- * let proc =
- * T.Proc { T.value = p; meta = Core.link [ meta; Core.kw_macro; T.Bool true ] }
- * in
- * Env.set env keyword proc;
- * proc
- * | _ -> raise (Reader.Syntax_error "malformed syntax-rules")) *)
- (* | _ -> raise (Reader.Syntax_error "missing syntax-rules")) *)
+ print_endline ("define-syntax: " ^ Printer.print keyword true);
+ print_endline
+ (" transformer: " ^ Printer.dump transformer);
+ let macro =
+ Types.list transformer
+ in
+ Env.set env keyword macro;
+ macro
| T.List
{ T.value =
[ T.Symbol { T.value = "lambda" }; T.Vector { T.value = arg_names }; expr ]
--- a/notes.org
+++ b/notes.org
@@ -1,5 +1,7 @@
* First things:
-** PROGRESSING (let) doesn't work at all
+** TODO Remove kw_macro
+We determine what's a macro based on "syntax-rules" (so we need to make sure that's always there)
+** DONE (let) doesn't work at all
** Should (let) include an implicit (begin)?
s9fes seems to do it
** TODO need an "unspecified" type?
--- a/printer.ml
+++ b/printer.ml
@@ -17,7 +17,11 @@
| T.Bool false -> "#f"
| T.Char c -> "#\\" ^ Char.escaped c
| T.Nil -> "nil"
- | T.Map _ | T.Comment ->
+ | T.Map { T.value = xs } ->
+ "{" ^ (Types.M9map.fold (fun k v s -> s ^ (if s = "" then "" else " ") ^ (print k r)
+ ^ " " ^ (print v r)) xs "")
+ ^ "}"
+ | T.Comment ->
"" (* TODO: this leaves a space in the output for block comments *)
(* | T.Pair ({ T.value = one }, { T.value = two }) -> "(" ^ (print one readable) ^ " . " ^ (print two readable) ^ ")" *)
| T.Proc p -> "#<proc>"
@@ -42,11 +46,10 @@
^ "\""
else s
| T.List { T.value = xs } ->
- "(" ^ String.concat " " (List.map (fun s -> print s r) xs) ^ ")"
+ "~(" ^ String.concat " " (List.map (fun s -> print s r) xs) ^ ")"
| T.Vector { T.value = v } ->
"#(" ^ String.concat " " (List.map (fun s -> print s r) v) ^ ")"
| T.Record r -> "<record supported>"
;;
-let dump obj =
- String.concat " " (List.map (fun s -> print s true) obj)
+let dump obj = String.concat " " (List.map (fun s -> print s true) obj)