11open Stdppx
22
3- let string_of_targ targ = Grammar. string_of_targ ~internal: false targ
4-
53let parens x = Printf. sprintf " (%s)" x
64
75type base_method =
86 { method_name : string
9- ; params : string list
7+ ; tvars : string list
108 ; type_name : string
119 }
1210
1311let base_methods =
14- [ {method_name = " bool" ; params = [] ; type_name = " bool" }
15- ; {method_name = " char" ; params = [] ; type_name = " char" }
16- ; {method_name = " int" ; params = [] ; type_name = " int" }
17- ; {method_name = " list" ; params = [" a" ]; type_name = " list" }
18- ; {method_name = " option" ; params = [" a" ]; type_name = " option" }
19- ; {method_name = " string" ; params = [] ; type_name = " string" }
20- ; {method_name = " location" ; params = [] ; type_name = " Astlib.Location.t" }
21- ; {method_name = " loc" ; params = [" a" ]; type_name = " Astlib.Loc.t" }
12+ [ {method_name = " bool" ; tvars = [] ; type_name = " bool" }
13+ ; {method_name = " char" ; tvars = [] ; type_name = " char" }
14+ ; {method_name = " int" ; tvars = [] ; type_name = " int" }
15+ ; {method_name = " list" ; tvars = [" a" ]; type_name = " list" }
16+ ; {method_name = " option" ; tvars = [" a" ]; type_name = " option" }
17+ ; {method_name = " string" ; tvars = [] ; type_name = " string" }
18+ ; {method_name = " location" ; tvars = [] ; type_name = " Astlib.Location.t" }
19+ ; {method_name = " loc" ; tvars = [" a" ]; type_name = " Astlib.Loc.t" }
2220 ]
2321
24- let poly_signature ~signature ~params ~type_name =
25- let poly_type = Ml. poly_type ~tvars: params type_name in
26- let poly_params = List. map ~f: Ml. tvar params in
27- let fun_pre_args = List. map ~f: (fun t -> parens (signature t)) poly_params in
22+ let poly_signature ~signature ~tvars ~nodify ~type_name =
23+ let args =
24+ List. map tvars ~f: (fun tvar ->
25+ if nodify
26+ then Ml. poly_inst " node" ~args: [Ml. tvar tvar]
27+ else Ml. tvar tvar)
28+ in
29+ let poly_type = Ml. poly_inst ~args type_name in
30+ let poly_tvars = List. map ~f: Ml. tvar tvars in
31+ let fun_pre_args = List. map ~f: (fun arg -> parens (signature arg)) args in
2832 let fun_sig = Ml. arrow_type (fun_pre_args @ [signature poly_type]) in
29- let universal_quantifiers = String. concat ~sep: " " poly_params in
33+ let universal_quantifiers = String. concat ~sep: " " poly_tvars in
3034 Printf. sprintf " %s . %s" universal_quantifiers fun_sig
3135
32- let base_method_signature ~signature ~params ~type_name =
33- match params with
36+ let method_signature ~signature ~tvars ~ nodify ~type_name =
37+ match tvars with
3438 | [] -> signature type_name
35- | params -> poly_signature ~signature ~params ~type_name
39+ | tvars -> poly_signature ~signature ~tvars ~nodify ~type_name
3640
37- let declare_base_method ~signature {method_name; params ; type_name} =
38- let signature = base_method_signature ~signature ~params ~type_name in
41+ let declare_base_method ~signature {method_name; tvars ; type_name} =
42+ let signature = method_signature ~signature ~tvars ~nodify: false ~type_name in
3943 Ml. declare_method ~virtual_: true ~signature ~name: method_name ()
4044
4145(* This type describes a variables bound when deconstructing a value.
@@ -72,7 +76,7 @@ type deconstructed =
7276(* * This type describes the kind of value we're trying to traverse.
7377 - [Ast_type {node_name; targs}] means we are traversing a named type of
7478 the AST. [node_name] is the name of the AST node we
75- want to traverse and [targs] are its type arguments if it is an
79+ want to traverse and [arity] is the number of type arguments if it is an
7680 instance of a polymorphic AST type.
7781 - [Abstract] means we're inside an anonymous function and want
7882 to traverse something that isn't a named type of the AST.
@@ -82,7 +86,7 @@ type deconstructed =
8286 in an [of_concrete] call in the [Ast_type _] case.
8387 Other traversal classes can ignore the context. *)
8488type value_kind =
85- | Ast_type of {node_name : string ; targs : Astlib.Grammar .targ list }
89+ | Ast_type of {node_name : string ; arity : int }
8690 | Abstract
8791
8892(* * The type used to describe the various traversal classes and how to generate
@@ -112,13 +116,10 @@ type traversal =
112116 ; recurse : value_kind : value_kind -> deconstructed : deconstructed -> string list
113117 }
114118
115- type type_ = Concrete | T
116-
117- let node_type ~type_ ~args node_name =
118- let type_name = match type_ with T -> " t" | Concrete -> " concrete" in
119- let node_type = Printf. sprintf " %s.%s" (Ml. module_name node_name) type_name in
120- let args = List. map args ~f: string_of_targ in
121- Ml. poly_inst node_type ~args
119+ let concrete_type ~tvars node_name =
120+ let full_name = Printf. sprintf " %s.concrete" (Ml. module_name node_name) in
121+ let args = List. map tvars ~f: (fun (_ : string ) -> " _" ) in
122+ Ml. poly_inst full_name ~args
122123
123124let fun_arg type_name = Ml. id (Printf. sprintf " f%s" type_name)
124125
@@ -177,8 +178,13 @@ and recursive_call ?(nested=false) ~traversal (ty : Astlib.Grammar.ty) =
177178 let exprs = traversal.recurse ~value_kind: Abstract ~deconstructed in
178179 let args = String. concat ~sep: " " (traversal.args deconstructed.pattern) in
179180 Printf. sprintf " (fun %s -> %s)" args (String. concat ~sep: " " exprs)
180- | Instance (n , tyl ) ->
181- Printf. sprintf " self#%s" (Name. make [n] tyl)
181+ | Instance (n , targs ) ->
182+ Printf. sprintf " self#%s %s" (Name. make [n] [] )
183+ (String. concat ~sep: " "
184+ (List. map targs ~f: (fun targ ->
185+ match (targ : Astlib.Grammar.targ ) with
186+ | Tvar tvar -> fun_arg tvar
187+ | Tname tname -> Printf. sprintf " self#%s" (Ml. id tname))))
182188 | Loc ty -> parens (Printf. sprintf " self#loc %s" (recursive_call ~nested: true ty))
183189 | Location -> " self#location"
184190
@@ -200,22 +206,22 @@ let print_method_for_alias ~traversal ~value_kind ~var ty =
200206
201207let print_method_body
202208 ~traversal
203- ~targs
204209 ~node_name
210+ ~tvars
205211 ~var
206212 (decl : Astlib.Grammar.decl )
207213 =
208- let value_kind = Ast_type {node_name; targs } in
214+ let value_kind = Ast_type {node_name; arity = List. length tvars } in
209215 match decl with
210216 | Ty ty -> print_method_for_alias ~traversal ~value_kind ~var ty
211217 | Record fields ->
212218 let deconstructed = deconstruct_record ~traversal fields in
213- let concrete_type = (node_type ~type_: Concrete ~args: targs node_name) in
219+ let concrete_type = concrete_type ~tvars node_name in
214220 let exprs = traversal.recurse ~value_kind ~deconstructed in
215221 Print. println " let %s : %s = %s in" deconstructed.pattern concrete_type var;
216222 List. iter exprs ~f: (Print. println " %s" )
217223 | Variant variants ->
218- let concrete_type = (node_type ~type_: Concrete ~args: targs node_name) in
224+ let concrete_type = concrete_type ~tvars node_name in
219225 Print. println " match (%s : %s) with" var concrete_type;
220226 List. iter variants
221227 ~f: (fun variant ->
@@ -245,7 +251,7 @@ module Map = struct
245251 let return =
246252 match value_kind with
247253 | Abstract -> pattern
248- | Ast_type {node_name; targs =_ } ->
254+ | Ast_type {node_name;arity =_ } ->
249255 Printf. sprintf " %s.%s %s"
250256 (Ml. module_name node_name)
251257 " of_concrete"
@@ -337,7 +343,7 @@ module Fold_map = struct
337343 let return =
338344 match value_kind with
339345 | Abstract -> Ml. tuple [pattern; acc_var]
340- | Ast_type {node_name; targs =_ } ->
346+ | Ast_type {node_name;arity =_ } ->
341347 let mapped =
342348 Printf. sprintf " %s.%s %s"
343349 (Ml. module_name node_name)
@@ -378,7 +384,7 @@ module Map_with_context = struct
378384 let return =
379385 match value_kind with
380386 | Abstract -> pattern
381- | Ast_type {node_name; targs =_ } ->
387+ | Ast_type {node_name;arity =_ } ->
382388 Printf. sprintf " %s.%s %s"
383389 (Ml. module_name node_name)
384390 " of_concrete"
@@ -440,8 +446,8 @@ module Lift = struct
440446 let make_node_arg ~value_kind =
441447 match value_kind with
442448 | Abstract -> " None"
443- | Ast_type { node_name; targs } ->
444- sprintf " (Some (%S, %d))" node_name ( List. length targs)
449+ | Ast_type { node_name; arity } ->
450+ sprintf " (Some (%S, %d))" node_name arity
445451
446452 let recurse ~value_kind ~deconstructed =
447453 let {kind; vars; pattern} = deconstructed in
@@ -489,60 +495,54 @@ let print_to_concrete node_name =
489495 (Ml. module_name node_name)
490496 (Ml. id node_name)
491497
492- let print_method_value ~traversal ~targs ~ node_name decl =
493- let args = traversal.args (Ml. id node_name) in
494- Ml. define_anon_fun ~args (fun () ->
498+ let print_method_value ~traversal ~node_name ~ tvars decl =
499+ let args = List. map tvars ~f: fun_arg @ traversal.args (Ml. id node_name) in
500+ Ml. print_anon_fun ~args (fun () ->
495501 print_to_concrete node_name;
496- print_method_body ~traversal ~targs ~node_name ~var: " concrete" decl)
497-
498- let declare_node_methods ~env_table ~signature (node_name , kind ) =
499- match (kind : Astlib.Grammar.kind ) with
500- | Mono _ ->
501- let name = Name. make [node_name] [] in
502- let signature = signature (node_type ~type_: T ~args: [] node_name) in
503- Ml. declare_method ~signature ~name ()
504- | Poly (_ , _ ) ->
505- let envs = Poly_env. find env_table node_name in
506- List. iter envs ~f: (fun env ->
507- let args = Poly_env. args env in
508- let name = Name. make [node_name] args in
509- let signature = signature (node_type ~type_: T ~args node_name) in
510- Ml. declare_method ~signature ~name () )
511-
512- let define_node_methods ~env_table ~traversal (node_name , kind ) =
513- match (kind : Astlib.Grammar.kind ) with
514- | Mono decl ->
515- let name = Name. make [node_name] [] in
516- let signature = traversal.signature (node_type ~type_: T ~args: [] node_name) in
517- Ml. define_method ~signature name (fun () ->
518- print_method_value ~traversal ~targs: [] ~node_name decl)
519- | Poly (_ , decl ) ->
520- let envs = Poly_env. find env_table node_name in
521- List. iter envs ~f: (fun env ->
522- let targs = Poly_env. args env in
523- let name = Name. make [node_name] targs in
524- let signature = traversal.signature (node_type ~type_: T ~args: targs node_name) in
525- let subst_decl = Poly_env. subst_decl ~env decl in
526- Ml. define_method ~signature name (fun () ->
527- print_method_value ~traversal ~targs ~node_name subst_decl))
502+ print_method_body ~traversal ~node_name ~tvars ~var: " concrete" decl)
503+
504+ let declare_node_methods ~signature (node_name , kind ) =
505+ let tvars =
506+ match (kind : Astlib.Grammar.kind ) with
507+ | Mono _ -> []
508+ | Poly (tvars , _ ) -> tvars
509+ in
510+ let name = Name. make [node_name] [] in
511+ let signature =
512+ method_signature ~signature ~tvars ~nodify: true
513+ ~type_name: (Ml. module_name node_name ^ " .t" )
514+ in
515+ Ml. declare_method ~signature ~name ()
516+
517+ let define_node_methods ~traversal (node_name , kind ) =
518+ let tvars, decl =
519+ match (kind : Astlib.Grammar.kind ) with
520+ | Mono decl -> [] , decl
521+ | Poly (tvars , decl ) -> tvars, decl
522+ in
523+ let name = Name. make [node_name] [] in
524+ let signature =
525+ method_signature ~signature: traversal.signature ~tvars ~nodify: true
526+ ~type_name: (Ml. module_name node_name ^ " .t" )
527+ in
528+ Ml. define_method ~signature name (fun () ->
529+ print_method_value ~traversal ~node_name ~tvars decl)
528530
529531let declare_virtual_traversal_class ~traversal grammar =
530- let env_table = Poly_env. env_table grammar in
531532 let {class_name; params; signature; extra_methods; _} = traversal in
532533 Ml. declare_class ~virtual_: true ?params class_name (fun () ->
533534 Ml. declare_object (fun () ->
534535 Option. iter extra_methods ~f: (fun f -> f () );
535536 List. iter base_methods ~f: (declare_base_method ~signature );
536- List. iter grammar ~f: (declare_node_methods ~env_table ~ signature )))
537+ List. iter grammar ~f: (declare_node_methods ~signature )))
537538
538539let define_virtual_traversal_class ~traversal grammar =
539- let env_table = Poly_env. env_table grammar in
540540 let {class_name; params; signature; extra_methods; _} = traversal in
541541 Ml. define_class ~virtual_: true ?params class_name (fun () ->
542542 Ml. define_object ~bind_self: true (fun () ->
543543 Option. iter extra_methods ~f: (fun f -> f () );
544544 List. iter base_methods ~f: (declare_base_method ~signature );
545- List. iter grammar ~f: (define_node_methods ~env_table ~ traversal )))
545+ List. iter grammar ~f: (define_node_methods ~traversal )))
546546
547547let declare_virtual_traversal_classes grammar =
548548 List. iter traversal_classes
0 commit comments