From 8bff1854f10e9b41a44b0465db3cc6bc031fdce5 Mon Sep 17 00:00:00 2001 From: Tobias Mock Date: Mon, 30 Sep 2024 22:39:39 +0200 Subject: [PATCH] Allow functors without parameters --- lib/module.ml | 35 ++++++++++++++++++----------------- lib/parser.mly | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/lib/module.ml b/lib/module.ml index 926a4b95..d5e52ab0 100644 --- a/lib/module.ml +++ b/lib/module.ml @@ -344,8 +344,10 @@ let rec add_to_env env foreign (mname, m) = | Error () -> raise (Error (loc, "Cannot add module"))) | Some cached -> Env.add_module ~key (envmodule_of_cached mname cached) env) - | Mapplied_functor (loc, key, p, m) -> - register_applied_functor env loc key p m + | Mapplied_functor (loc, key, p, m) -> ( + match register_applied_functor env loc key p m with + | Ok env -> env + | Error () -> raise (Error (loc, "Cannot apply functor"))) | Mfunctor (loc, key, ps, items, m) -> ( let mname = Path.append key mname in match register_functor env loc mname ps items m with @@ -493,21 +495,20 @@ and register_functor env loc mname params body modul : (Env.t, unit) Result.t = Ok env and register_applied_functor env loc key mname modul = - (* It's okay to apply a functor multiple times *) - let cached = - match Hashtbl.find_opt module_cache mname with - | Some cached -> envmodule_of_cached mname cached - | None -> - let scope = make_scope env loc None mname modul in - (* Externals need to be added again with the correct user name *) - List.iter - (function Mext (_, t, n, c) -> add_ext_item ~mname t n c | _ -> ()) - modul.i; - let cached = Cached (Clocal mname, scope, modul) in - Hashtbl.add module_cache mname cached; - envmodule_of_cached mname cached - in - Env.add_module ~key cached env + (* Modules must be unique *) + if Hashtbl.mem module_cache mname then Error () + else + let cached = + let scope = make_scope env loc None mname modul in + (* Externals need to be added again with the correct user name *) + List.iter + (function Mext (_, t, n, c) -> add_ext_item ~mname t n c | _ -> ()) + modul.i; + let cached = Cached (Clocal mname, scope, modul) in + Hashtbl.add module_cache mname cached; + envmodule_of_cached mname cached + in + Ok (Env.add_module ~key cached env) let find_module env loc name = (* We first search the env for local modules. Then we try read the module the normal way *) diff --git a/lib/parser.mly b/lib/parser.mly index 230f6283..571ee160 100644 --- a/lib/parser.mly +++ b/lib/parser.mly @@ -168,7 +168,7 @@ path_with_loc: | path = use_path { $loc, path } functor_: - | Functor; name = module_decl; Lpar; params = separated_nonempty_list(Comma, functor_param); Rpar; + | Functor; name = module_decl; Lpar; params = separated_list(Comma, functor_param); Rpar; Lcurly; items = separated_nonempty_list(Semicolon, top_item); Rcurly { Functor (name, params, items) }