ref: 264e6b67b3caa3be6c4a23fca1a81adddc9d2bac
parent: 120a0cb0fd9df6a5da5d0ba480d6eb9b8b6d66a8
author: smazga <smazga@greymanlabs.com>
date: Tue Aug 18 12:29:01 EDT 2020
slowly getting to a place where macros can be handled
--- a/env.ml
+++ b/env.ml
@@ -13,7 +13,7 @@
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)+ (* 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
@@ -41,6 +41,9 @@
try Env.get env s with
| _ -> T.Nil
with
+ | T.Macro m ->
+ print_endline "is_macro_call: true";
+ true
| 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)
@@ -54,23 +57,30 @@
let eval_macro sym args macro env =
(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 rec handle_groups groups =
- (match groups with
- | hd :: tl -> print_endline (" HD: " ^ Printer.print hd true ^ " tl: " ^ Printer.dump tl); handle_groups tl- | _ -> print_endline "<list end>") in
- handle_groups groups;
- 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);- | _ -> ());
-
+ | _ :: 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 rec handle_groups groups =
+ match groups with
+ | hd :: tl ->
+ print_endline (" HD: " ^ Printer.print hd true ^ " tl: " ^ Printer.dump tl);+ handle_groups tl
+ | _ -> print_endline "<list end>"
+ in
+ handle_groups groups;
+ 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 "(_")
@@ -88,7 +98,7 @@
(* let sub_env = Env.make (Some env) in *)
match Reader.read smacro with
| T.List { T.value = transformer } ->- print_endline (" TRANSFORMER: " ^ Printer.dump transformer)+ print_endline (" TRANSFORMER: " ^ Printer.dump transformer)| _ -> ()
;;
@@ -98,11 +108,15 @@
print_endline (" YES!: " ^ Printer.print ast true);match ast with
| T.List { T.value = s :: 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.Macro { T.value = s; meta = m } ->+ print_endline (" THIS IS A MACRO: " ^ Printer.print s true);+ print_endline (" META: " ^ Printer.print m true);+ print_endline (" ARGS: " ^ Printer.dump args);+ ast
| T.Proc { T.value = f } -> macroexpand (f args) env | T.List { T.value = macro } ->eval_macro s args macro env;
@@ -119,6 +133,9 @@
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 }+ | T.Macro { T.value = m } ->+ print_endline ("wait, what? " ^ Printer.print m true);+ T.Nil
| _ -> ast
and eval ast env =
@@ -148,19 +165,20 @@
value
| T.List
{ T.value =- [ T.Symbol { T.value = "define-syntax" }- ; keyword
- ; T.List { T.value = transformer }- ]
+ [ T.Symbol { T.value = "define-syntax" }; keyword; T.List { T.value = macro } ]} ->
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
+ (match macro with
+ | _ :: literals :: groups ->
+ let macro_entry =
+ Types.macro (Printer.print keyword true) literals (Types.list groups)
+ in
+ print_endline (" macro_entry: " ^ Printer.print macro_entry true);+ print_endline (" literals: " ^ Printer.print literals true);+ print_endline (" groups: " ^ Printer.dump groups);+ 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 ]--- a/printer.ml
+++ b/printer.ml
@@ -17,12 +17,15 @@
| 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 } ->- "{" ^ (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 *)
+ "{"+ ^ 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>"
| T.Symbol { T.value = s } -> s@@ -49,7 +52,7 @@
"(" ^ 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>"
+ | T.Record r -> "<record unsupported>"
;;
let dump obj = String.concat " " (List.map (fun s -> print s true) obj)
--- a/types.ml
+++ b/types.ml
@@ -15,6 +15,7 @@
(* | Pair of t with_meta * t list *)
| Proc of (t list -> t) with_meta
| Symbol of string with_meta
+ | Macro of t with_meta
| Bytevector of t list
| Eof_object
| Number of float with_meta
@@ -44,6 +45,9 @@
type m9type = Value.t
+let macro_literals = Types.String "literals"
+let macro_transformers = Types.String "transformers"
+
exception M9exn of Types.t
let to_bool x =
@@ -66,3 +70,11 @@
let vector x = Types.Vector { Types.value = x; meta = Types.Nil } let record x = Types.Record { Types.value = x; meta = Types.Nil } let number x = Types.Number { Types.value = x; meta = Types.Bool (is_float x) }+
+let macro sym literals transformers =
+ let meta = ref M9map.empty in
+ meta
+ := M9map.add macro_literals literals !meta
+ |> M9map.add macro_transformers transformers;
+ Types.Macro { Types.value = symbol sym; meta = map !meta }+;;
--
⑨