From b7472a31c0463d228d2a7a820251f5a5bd753922 Mon Sep 17 00:00:00 2001 From: butterunderflow <azhong.934@gmail.com> Date: Sun, 4 Aug 2024 22:03:41 +0800 Subject: [PATCH 1/2] use an map to hint module expression of module type id --- lib/typing/check.ml | 71 +++---- lib/typing/env.ml | 22 ++- lib/typing/render.ml | 39 ++-- lib/typing/report.ml | 15 +- tests/cram/test_dirs/list.t/run.t | 275 ++++++++++++++-------------- tests/cram/test_dirs/simple.t/run.t | 12 +- tests/regular/render_typed_test.ml | 203 ++++++++++---------- tests/regular/typing_test.ml | 4 +- 8 files changed, 339 insertions(+), 302 deletions(-) diff --git a/lib/typing/check.ml b/lib/typing/check.ml index 4303cee..ceaf580 100644 --- a/lib/typing/check.ml +++ b/lib/typing/check.ml @@ -50,7 +50,7 @@ let rec check_expr (e : T.expr) (env : Env.t) : expr = | T.ESeq (e0, e1) -> check_seq e0 e1 env with | U.UnificationError (t0, t1) -> - Report.unification_error t0 t1 e.start_loc e.end_loc + Report.unification_error t0 t1 e.start_loc e.end_loc env | U.OccurError (tv, te) -> Report.occur_error tv te e.start_loc e.end_loc | e -> raise e @@ -374,6 +374,7 @@ and make_mt_by_scope module_dict = _; curr; history; + hints = _; } = I.MTMod { @@ -387,38 +388,42 @@ and make_mt_by_scope } and check_mod (me : T.mod_expr) (env : Env.t) : mod_expr = - match me.node with - | T.MEName name -> MEName (name, Env.lookup_module_def name env) - | T.MEStruct body -> - let body_typed, env' = check_top_levels body (Env.enter_env env) in - let scope = absorb_history env' env in - let mt = make_mt_by_scope scope in - MEStruct (body_typed, mt) - | T.MEFunctor ((name, ext_mt0), me1) -> - let mt0 = normalize_mt ext_mt0 env in - let me1_typed = check_mod me1 (Env.add_module name mt0 env) in - MEFunctor ((name, mt0), me1_typed) - | T.MEField (me, name) -> ( - let me_typed = check_mod me env in - match get_mod_ty me_typed with - | I.MTMod { mod_defs; _ } -> - MEField (me_typed, name, List.assoc name mod_defs) - | I.MTFun _ -> failwith "try get field from functor") - | T.MEApply (me0, me1) -> ( - let me0_typed = check_mod me0 env in - let me1_typed = check_mod me1 env in - let mt0 = get_mod_ty me0_typed in - let mt1 = get_mod_ty me1_typed in - match mt0 with - | I.MTMod _ -> failwith "try apply a structure" - | I.MTFun (para_mt, body_mt) -> - MEApply - (me0_typed, me1_typed, apply_functor para_mt body_mt mt1 env)) - | T.MERestrict (me, mt) -> - let me_typed = check_mod me env in - let mt = normalize_mt mt env in - let _subst = check_subtype (get_mod_ty me_typed) mt in - MERestrict (me_typed, mt, shift_mt mt env) + let me_typed = + match me.node with + | T.MEName name -> MEName (name, Env.lookup_module_def name env) + | T.MEStruct body -> + let body_typed, env' = check_top_levels body (Env.enter_env env) in + let scope = absorb_history env' env in + let mt = make_mt_by_scope scope in + MEStruct (body_typed, mt) + | T.MEFunctor ((name, ext_mt0), me1) -> + let mt0 = normalize_mt ext_mt0 env in + let me1_typed = check_mod me1 (Env.add_module name mt0 env) in + MEFunctor ((name, mt0), me1_typed) + | T.MEField (me, name) -> ( + let me_typed = check_mod me env in + match get_mod_ty me_typed with + | I.MTMod { mod_defs; _ } -> + MEField (me_typed, name, List.assoc name mod_defs) + | I.MTFun _ -> failwith "try get field from functor") + | T.MEApply (me0, me1) -> ( + let me0_typed = check_mod me0 env in + let me1_typed = check_mod me1 env in + let mt0 = get_mod_ty me0_typed in + let mt1 = get_mod_ty me1_typed in + match mt0 with + | I.MTMod _ -> failwith "try apply a structure" + | I.MTFun (para_mt, body_mt) -> + MEApply + (me0_typed, me1_typed, apply_functor para_mt body_mt mt1 env)) + | T.MERestrict (me, mt) -> + let me_typed = check_mod me env in + let mt = normalize_mt mt env in + let _subst = check_subtype (get_mod_ty me_typed) mt in + MERestrict (me_typed, mt, shift_mt mt env) + in + Env.try_record_hint me_typed env; + me_typed (* apply a functor, add returned module type's id into environment *) and apply_functor para_mt body_mt arg_mt env = diff --git a/lib/typing/env.ml b/lib/typing/env.ml index 7f7bb5e..5acb6b7 100644 --- a/lib/typing/env.ml +++ b/lib/typing/env.ml @@ -1,4 +1,5 @@ module I = Types_in +module T = Typedtree type scope = { values : (string * I.bind_ty) list; @@ -9,7 +10,8 @@ type scope = { module_dict : (int * I.mod_ty) list; (* UNUSED FIELD: designed for caching module id to their definition *) curr : int; - history : int list ref; + history : int list ref; (* module ids created in this scope *) + hints : (int * T.mod_expr) list ref; } type t = scope list @@ -72,6 +74,15 @@ let record_history id (env : t) = | [] -> failwith "neverreach" | s :: _ -> s.history := id :: !(s.history) +let try_record_hint me_typed (env : t) = + match env with + | [] -> failwith "neverreach" + | s :: _ -> ( + let mt = T.get_mod_ty me_typed in + match mt with + | I.MTMod { id; _ } -> s.hints := (id, me_typed) :: !(s.hints) + | _ -> ()) + let record_all_history ids (env : t) = match env with | [] -> failwith "neverreach" @@ -119,6 +130,14 @@ let rec lookup_type_def tn env = | Some def -> (s.curr, def) | None -> lookup_type_def tn env') +let rec lookup_hint id env = + match env with + | [] -> None + | s :: env' -> ( + match List.assoc_opt id !(s.hints) with + | None -> lookup_hint id env' + | Some me -> Some me) + let get_curr env = match env with | s :: _ -> s.curr @@ -134,6 +153,7 @@ let init_scope () = module_dict = []; curr = 0; history = ref []; + hints = ref []; } let init () = [ init_scope () ] diff --git a/lib/typing/render.ml b/lib/typing/render.ml index 9999f73..b09cee6 100644 --- a/lib/typing/render.ml +++ b/lib/typing/render.ml @@ -174,7 +174,7 @@ module MakePP (Config : PPConfig) = struct Fmt.fprintf fmt "@]@])") else content_printer () - and pp_mod fmt me = + and pp_mod fmt ?(env : Env.t option) me = match me with | MEName (name, _) -> Fmt.pp_print_string fmt name | MEStruct (tops, mt) -> @@ -192,19 +192,19 @@ module MakePP (Config : PPConfig) = struct Fmt.fprintf fmt "@[<v 2>functor (%s : " name; pp_mod_ty fmt mt; Fmt.fprintf fmt ")@\n-> @\n"; - pp_mod fmt me; + pp_mod fmt ?env me; Fmt.fprintf fmt "@]" | MEField (me, name, _) -> Fmt.fprintf fmt "@["; - pp_mod fmt me; + pp_mod fmt ?env me; Fmt.fprintf fmt ".%s" name; Fmt.fprintf fmt "@]" | MEApply (me0, me1, mt) -> pp_is_mod_ty fmt Config.show_mod_ty (fun _ -> - pp_mod fmt me0; + pp_mod fmt ?env me0; Fmt.fprintf fmt "("; - pp_mod fmt me1; + pp_mod fmt ?env me1; Fmt.fprintf fmt ")") mt | MERestrict (me, mt, mt') -> @@ -212,7 +212,7 @@ module MakePP (Config : PPConfig) = struct (fun _ -> Fmt.fprintf fmt "("; Fmt.fprintf fmt "@["; - pp_mod fmt me; + pp_mod fmt ?env me; Fmt.fprintf fmt " : "; Fmt.fprintf fmt "@["; pp_mod_ty fmt mt; @@ -298,12 +298,12 @@ module MakePP (Config : PPConfig) = struct pp_ty fmt te; Fmt.fprintf fmt "@]" - and pp_ty fmt te = + and pp_ty fmt ?env te = match te with | I.TConsI ((id, name), tes) -> Fmt.fprintf fmt "@["; (match tes with - | [] -> Fmt.fprintf fmt "()" + | [] -> Fmt.fprintf fmt "()@ " | te0 :: tes -> Fmt.fprintf fmt "("; pp_ty fmt te0; @@ -312,8 +312,14 @@ module MakePP (Config : PPConfig) = struct Fmt.fprintf fmt ",@ "; pp_ty fmt te) tes; - Fmt.fprintf fmt ")"); - Fmt.fprintf fmt "@ %d.%s" id name; + Fmt.fprintf fmt ")@ "); + (match (Option.bind env (Env.lookup_hint id), id) with + | Some me, _ -> + pp_mod fmt ?env me; + Fmt.fprintf fmt "." + | None, 0 (* 0 is default root module's structure type id *) -> () + | None, _ -> Fmt.fprintf fmt "%d." id); + Fmt.fprintf fmt "%s" name; Fmt.fprintf fmt "@]" | I.TVarI { contents = I.Unbound tv } -> Fmt.fprintf fmt "{%s}" (Ident.show_ident tv) @@ -455,10 +461,10 @@ module MakePP (Config : PPConfig) = struct prog; Format.pp_print_flush fmt () - let pp_str_of_ty ty = + let pp_str_of_ty ?env ty = let buf = Buffer.create 10 in let formatter = Fmt.formatter_of_buffer buf in - pp_ty formatter ty; + pp_ty formatter ?env ty; Fmt.pp_print_flush formatter (); Buffer.contents buf end @@ -471,7 +477,16 @@ module ShowAllConfig : PPConfig = struct let show_mod_ty = true end +module ShowNothingConfig : PPConfig = struct + let show_const_ty = false + + let show_bind_ty = false + + let show_mod_ty = false +end + module DefaultPP = MakePP (ShowAllConfig) +module NoTypeHintPP = MakePP (ShowNothingConfig) let default_dbg prog = let buf = Buffer.create 50 in diff --git a/lib/typing/report.ml b/lib/typing/report.ml index 04b1a65..7e00cbf 100644 --- a/lib/typing/report.ml +++ b/lib/typing/report.ml @@ -1,15 +1,16 @@ module T = Types_in -module PP = Render.DefaultPP +module PP = Render.NoTypeHintPP type err = | UnificationError of (T.ty * T.ty * Lexing.position * Lexing.position) (* error reportings *) (* todo: support error tolerable type checking *) -exception UnificationError of T.ty * T.ty * Lexing.position * Lexing.position +exception + UnificationError of T.ty * T.ty * Lexing.position * Lexing.position * Env.t -let unification_error t0 t1 loc1 loc2 = - raise (UnificationError (t0, t1, loc1, loc2)) +let unification_error t0 t1 loc1 loc2 env = + raise (UnificationError (t0, t1, loc1, loc2, env)) exception ComponentInCompatible of string * T.bind_ty * T.bind_ty @@ -33,10 +34,10 @@ let unknown_location () = Printf.printf "At some unknown location: " let wrap_with_error_report f = try Some (f ()) with - | UnificationError (t0, t1, start, last) -> + | UnificationError (t0, t1, start, last, env) -> print_code_range start last; - Printf.printf "Can't unify `%s` with `%s`" (PP.pp_str_of_ty t0) - (PP.pp_str_of_ty t1); + Printf.printf "Can't unify `%s` with `%s`" (PP.pp_str_of_ty ~env t0) + (PP.pp_str_of_ty ~env t1); None | OccurError (tv, te, start, last) -> print_code_range start last; diff --git a/tests/cram/test_dirs/list.t/run.t b/tests/cram/test_dirs/list.t/run.t index 2dd4572..e8e6a82 100644 --- a/tests/cram/test_dirs/list.t/run.t +++ b/tests/cram/test_dirs/list.t/run.t @@ -4,180 +4,173 @@ $ cat test_list.typed - external println_int : (() 0.int - ->() 0.unit)= "ff_builtin_println_int" + external println_int : (() int + ->() unit)= "ff_builtin_println_int" - external println_string : (() 0.string - ->() 0.unit)= "ff_builtin_println_str" + external println_string : (() string + ->() unit)= "ff_builtin_println_str" - external add : (() 0.int - ->(() 0.int - ->() 0.int))= "ff_builtin_add" + external add : (() int + ->(() int + ->() int))= "ff_builtin_add" type ('a/0) list = | Cons of (['a/0] - * (['a/0]) 0.list) + * (['a/0]) list) | Nil let cons = fun x -> fun y -> (Cons[0] is (({{'_t/1}} - * ({{'_t/1}}) 0.list) - ->({{'_t/1}}) 0.list)) ((x is {'_t/1}), (y is {({{'_t/1}}) - 0.list})) - - let lst = (cons is ({() 0.int} - ->(({() 0.int}) 0.list - ->({() 0.int}) 0.list))) (3 is () 0.int) (cons is ( - {() 0.int} - ->( - ({ - () 0.int}) - 0.list - -> - ({ - () 0.int}) - 0.list))) ( - 2 is () 0.int) (cons is ({() 0.int} - ->(({() 0.int}) 0.list - ->({() 0.int}) 0.list))) (1 is () 0.int) ( - Nil[1] is ({() 0.int}) 0.list) + * ({{'_t/1}}) list) + ->({{'_t/1}}) list)) ((x is {'_t/1}), (y is {({{'_t/1}}) + list})) + + let lst = (cons is ({() int} + ->(({() int}) list + ->({() int}) list))) (3 is () int) (cons is ( + {() int} + ->(({() int}) + list + ->({ + () int}) + list))) ( + 2 is () int) (cons is ({() int} + ->(({() int}) list + ->({() int}) list))) (1 is () int) (Nil[1] is + ({() int}) + list) let rec iter = fun lst -> fun f -> - match (lst is {({{'_t/20}}) 0.list}) with + match (lst is {({{'_t/20}}) list}) with | (Cons[0] ((x is {'_t/20}) - * (lst is {({{'_t/20}}) 0.list}))) -> + * (lst is {({{'_t/20}}) list}))) -> (f is {({'_t/20} - ->{() 0.unit})}) (x is {'_t/20}) ; - (iter is {(({'_t/20}) 0.list + ->{() unit})}) (x is {'_t/20}) ; + (iter is {(({'_t/20}) list ->{(({'_t/20} - ->() 0.unit) - ->{{() 0.unit}})})}) (lst is ({'_t/20}) - 0.list) ( + ->() unit) + ->{{() unit}})})}) (lst is ({'_t/20}) + list) ( f is ({'_t/20} - ->() 0.unit)) - | Nil -> (() is () 0.unit) + ->() unit)) + | Nil -> (() is () unit) let print_int_lst = fun lst -> - (iter is (({() 0.int}) 0.list - ->(({() 0.int} - ->() 0.unit) - ->() 0.unit))) (lst is {({() 0.int}) 0.list}) (println_int is ( - () 0.int - ->() 0.unit)) + (iter is (({() int}) list + ->(({() int} + ->() unit) + ->() unit))) (lst is {({() int}) list}) (println_int is ( + () int + ->() unit)) - let result = (print_int_lst is ((() 0.int) 0.list - ->() 0.unit)) (lst is (() 0.int) 0.list) + let result = (print_int_lst is ((() int) list + ->() unit)) (lst is (() int) list) let rec map = fun lst -> fun f -> - match (lst is {({{'_t/36}}) 0.list}) with - | (Cons[0] - ((x is {'_t/36}) - * (lst is {({{'_t/36}}) 0.list}))) -> + match (lst is {({{'_t/36}}) list}) with + | (Cons[0] ((x is {'_t/36}) + * (lst is {({{'_t/36}}) list}))) -> (cons is ({{'ret/39}} - ->(({{'ret/39}}) 0.list - ->({{'ret/39}}) 0.list))) (f is {({'_t/36} - ->{'ret/39})}) ( - x is {'_t/36}) (map is {(({'_t/36}) 0.list + ->(({{'ret/39}}) list + ->({{'ret/39}}) list))) (f is {({'_t/36} + ->{'ret/39})}) ( + x is {'_t/36}) (map is {(({'_t/36}) list ->{(({'_t/36} ->{'ret/39}) - ->{({{'ret/39}}) 0.list})})}) ( - lst is ({'_t/36}) 0.list) (f is ({'_t/36} - ->{'ret/39})) - | Nil -> (Nil[1] is ({{'ret/39}}) 0.list) - - let result = (print_int_lst is ((() 0.int) 0.list - ->() 0.unit)) (map is (({() 0.int}) 0.list - ->(({() 0.int} - ->{() 0.int}) - ->({() 0.int}) - 0.list))) ( - lst is (() 0.int) 0.list) (add is (() 0.int - ->(() 0.int - ->() 0.int))) (7 is () 0.int) - - let lst = (cons is ({(() 0.int - * () 0.int)} - ->(({(() 0.int - * () 0.int)}) 0.list - ->({(() 0.int - * () 0.int)}) 0.list))) ((2 is () 0.int), ( - 4 is () 0.int)) (cons is ({(() 0.int - * () 0.int)} - ->(({(() 0.int - * () 0.int)}) 0.list - ->({(() 0.int - * () 0.int)}) 0.list))) ((1 is () 0.int), ( - 2 is () 0.int)) (Nil[1] is ({(() 0.int - * () 0.int)}) 0.list) + ->{({{'ret/39}}) list})})}) ( + lst is ({'_t/36}) list) (f is ({'_t/36} + ->{'ret/39})) + | Nil -> (Nil[1] is ({{'ret/39}}) list) + + let result = (print_int_lst is ((() int) list + ->() unit)) (map is (({() int}) list + ->(({() int} + ->{() int}) + ->({() int}) list))) ( + lst is (() int) list) (add is (() int + ->(() int + ->() int))) (7 is () int) + + let lst = (cons is ({(() int + * () int)} + ->(({(() int + * () int)}) list + ->({(() int + * () int)}) list))) ((2 is () int), (4 is + () int)) ( + cons is ({(() int + * () int)} + ->(({(() int + * () int)}) list + ->({(() int + * () int)}) list))) ((1 is () int), (2 is () int)) ( + Nil[1] is ({(() int + * () int)}) list) let print_int_tu = fun tu -> - match (tu is {({() 0.int} - * {() 0.int})}) with - | ((x is {() 0.int}) - * (y is {() 0.int})) -> - (println_int is (() 0.int - ->() 0.unit)) (x is {() 0.int}) ; - (println_int is (() 0.int - ->() 0.unit)) (y is {() 0.int}) + match (tu is {({() int} + * {() int})}) with + | ((x is {() int}) + * (y is {() int})) -> + (println_int is (() int + ->() unit)) (x is {() int}) ; + (println_int is (() int + ->() unit)) (y is {() int}) let print_int_tu_lst = fun lst -> - (iter is (({(() 0.int - * () 0.int)}) 0.list - ->(({(() 0.int - * () 0.int)} - ->() 0.unit) - ->() 0.unit))) (lst is {({(() 0.int - * () 0.int)}) 0.list}) ( - print_int_tu is ((() 0.int - * () 0.int) - ->() 0.unit)) - - let result = (print_int_tu_lst is (((() 0.int - * () 0.int)) 0.list - ->() 0.unit)) (lst is ((() 0.int - * () 0.int)) - 0.list) + (iter is (({(() int + * () int)}) list + ->(({(() int + * () int)} + ->() unit) + ->() unit))) (lst is {({(() int + * () int)}) list}) (print_int_tu is ( + (() int + * () int) + ->() unit)) + + let result = (print_int_tu_lst is (((() int + * () int)) list + ->() unit)) (lst is ((() int + * () int)) + list) let tu_adder = fun tu -> - match (tu is {({() 0.int} - * {() 0.int})}) with - | ((x is {() 0.int}) - * (y is {() 0.int})) -> - ((add is (() 0.int - ->(() 0.int - ->() 0.int))) (x is {() 0.int}) (1 is () 0.int), (add is ( - () 0.int - ->( - () 0.int - -> - () 0.int))) ( - y is {() 0.int}) (1 is () 0.int)) - - let result = (print_int_tu_lst is (((() 0.int - * () 0.int)) 0.list - ->() 0.unit)) (map is (({(() 0.int - * () 0.int)}) - 0.list - ->(({(() 0.int - * - () 0.int)} - ->{( - () 0.int - * () 0.int)}) - ->({( - () 0.int - * - () 0.int)}) - 0.list))) ( - lst is ((() 0.int - * () 0.int)) 0.list) (tu_adder is ((() 0.int - * () 0.int) - ->(() 0.int - * () 0.int))) + match (tu is {({() int} + * {() int})}) with + | ((x is {() int}) + * (y is {() int})) -> + ((add is (() int + ->(() int + ->() int))) (x is {() int}) (1 is () int), (add is ( + () int + ->(() int + ->() int))) ( + y is {() int}) (1 is () int)) + + let result = (print_int_tu_lst is (((() int + * () int)) list + ->() unit)) (map is (({(() int + * () int)}) + list + ->(({(() int + * () int)} + ->{(() int + * + () int)}) + ->({(() int + * + () int)}) + list))) ( + lst is ((() int + * () int)) list) (tu_adder is ((() int + * () int) + ->(() int + * () int))) $ $FF test_list.fun diff --git a/tests/cram/test_dirs/simple.t/run.t b/tests/cram/test_dirs/simple.t/run.t index e802749..f48ed8f 100644 --- a/tests/cram/test_dirs/simple.t/run.t +++ b/tests/cram/test_dirs/simple.t/run.t @@ -196,19 +196,19 @@ $ cat simple1.typed - let x = (1 is () 0.int) + let x = (1 is () int) - let y = (1 is () 0.int) + let y = (1 is () int) let z = fun x -> - (y is () 0.int) + (y is () int) let w = fun x -> - (0 is () 0.int) + (0 is () int) let m = fun x -> - (w is ({() 0.int} - ->() 0.int)) (1 is () 0.int) + (w is ({() int} + ->() int)) (1 is () int) $ $FF simple.fun diff --git a/tests/regular/render_typed_test.ml b/tests/regular/render_typed_test.ml index ade10a5..295f481 100644 --- a/tests/regular/render_typed_test.ml +++ b/tests/regular/render_typed_test.ml @@ -12,11 +12,12 @@ let%expect_test "Test: pretty print typed expression" = Format.pp_print_flush fmt () in print_typed "1"; - [%expect {| (1 is () 0.int) |}]; + [%expect {| (1 is () int) |}]; print_typed {|let x = 1 in x|}; [%expect {| - let x = (1 is () 0.int) - in (x is () 0.int) |}]; + let x = (1 is () int) + in (x is () int) + |}]; print_typed {|fun x -> let y = x in y |}; [%expect @@ -30,16 +31,16 @@ let%expect_test "Test: pretty print typed expression" = [%expect {| if - (true is () 0.bool) + (true is () bool) then - (1 is () 0.int) + (1 is () int) else - (2 is () 0.int) |}]; + (2 is () int) + |}]; print_typed {| (1, 2, 3,4) |}; [%expect - {| - ((1 is () 0.int), (2 is () 0.int), (3 is () 0.int), (4 is () 0.int)) |}]; + {| ((1 is () int), (2 is () int), (3 is () int), (4 is () int)) |}]; print_typed {| @@ -50,12 +51,13 @@ let%expect_test "Test: pretty print typed expression" = [%expect {| let rec f = fun x -> - (x is {() 0.int}) + (x is {() int}) and y = fun x -> - (f is ({() 0.int} - ->{() 0.int})) (1 is () 0.int) - in (f is (() 0.int - ->() 0.int)) (1 is () 0.int) |}] + (f is ({() int} + ->{() int})) (1 is () int) + in (f is (() int + ->() int)) (1 is () int) + |}] let%expect_test "Test: pretty print typed program" = let print_typed str = @@ -84,17 +86,18 @@ let%expect_test "Test: pretty print typed program" = [%expect {| type () int_l = - | Cons of () 0.int + | Cons of () int | Nil - let co = (Cons[0] is (() 0.int - ->() 0.int_l)) (1 is () 0.int) + let co = (Cons[0] is (() int + ->() int_l)) (1 is () int) - let c = (Nil[1] is () 0.int_l) + let c = (Nil[1] is () int_l) - let f = match (c is () 0.int_l) with - | (Cons[0] (x is () 0.int)) -> (x is () 0.int) - | Nil -> (0 is () 0.int) |}]; + let f = match (c is () int_l) with + | (Cons[0] (x is () int)) -> (x is () int) + | Nil -> (0 is () int) + |}]; print_typed {| @@ -331,7 +334,7 @@ let%expect_test "Test: pretty print typed program" = type () t = | Nil - let z = (1 is () 0.int) + let z = (1 is () int) let x = (Nil[0] is () 2.t) @@ -341,7 +344,7 @@ let%expect_test "Test: pretty print typed program" = val x : () 2.t - val z : () 0.int + val z : () int constr Nil[0] : () 2.t @@ -442,9 +445,9 @@ module MMM = (M(F).K : I) id = 1 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -456,11 +459,11 @@ module MMM = (M(F).K : I) id = 2 - val z : () 0.int + val z : () int - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -470,21 +473,21 @@ module MMM = (M(F).K : I) module MJ = (struct - let x = (1 is () 0.int) + let x = (1 is () int) - let y = (1 is () 0.int) + let y = (1 is () int) - let z = (1 is () 0.int) + let z = (1 is () int) end is sig id = 3 - val z : () 0.int + val z : () int - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -494,17 +497,17 @@ module MMM = (M(F).K : I) module Simple = (struct - let x = (1 is () 0.int) + let x = (1 is () int) - let y = (2 is () 0.int) + let y = (2 is () int) end is sig id = 4 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -516,9 +519,9 @@ module MMM = (M(F).K : I) id = 1 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -529,9 +532,9 @@ module MMM = (M(F).K : I) id = 1 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -545,9 +548,9 @@ module MMM = (M(F).K : I) id = 6 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -559,9 +562,9 @@ module MMM = (M(F).K : I) id = 7 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -576,9 +579,9 @@ module MMM = (M(F).K : I) id = 7 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -589,9 +592,9 @@ module MMM = (M(F).K : I) id = 6 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -610,9 +613,9 @@ module MMM = (M(F).K : I) id = 1 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -621,25 +624,25 @@ module MMM = (M(F).K : I) -> (((struct - let x = (1 is () 0.int) + let x = (1 is () int) - let y = (1 is () 0.int) + let y = (1 is () int) - let z = (1 is () 0.int) + let z = (1 is () int) - let w = (2 is () 0.int) + let w = (2 is () int) end is sig id = 8 - val w : () 0.int + val w : () int - val z : () 0.int + val z : () int - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -648,11 +651,11 @@ module MMM = (M(F).K : I) id = 2 - val z : () 0.int + val z : () int - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -661,11 +664,11 @@ module MMM = (M(F).K : I) id = 9 - val z : () 0.int + val z : () int - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -681,9 +684,9 @@ module MMM = (M(F).K : I) id = 11 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -694,9 +697,9 @@ module MMM = (M(F).K : I) id = 12 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -712,9 +715,9 @@ module MMM = (M(F).K : I) id = 1 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -723,9 +726,9 @@ module MMM = (M(F).K : I) id = 13 - val y : () 0.int + val y : () int - val x : () 0.int + val x : () int Owned Modules = { } @@ -795,10 +798,10 @@ module MMM = (M(F).K : I) print_typed {| let x = ();();();1 |}; [%expect {| - let x = (() is () 0.unit) ; - (() is () 0.unit) ; - (() is () 0.unit) ; - (1 is () 0.int) + let x = (() is () unit) ; + (() is () unit) ; + (() is () unit) ; + (1 is () int) |}]; (* constructor accessed by path *) @@ -824,7 +827,7 @@ module MMM = (M(F).K : I) type () t = | Nil - | Integer of () 0.int + | Integer of () int end is sig @@ -832,12 +835,12 @@ module MMM = (M(F).K : I) constr Nil[0] : () 1.t - constr Integer[1] : (() 0.int + constr Integer[1] : (() int ->() 1.t) type () t = | Nil - | Integer of () 0.int + | Integer of () int Owned Modules = { } @@ -847,8 +850,8 @@ module MMM = (M(F).K : I) let c = (C.Nil[0] is () 1.t) let result = match (c is () 1.t) with - | Nil -> (() is () 0.unit) - | (Integer[1] (i is () 0.int)) -> (() is () 0.unit) + | Nil -> (() is () unit) + | (Integer[1] (i is () int)) -> (() is () unit) |}]; print_typed @@ -872,25 +875,25 @@ module MMM = (M(F).K : I) {| type () list = | Nil - | Cons of (() 0.int - * (() 0.int) 0.list) + | Cons of (() int + * (() int) list) type ('a/0, 'b/0) tu = | Tu of (['b/0] * ['a/0]) - let x = (Tu[0] is (({() 0.int} - * {() 0.string}) - ->({() 0.string}, {() 0.int}) 0.tu)) ((1 is () 0.int), ( - ""c"" is () 0.string)) + let x = (Tu[0] is (({() int} + * {() string}) + ->({() string}, {() int}) tu)) ((1 is () int), (""c"" is + () string)) - let result1 = match (x is (() 0.string, () 0.int) 0.tu) with - | (Tu[0] ((a is {() 0.int}) - * (b is {() 0.string}))) -> (a is () 0.int) + let result1 = match (x is (() string, () int) tu) with + | (Tu[0] ((a is {() int}) + * (b is {() string}))) -> (a is () int) - let result2 = match (x is (() 0.string, () 0.int) 0.tu) with - | (Tu[0] ((a is {() 0.int}) - * (b is {() 0.string}))) -> (b is () 0.string) + let result2 = match (x is (() string, () int) tu) with + | (Tu[0] ((a is {() int}) + * (b is {() string}))) -> (b is () string) |}]; print_typed @@ -1009,21 +1012,21 @@ module MMM = (M(F).K : I) -> (struct - type t = () 0.int + type t = () int - type s = () 0.int + type s = () int - let x = (1 is () 0.int) + let x = (1 is () int) end is sig id = 4 - val x : () 0.int + val x : () int - type s = () 0.int + type s = () int - type t = () 0.int + type t = () int Owned Modules = { } diff --git a/tests/regular/typing_test.ml b/tests/regular/typing_test.ml index 769fcb7..9a330fe 100644 --- a/tests/regular/typing_test.ml +++ b/tests/regular/typing_test.ml @@ -1144,7 +1144,7 @@ let%expect_test "Error reporting test" = let y = true let z = x = y |}; - [%expect {| 4:13-4:13 Can't unify `() 0.int` with `() 0.bool` |}]; + [%expect {| 4:13-4:13 Can't unify `() int` with `() bool` |}]; print_typed {| @@ -1256,7 +1256,7 @@ let%expect_test "Error reporting test" = let z = Y1.y = Y2.y |}; - [%expect {| 25:21-25:21 Can't unify `() 6.t` with `() 7.t` |}]; + [%expect {| 25:21-25:21 Can't unify `() Y1.t` with `() Y2.t` |}]; print_typed {| module type I = sig From 90768871b289a7ee689cab9cfda33343201ea931 Mon Sep 17 00:00:00 2001 From: butterunderflow <azhong.934@gmail.com> Date: Sun, 4 Aug 2024 22:10:42 +0800 Subject: [PATCH 2/2] refactor: avoid huge let expression factor out `check_mod` to smaller parts --- lib/typing/check.ml | 72 ++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/lib/typing/check.ml b/lib/typing/check.ml index ceaf580..91b0b36 100644 --- a/lib/typing/check.ml +++ b/lib/typing/check.ml @@ -390,41 +390,53 @@ and make_mt_by_scope and check_mod (me : T.mod_expr) (env : Env.t) : mod_expr = let me_typed = match me.node with - | T.MEName name -> MEName (name, Env.lookup_module_def name env) - | T.MEStruct body -> - let body_typed, env' = check_top_levels body (Env.enter_env env) in - let scope = absorb_history env' env in - let mt = make_mt_by_scope scope in - MEStruct (body_typed, mt) + | T.MEName name -> check_mod_name name env + | T.MEStruct body -> check_struct body env | T.MEFunctor ((name, ext_mt0), me1) -> - let mt0 = normalize_mt ext_mt0 env in - let me1_typed = check_mod me1 (Env.add_module name mt0 env) in - MEFunctor ((name, mt0), me1_typed) - | T.MEField (me, name) -> ( - let me_typed = check_mod me env in - match get_mod_ty me_typed with - | I.MTMod { mod_defs; _ } -> - MEField (me_typed, name, List.assoc name mod_defs) - | I.MTFun _ -> failwith "try get field from functor") - | T.MEApply (me0, me1) -> ( - let me0_typed = check_mod me0 env in - let me1_typed = check_mod me1 env in - let mt0 = get_mod_ty me0_typed in - let mt1 = get_mod_ty me1_typed in - match mt0 with - | I.MTMod _ -> failwith "try apply a structure" - | I.MTFun (para_mt, body_mt) -> - MEApply - (me0_typed, me1_typed, apply_functor para_mt body_mt mt1 env)) - | T.MERestrict (me, mt) -> - let me_typed = check_mod me env in - let mt = normalize_mt mt env in - let _subst = check_subtype (get_mod_ty me_typed) mt in - MERestrict (me_typed, mt, shift_mt mt env) + check_functor name ext_mt0 me1 env + | T.MEField (me, name) -> check_mod_field me name env + | T.MEApply (me0, me1) -> check_mod_apply me0 me1 env + | T.MERestrict (me, mt) -> check_mod_restrict me mt env in Env.try_record_hint me_typed env; me_typed +and check_mod_name name env = MEName (name, Env.lookup_module_def name env) + +and check_struct body env = + let body_typed, env' = check_top_levels body (Env.enter_env env) in + let scope = absorb_history env' env in + let mt = make_mt_by_scope scope in + MEStruct (body_typed, mt) + +and check_functor name ext_mt0 me1 env = + let mt0 = normalize_mt ext_mt0 env in + let me1_typed = check_mod me1 (Env.add_module name mt0 env) in + MEFunctor ((name, mt0), me1_typed) + +and check_mod_field me name env = + let me_typed = check_mod me env in + match get_mod_ty me_typed with + | I.MTMod { mod_defs; _ } -> + MEField (me_typed, name, List.assoc name mod_defs) + | I.MTFun _ -> failwith "try get field from functor" + +and check_mod_apply me0 me1 env = + let me0_typed = check_mod me0 env in + let me1_typed = check_mod me1 env in + let mt0 = get_mod_ty me0_typed in + let mt1 = get_mod_ty me1_typed in + match mt0 with + | I.MTMod _ -> failwith "try apply a structure" + | I.MTFun (para_mt, body_mt) -> + MEApply (me0_typed, me1_typed, apply_functor para_mt body_mt mt1 env) + +and check_mod_restrict me mt env = + let me_typed = check_mod me env in + let mt = normalize_mt mt env in + let _subst = check_subtype (get_mod_ty me_typed) mt in + MERestrict (me_typed, mt, shift_mt mt env) + (* apply a functor, add returned module type's id into environment *) and apply_functor para_mt body_mt arg_mt env = let subst = check_subtype arg_mt para_mt in