ref: ad64b64a877a8ade76ab155b61931aa2f18a3ee5
dir: /macro.ml/
module T = Types.Types (* let gen_sym root = * let gen() = match Random.int(26+26+10) with * n when n < 26 -> int_of_char 'a' + n * | n when n < 26 + 26 -> int_of_char 'A' + n - 26 * | n -> int_of_char '0' + n - 26 - 26 in * let gen _ = String.make 1 (char_of_int(gen())) in * root ^ (String.concat "" (Array.to_list (Array.init 5 gen))) *) let rec is_matching_pattern sym pattern args matched = match pattern, args with (* literals and ellipses not handled, yet *) | ph :: pt, ah :: at -> print_endline " LIST <-> LIST"; if ph = "_" || (ph = Printer.print sym true && sym = ah) then is_matching_pattern sym pt at matched && true else ( print_endline (" ------> " ^ ph ^ " vs " ^ Printer.print ah true); is_matching_pattern sym pt at matched) | ph :: pt, [] -> print_endline " LIST <-> []"; if ph = "_" || ph = Printer.print sym true then is_matching_pattern sym pt [] matched && true else (List.hd pt = "...") | [], ah :: at -> print_endline " [] <-> LIST"; false | _, _ -> matched ;; let lambdaize pattern template args = match pattern, args with | ph :: pt, ah :: at :: rest -> print_endline "lambdaize: list list"; Reader.read ("((lambda (" ^ Printer.stringify pt false ^ ") (" ^ Printer.print template true ^ ")" ^ Printer.stringify args false ^ "))") | ph :: pt, ah :: at -> print_endline "lambdaize: list short"; Reader.read ("((lambda (" ^ Printer.stringify pt true ^ ")" ^ Printer.print template true ^ ")" ^ Printer.stringify args true ^ ")") | ph :: pt, [] -> print_endline "lambdaize: list empty"; Reader.read ("((lambda (" ^ Printer.stringify pt false ^ ") " ^ Printer.print template true ^ "))") | _ -> 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 } -> (try let literals = Types.M9map.find Types.macro_literals m in let transformers = Types.M9map.find Types.macro_transformers m in print_endline (" -- EVAL_MACRO: literals: " ^ Printer.print literals true ^ " transformers: " ^ Printer.print transformers true); print_endline (" args: " ^ Printer.dump args); 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 pattern: " ^ Printer.dump pattern); print_endline (" - template: " ^ Printer.dump template); print_endline ("matched?: " ^ if is_matching_pattern sym (List.map (fun x -> Printer.print x true) pattern) (Core.seq ast) true then "yes" else "no"); 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 pattern: " ^ Printer.dump pattern); print_endline ("matched?: " ^ if is_matching_pattern sym (List.map (fun x -> Printer.print x true) pattern) (Core.seq ast) true then "yes" else "no"); 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 | _ -> T.Nil) (* errors? *) | [] -> T.Nil in match_transform (Core.seq transformers) with | Not_found -> T.Nil) | _ -> T.Nil ;;