@@ -72,6 +72,43 @@ let rec expand_macro : Raw.t -> expr = function
7272 List. fold_left t ~init: (expand_macro h) ~f: (fun acc e ->
7373 List [ expand_macro e; acc ] )
7474
75+ let rec equal_expr x y =
76+ match (x, y) with
77+ | Var x1 , Var x2 | Symbol x1 , Symbol x2 -> equal_string x1 x2
78+ | Unquote e1 , Unquote e2 -> equal_expr e1 e2
79+ | List es1 , List es2 -> begin
80+ try List. for_all2_exn es1 es2 ~f: equal_expr with _ -> false
81+ end
82+ | _ -> false
83+
84+ let rec replace_id xfrom xto = function
85+ | Symbol s -> Symbol s
86+ | Var x -> Var x
87+ | Unquote e when equal_expr e xfrom -> xto
88+ | Unquote e -> Unquote e
89+ | List es -> List (List. map ~f: (replace_id xfrom xto) es)
90+
91+ let unfold_decl_def (env : (string * (expr list * expr list) ) list ) es :
92+ expr list =
93+ List. fold_left es ~init: (env, [] ) ~f: (fun (env , acc ) -> function
94+ | List (Symbol "new-declaration" :: List (Symbol k :: args ) :: content ) ->
95+ ((k, (args, content)) :: env, acc)
96+ | List (Symbol k :: args)
97+ when List.Assoc. find ~equal: equal_string env k |> Option. is_some ->
98+ let syntax_args, content =
99+ List.Assoc. find_exn ~equal: equal_string env k
100+ in
101+ if List. length syntax_args <> List. length args then
102+ failwith (" Error: not enough args given in macro call " ^ k)
103+ else
104+ let replace_ids e =
105+ List. fold_left (List. zip_exn syntax_args args) ~init: e
106+ ~f: (fun acc (xfrom , xto ) -> replace_id xfrom (Unquote xto) acc )
107+ in
108+ (env, (List. map ~f: replace_ids content |> List. rev) @ acc)
109+ | e -> (env, e :: acc) )
110+ |> snd |> List. rev
111+
75112(* ---------------------------------------
76113 Constellation of Expr
77114 --------------------------------------- *)
@@ -155,57 +192,45 @@ let rec sgen_expr_of_expr (e : expr) : sgen_expr =
155192 | List [ Symbol k; g ] when equal_string k focus_op ->
156193 Focus (sgen_expr_of_expr g)
157194 (* union *)
158- | List (Symbol k :: gs ) when equal_string k " union" ->
159- Union (List. map ~f: sgen_expr_of_expr gs)
195+ | List (Symbol "union" :: gs ) -> Union (List. map ~f: sgen_expr_of_expr gs)
160196 (* process *)
161- | List (Symbol k :: gs ) when equal_string k " process" ->
162- Process (List. map ~f: sgen_expr_of_expr gs)
197+ | List (Symbol "process" :: gs ) -> Process (List. map ~f: sgen_expr_of_expr gs)
163198 (* kill *)
164- | List [ Symbol k; g ] when equal_string k " kill" ->
165- Kill (sgen_expr_of_expr g)
199+ | List [ Symbol " kill" ; g ] -> Kill (sgen_expr_of_expr g)
166200 (* clean *)
167- | List [ Symbol k; g ] when equal_string k " clean" ->
168- Clean (sgen_expr_of_expr g)
201+ | List [ Symbol " clean" ; g ] -> Clean (sgen_expr_of_expr g)
169202 (* exec *)
170- | List [ Symbol k; g ] when equal_string k " exec" ->
171- Exec (false , sgen_expr_of_expr g)
203+ | List [ Symbol " exec" ; g ] -> Exec (false , sgen_expr_of_expr g)
172204 (* linear exec *)
173- | List [ Symbol k; g ] when equal_string k " linexec" ->
174- Exec (true , sgen_expr_of_expr g)
205+ | List [ Symbol " linexec" ; g ] -> Exec (true , sgen_expr_of_expr g)
175206 (* eval *)
176- | List [ Symbol k; g ] when equal_string k " eval" ->
177- Eval (sgen_expr_of_expr g)
207+ | List [ Symbol " eval" ; g ] -> Eval (sgen_expr_of_expr g)
178208 (* KEEP LAST -- raw constellation *)
179209 | List g -> Raw (constellation_of_expr (List g))
180210
181211(* ---------------------------------------
182212 Stellogen program of Expr
183213 --------------------------------------- *)
184214
185- (* let typedecl_of_expr : expr -> type_declaration = function
186- | Symbol k when equal_string k nil_op -> []
187- | List [ Symbol k; h; t ] when equal_string k cons_op ->
188- *)
189-
190215let decl_of_expr : expr -> declaration = function
191216 (* definition := *)
192217 | List [ Symbol k; x; g ] when equal_string k def_op ->
193218 Def (ray_of_expr x, sgen_expr_of_expr g)
194- | List [ Symbol k ; x; g ] when equal_string k " spec " ->
195- Def (ray_of_expr x, sgen_expr_of_expr g)
219+ | List [ Symbol " spec " ; x; g ] -> Def (ray_of_expr x, sgen_expr_of_expr g)
220+ | List [ Symbol " exec " ; x; g ] -> Def (ray_of_expr x, sgen_expr_of_expr g)
196221 (* show *)
197- | List [ Symbol k; g ] when equal_string k " show" ->
198- Show (sgen_expr_of_expr g)
222+ | List [ Symbol " show" ; g ] -> Show (sgen_expr_of_expr g)
199223 (* trace *)
200- | List [ Symbol k; g ] when equal_string k " trace" ->
201- Trace (sgen_expr_of_expr g)
224+ | List [ Symbol " trace" ; g ] -> Trace (sgen_expr_of_expr g)
202225 (* expect *)
203226 | List [ Symbol k; x; g ] when equal_string k expect_op ->
204227 Expect (ray_of_expr x, sgen_expr_of_expr g, const " default" )
205228 | List [ Symbol k; x; g; m ] when equal_string k expect_op ->
206229 Expect (ray_of_expr x, sgen_expr_of_expr g, ray_of_expr m)
207230 (* use *)
208231 | List [ Symbol k; r ] when equal_string k " use" -> Use (ray_of_expr r)
209- | _ -> failwith " error: invalid declaration"
232+ | e -> failwith ( " error: invalid declaration ^ " ^ to_string e)
210233
211234let program_of_expr = List. map ~f: decl_of_expr
235+
236+ let preprocess e = e |> List. map ~f: expand_macro |> unfold_decl_def []
0 commit comments