Simplification: store paths in Uids

rather than scattered in structures

The context is still hierarchical for defs though, so one needs to retrieve the
path to lookup in the correct context for info. Exceptions are enums and struct
defs, which are re-exposed at toplevel.
This commit is contained in:
Louis Gesbert 2023-08-30 17:49:29 +02:00
parent b5baa91a2e
commit 7db63e5f78
36 changed files with 382 additions and 331 deletions

View File

@ -58,13 +58,14 @@ module Make (X : Info) () : Id with type info = X.info = struct
{ id = !counter; info } { id = !counter; info }
let get_info (uid : t) : X.info = uid.info let get_info (uid : t) : X.info = uid.info
let format (fmt : Format.formatter) (x : t) : unit = X.format fmt x.info
let hash (x : t) : int = x.id let hash (x : t) : int = x.id
module Set = Set.Make (Ordering) module Set = Set.Make (Ordering)
module Map = Map.Make (Ordering) module Map = Map.Make (Ordering)
end end
(* - Raw idents - *)
module MarkedString = struct module MarkedString = struct
type info = string Mark.pos type info = string Mark.pos
@ -75,3 +76,54 @@ module MarkedString = struct
end end
module Gen () = Make (MarkedString) () module Gen () = Make (MarkedString) ()
(* - Modules, paths and qualified idents - *)
module Module = struct
include String
let to_string m = m
let format ppf m = Format.fprintf ppf "@{<blue>%s@}" m
let of_string m = m
end
(* TODO: should probably be turned into an uid once we implement module import
directives; that will incur an additional resolution work on all paths
though ([module Module = Gen ()]) *)
module Path = struct
type t = Module.t list
let format ppf p =
Format.pp_print_list
~pp_sep:(fun _ () -> ())
(fun ppf m ->
Format.fprintf ppf "%a@{<cyan>.@}" Module.format m)
ppf p
let to_string p = String.concat "." p
let equal = List.equal String.equal
let compare = List.compare String.compare
end
module QualifiedMarkedString = struct
type info = Path.t * MarkedString.info
let to_string (p, i) =
Format.asprintf "%a%a" Path.format p MarkedString.format i
let format fmt (p, i) =
Path.format fmt p; MarkedString.format fmt i
let equal (p1, i1) (p2, i2) =
Path.equal p1 p2 && MarkedString.equal i1 i2
let compare (p1, i1) (p2, i2) =
match Path.compare p1 p2 with
| 0 -> MarkedString.compare i1 i2
| n -> n
end
module Gen_qualified () = struct
include Make (QualifiedMarkedString) ()
let fresh path t = fresh (path, t)
let path t = fst (get_info t)
let get_info t = snd (get_info t)
end

View File

@ -60,3 +60,35 @@ module Make (X : Info) () : Id with type info = X.info
module Gen () : Id with type info = MarkedString.info module Gen () : Id with type info = MarkedString.info
(** Shortcut for creating a kind of uids over marked strings *) (** Shortcut for creating a kind of uids over marked strings *)
(** {2 Handling of Uids with additional path information} *)
module Module: sig
type t = private string (* TODO: this will become an uid at some point *)
val to_string: t -> string
val format: Format.formatter -> t -> unit
val equal : t -> t-> bool
val compare : t -> t -> int
val of_string: string -> t
module Set : Set.S with type elt = t
module Map : Map.S with type key = t
end
module Path: sig
type t = Module.t list
val to_string: t -> string
val format: Format.formatter -> t -> unit
val equal : t -> t-> bool
val compare : t -> t -> int
end
(** Same as [Gen] but also registers path information *)
module Gen_qualified () : sig
include Id with type info = Path.t * MarkedString.info
val fresh : Path.t -> MarkedString.info -> t
val path : t -> Path.t
val get_info : t -> MarkedString.info
end

View File

@ -31,7 +31,7 @@ type scope_input_var_ctx = {
type 'm scope_ref = type 'm scope_ref =
| Local_scope_ref of 'm Ast.expr Var.t | Local_scope_ref of 'm Ast.expr Var.t
| External_scope_ref of path * ScopeName.t Mark.pos | External_scope_ref of ScopeName.t Mark.pos
type 'm scope_sig_ctx = { type 'm scope_sig_ctx = {
scope_sig_local_vars : scope_var_ctx list; (** List of scope variables *) scope_sig_local_vars : scope_var_ctx list; (** List of scope variables *)
@ -73,15 +73,12 @@ let pos_mark_mk (type a m) (e : (a, m) gexpr) :
let pos_mark_as e = pos_mark (Mark.get e) in let pos_mark_as e = pos_mark (Mark.get e) in
pos_mark, pos_mark_as pos_mark, pos_mark_as
let rec module_scope_sig scope_sig_ctx path scope = let module_scope_sig scope_sig_ctx scope =
match path with let ssctx =
| [] -> ScopeName.Map.find scope scope_sig_ctx.scope_sigs List.fold_left (fun ssctx m -> ModuleName.Map.find m ssctx.scope_sigs_modules)
| (modname, mpos) :: path -> ( scope_sig_ctx (ScopeName.path scope)
match ModuleName.Map.find_opt modname scope_sig_ctx.scope_sigs_modules with in
| None -> ScopeName.Map.find scope ssctx.scope_sigs
Message.raise_spanned_error mpos "Module %a not found" ModuleName.format
modname
| Some sig_ctx -> module_scope_sig sig_ctx path scope)
let merge_defaults let merge_defaults
~(is_func : bool) ~(is_func : bool)
@ -214,7 +211,7 @@ let rec translate_expr (ctx : 'm ctx) (e : 'm Scopelang.Ast.expr) :
let m = Mark.get e in let m = Mark.get e in
match Mark.remove e with match Mark.remove e with
| EMatch { e = e1; name; cases = e_cases } -> | EMatch { e = e1; name; cases = e_cases } ->
let path, enum_sig = EnumName.Map.find name ctx.decl_ctx.ctx_enums in let enum_sig = EnumName.Map.find name ctx.decl_ctx.ctx_enums in
let d_cases, remaining_e_cases = let d_cases, remaining_e_cases =
(* FIXME: these checks should probably be moved to a better place *) (* FIXME: these checks should probably be moved to a better place *)
EnumConstructor.Map.fold EnumConstructor.Map.fold
@ -223,9 +220,9 @@ let rec translate_expr (ctx : 'm ctx) (e : 'm Scopelang.Ast.expr) :
try EnumConstructor.Map.find constructor e_cases try EnumConstructor.Map.find constructor e_cases
with EnumConstructor.Map.Not_found _ -> with EnumConstructor.Map.Not_found _ ->
Message.raise_spanned_error (Expr.pos e) Message.raise_spanned_error (Expr.pos e)
"The constructor %a of enum %a%a is missing from this pattern \ "The constructor %a of enum %a is missing from this pattern \
matching" matching"
EnumConstructor.format constructor Print.path path EnumConstructor.format constructor
EnumName.format name EnumName.format name
in in
let case_d = translate_expr ctx case_e in let case_d = translate_expr ctx case_e in
@ -236,16 +233,16 @@ let rec translate_expr (ctx : 'm ctx) (e : 'm Scopelang.Ast.expr) :
in in
if not (EnumConstructor.Map.is_empty remaining_e_cases) then if not (EnumConstructor.Map.is_empty remaining_e_cases) then
Message.raise_spanned_error (Expr.pos e) Message.raise_spanned_error (Expr.pos e)
"Pattern matching is incomplete for enum %a%a: missing cases %a" "Pattern matching is incomplete for enum %a: missing cases %a"
Print.path path EnumName.format name EnumName.format name
(EnumConstructor.Map.format_keys ~pp_sep:(fun fmt () -> (EnumConstructor.Map.format_keys ~pp_sep:(fun fmt () ->
Format.fprintf fmt ", ")) Format.fprintf fmt ", "))
remaining_e_cases; remaining_e_cases;
let e1 = translate_expr ctx e1 in let e1 = translate_expr ctx e1 in
Expr.ematch ~e:e1 ~name ~cases:d_cases m Expr.ematch ~e:e1 ~name ~cases:d_cases m
| EScopeCall { path; scope; args } -> | EScopeCall { scope; args } ->
let pos = Expr.mark_pos m in let pos = Expr.mark_pos m in
let sc_sig = module_scope_sig ctx.scopes_parameters path scope in let sc_sig = module_scope_sig ctx.scopes_parameters scope in
let in_var_map = let in_var_map =
ScopeVar.Map.merge ScopeVar.Map.merge
(fun var_name (str_field : scope_input_var_ctx option) expr -> (fun var_name (str_field : scope_input_var_ctx option) expr ->
@ -300,8 +297,8 @@ let rec translate_expr (ctx : 'm ctx) (e : 'm Scopelang.Ast.expr) :
let e = let e =
match sc_sig.scope_sig_scope_ref with match sc_sig.scope_sig_scope_ref with
| Local_scope_ref v -> Expr.evar v m | Local_scope_ref v -> Expr.evar v m
| External_scope_ref (path, name) -> | External_scope_ref name ->
Expr.eexternal ~path Expr.eexternal
~name:(Mark.map (fun s -> External_scope s) name) ~name:(Mark.map (fun s -> External_scope s) name)
m m
in in
@ -411,9 +408,8 @@ let rec translate_expr (ctx : 'm ctx) (e : 'm Scopelang.Ast.expr) :
EndCall f_markings) EndCall f_markings)
ts_in (Expr.pos e) ts_in (Expr.pos e)
| _ -> original_field_expr) | _ -> original_field_expr)
(snd (StructName.Map.find sc_sig.scope_sig_output_struct
(StructName.Map.find sc_sig.scope_sig_output_struct ctx.decl_ctx.ctx_structs))
ctx.decl_ctx.ctx_structs)))
(Expr.with_ty m (TStruct sc_sig.scope_sig_output_struct, Expr.pos e)) (Expr.with_ty m (TStruct sc_sig.scope_sig_output_struct, Expr.pos e))
in in
(* Here we have to go through an if statement that records a decision being (* Here we have to go through an if statement that records a decision being
@ -497,8 +493,8 @@ let rec translate_expr (ctx : 'm ctx) (e : 'm Scopelang.Ast.expr) :
ctx.subscope_vars ctx.subscope_vars
|> SubScopeName.Map.find (Mark.remove alias) |> SubScopeName.Map.find (Mark.remove alias)
|> retrieve_in_and_out_typ_or_any var |> retrieve_in_and_out_typ_or_any var
| ELocation (ToplevelVar { path; name }) -> ( | ELocation (ToplevelVar { name }) -> (
let decl_ctx = Program.module_ctx ctx.decl_ctx path in let decl_ctx = Program.module_ctx ctx.decl_ctx (TopdefName.path (Mark.remove name)) in
let typ = TopdefName.Map.find (Mark.remove name) decl_ctx.ctx_topdefs in let typ = TopdefName.Map.find (Mark.remove name) decl_ctx.ctx_topdefs in
match Mark.remove typ with match Mark.remove typ with
| TArrow (tin, (tout, _)) -> List.map Mark.remove tin, tout | TArrow (tin, (tout, _)) -> List.map Mark.remove tin, tout
@ -572,11 +568,13 @@ let rec translate_expr (ctx : 'm ctx) (e : 'm Scopelang.Ast.expr) :
%a's results. Maybe you forgot to qualify it as an output?" %a's results. Maybe you forgot to qualify it as an output?"
SubScopeName.format (Mark.remove s) ScopeVar.format (Mark.remove a) SubScopeName.format (Mark.remove s) ScopeVar.format (Mark.remove a)
SubScopeName.format (Mark.remove s)) SubScopeName.format (Mark.remove s))
| ELocation (ToplevelVar { path = []; name }) -> | ELocation (ToplevelVar { name }) ->
let v, _ = TopdefName.Map.find (Mark.remove name) ctx.toplevel_vars in let path = TopdefName.path (Mark.remove name) in
Expr.evar v m if path = [] then
| ELocation (ToplevelVar { path = _ :: _ as path; name }) -> let v, _ = TopdefName.Map.find (Mark.remove name) ctx.toplevel_vars in
Expr.eexternal ~path ~name:(Mark.map (fun n -> External_value n) name) m Expr.evar v m
else
Expr.eexternal ~name:(Mark.map (fun n -> External_value n) name) m
| EOp { op = Add_dat_dur _; tys } -> | EOp { op = Add_dat_dur _; tys } ->
Expr.eop (Add_dat_dur ctx.date_rounding) tys m Expr.eop (Add_dat_dur ctx.date_rounding) tys m
| EOp { op; tys } -> Expr.eop (Operator.translate op) tys m | EOp { op; tys } -> Expr.eop (Operator.translate op) tys m
@ -710,11 +708,11 @@ let translate_rule
(* A global variable can't be defined locally. The [Definition] constructor (* A global variable can't be defined locally. The [Definition] constructor
could be made more specific to avoid this case, but the added complexity could be made more specific to avoid this case, but the added complexity
didn't seem worth it *) didn't seem worth it *)
| Call ((path, subname), subindex, m) -> | Call (subname, subindex, m) ->
let subscope_sig = module_scope_sig ctx.scopes_parameters path subname in let subscope_sig = module_scope_sig ctx.scopes_parameters subname in
let scope_sig_decl = let scope_sig_decl =
ScopeName.Map.find subname ScopeName.Map.find subname
(Program.module_ctx ctx.decl_ctx path).ctx_scopes (Program.module_ctx ctx.decl_ctx (ScopeName.path subname)).ctx_scopes
in in
let all_subscope_vars = subscope_sig.scope_sig_local_vars in let all_subscope_vars = subscope_sig.scope_sig_local_vars in
let all_subscope_input_vars = let all_subscope_input_vars =
@ -736,8 +734,8 @@ let translate_rule
let m = mark_tany m pos_call in let m = mark_tany m pos_call in
match subscope_sig.scope_sig_scope_ref with match subscope_sig.scope_sig_scope_ref with
| Local_scope_ref var -> Expr.make_var var m | Local_scope_ref var -> Expr.make_var var m
| External_scope_ref (path, name) -> | External_scope_ref name ->
Expr.eexternal ~path ~name:(Mark.map (fun n -> External_scope n) name) m Expr.eexternal ~name:(Mark.map (fun n -> External_scope n) name) m
in in
let called_scope_input_struct = subscope_sig.scope_sig_input_struct in let called_scope_input_struct = subscope_sig.scope_sig_input_struct in
let called_scope_return_struct = subscope_sig.scope_sig_output_struct in let called_scope_return_struct = subscope_sig.scope_sig_output_struct in
@ -1069,7 +1067,7 @@ let translate_scope_decl
StructField.Map.empty scope_input_variables StructField.Map.empty scope_input_variables
in in
let new_struct_ctx = let new_struct_ctx =
StructName.Map.singleton scope_input_struct_name ([], field_map) StructName.Map.singleton scope_input_struct_name field_map
in in
scope_body, new_struct_ctx scope_body, new_struct_ctx
@ -1088,18 +1086,18 @@ let translate_program (prgm : 'm Scopelang.Ast.program) : 'm Ast.program =
prg.Scopelang.Ast.program_scopes)) prg.Scopelang.Ast.program_scopes))
prgm.program_modules; prgm.program_modules;
let sctx : 'm scope_sigs_ctx = let sctx : 'm scope_sigs_ctx =
let process_scope_sig (scope_path, scope_name) scope = let process_scope_sig scope_name scope =
Message.emit_debug "process_scope_sig %a%a (%a)" Print.path scope_path Message.emit_debug "process_scope_sig %a (%a)"
ScopeName.format scope_name ScopeName.format ScopeName.format scope_name ScopeName.format
scope.Scopelang.Ast.scope_decl_name; scope.Scopelang.Ast.scope_decl_name;
let scope_path = ScopeName.path scope_name in
let scope_ref = let scope_ref =
match scope_path with if scope_path = [] then
| [] ->
let v = Var.make (Mark.remove (ScopeName.get_info scope_name)) in let v = Var.make (Mark.remove (ScopeName.get_info scope_name)) in
Local_scope_ref v Local_scope_ref v
| path -> else
External_scope_ref External_scope_ref
(path, Mark.copy (ScopeName.get_info scope_name) scope_name) (Mark.copy (ScopeName.get_info scope_name) scope_name)
in in
let scope_info = let scope_info =
try try
@ -1108,7 +1106,7 @@ let translate_program (prgm : 'm Scopelang.Ast.program) : 'm Ast.program =
with ScopeName.Map.Not_found _ -> with ScopeName.Map.Not_found _ ->
Message.raise_spanned_error Message.raise_spanned_error
(Mark.get (ScopeName.get_info scope_name)) (Mark.get (ScopeName.get_info scope_name))
"Could not find scope %a%a" Print.path scope_path ScopeName.format "Could not find scope %a" ScopeName.format
scope_name scope_name
in in
let scope_sig_in_fields = let scope_sig_in_fields =
@ -1148,17 +1146,15 @@ let translate_program (prgm : 'm Scopelang.Ast.program) : 'm Ast.program =
scope_sig_in_fields; scope_sig_in_fields;
} }
in in
let rec process_modules path prg = let rec process_modules prg =
{ {
scope_sigs = scope_sigs =
ScopeName.Map.mapi ScopeName.Map.mapi
(fun scope_name (scope_decl, _) -> (fun scope_name (scope_decl, _) ->
process_scope_sig (path, scope_name) scope_decl) process_scope_sig scope_name scope_decl)
prg.Scopelang.Ast.program_scopes; prg.Scopelang.Ast.program_scopes;
scope_sigs_modules = scope_sigs_modules =
ModuleName.Map.mapi ModuleName.Map.map process_modules
(fun modname prg ->
process_modules (path @ [modname, Pos.no_pos]) prg)
prg.Scopelang.Ast.program_modules; prg.Scopelang.Ast.program_modules;
} }
in in
@ -1166,21 +1162,20 @@ let translate_program (prgm : 'm Scopelang.Ast.program) : 'm Ast.program =
scope_sigs = scope_sigs =
ScopeName.Map.mapi ScopeName.Map.mapi
(fun scope_name (scope_decl, _) -> (fun scope_name (scope_decl, _) ->
process_scope_sig ([], scope_name) scope_decl) process_scope_sig scope_name scope_decl)
prgm.Scopelang.Ast.program_scopes; prgm.Scopelang.Ast.program_scopes;
scope_sigs_modules = scope_sigs_modules =
ModuleName.Map.mapi ModuleName.Map.map
(fun modname prg -> process_modules [modname, Pos.no_pos] prg) process_modules
prgm.Scopelang.Ast.program_modules; prgm.Scopelang.Ast.program_modules;
} }
in in
let rec gather_module_in_structs acc path sctx = let rec gather_module_in_structs acc sctx =
(* Expose all added in_structs from submodules at toplevel *) (* Expose all added in_structs from submodules at toplevel *)
ModuleName.Map.fold ModuleName.Map.fold
(fun modname scope_sigs acc -> (fun _ scope_sigs acc ->
let path = path @ [modname, Pos.no_pos] in
let acc = let acc =
gather_module_in_structs acc path scope_sigs.scope_sigs_modules gather_module_in_structs acc scope_sigs.scope_sigs_modules
in in
ScopeName.Map.fold ScopeName.Map.fold
(fun _ scope_sig_ctx acc -> (fun _ scope_sig_ctx acc ->
@ -1196,7 +1191,7 @@ let translate_program (prgm : 'm Scopelang.Ast.program) : 'm Ast.program =
scope_sig_ctx.scope_sig_in_fields StructField.Map.empty scope_sig_ctx.scope_sig_in_fields StructField.Map.empty
in in
StructName.Map.add scope_sig_ctx.scope_sig_input_struct StructName.Map.add scope_sig_ctx.scope_sig_input_struct
(path, fields) acc) fields acc)
scope_sigs.scope_sigs acc) scope_sigs.scope_sigs acc)
sctx acc sctx acc
in in
@ -1204,7 +1199,7 @@ let translate_program (prgm : 'm Scopelang.Ast.program) : 'm Ast.program =
{ {
decl_ctx with decl_ctx with
ctx_structs = ctx_structs =
gather_module_in_structs decl_ctx.ctx_structs [] sctx.scope_sigs_modules; gather_module_in_structs decl_ctx.ctx_structs sctx.scope_sigs_modules;
} }
in in
let top_ctx = let top_ctx =

View File

@ -215,7 +215,7 @@ type var_or_states = WholeVar | States of StateName.t list
type scope = { type scope = {
scope_vars : var_or_states ScopeVar.Map.t; scope_vars : var_or_states ScopeVar.Map.t;
scope_sub_scopes : (path * ScopeName.t) SubScopeName.Map.t; scope_sub_scopes : ScopeName.t SubScopeName.Map.t;
scope_uid : ScopeName.t; scope_uid : ScopeName.t;
scope_defs : scope_def ScopeDef.Map.t; scope_defs : scope_def ScopeDef.Map.t;
scope_assertions : assertion AssertionName.Map.t; scope_assertions : assertion AssertionName.Map.t;

View File

@ -104,7 +104,7 @@ type var_or_states = WholeVar | States of StateName.t list
type scope = { type scope = {
scope_vars : var_or_states ScopeVar.Map.t; scope_vars : var_or_states ScopeVar.Map.t;
scope_sub_scopes : (path * ScopeName.t) SubScopeName.Map.t; scope_sub_scopes : ScopeName.t SubScopeName.Map.t;
scope_uid : ScopeName.t; scope_uid : ScopeName.t;
scope_defs : scope_def ScopeDef.Map.t; scope_defs : scope_def ScopeDef.Map.t;
scope_assertions : assertion AssertionName.Map.t; scope_assertions : assertion AssertionName.Map.t;

View File

@ -169,6 +169,7 @@ let rec disambiguate_constructor
Message.raise_spanned_error pos "Enum %s does not contain case %s" Message.raise_spanned_error pos "Enum %s does not contain case %s"
(Mark.remove enum) (Mark.remove constructor)) (Mark.remove enum) (Mark.remove constructor))
| (modname, mpos) :: path -> ( | (modname, mpos) :: path -> (
let modname = ModuleName.of_string modname in
match ModuleName.Map.find_opt modname ctxt.modules with match ModuleName.Map.find_opt modname ctxt.modules with
| None -> | None ->
Message.raise_spanned_error mpos "Module %a not found" ModuleName.format Message.raise_spanned_error mpos "Module %a not found" ModuleName.format
@ -373,7 +374,7 @@ let rec translate_expr
| Some v -> | Some v ->
Expr.elocation Expr.elocation
(ToplevelVar (ToplevelVar
{ path = []; name = v, Mark.get (TopdefName.get_info v) }) { name = v, Mark.get (TopdefName.get_info v) })
emark emark
| None -> | None ->
Name_resolution.raise_unknown_identifier Name_resolution.raise_unknown_identifier
@ -383,7 +384,7 @@ let rec translate_expr
match Ident.Map.find_opt (Mark.remove name) ctxt.topdefs with match Ident.Map.find_opt (Mark.remove name) ctxt.topdefs with
| Some v -> | Some v ->
Expr.elocation Expr.elocation
(ToplevelVar { path; name = v, Mark.get (TopdefName.get_info v) }) (ToplevelVar { name = v, Mark.get (TopdefName.get_info v) })
emark emark
| None -> | None ->
Name_resolution.raise_unknown_identifier "for an external variable" name) Name_resolution.raise_unknown_identifier "for an external variable" name)
@ -393,19 +394,17 @@ let rec translate_expr
when Option.fold scope ~none:false ~some:(fun s -> when Option.fold scope ~none:false ~some:(fun s ->
Name_resolution.is_subscope_uid s ctxt y) -> Name_resolution.is_subscope_uid s ctxt y) ->
(* In this case, y.x is a subscope variable *) (* In this case, y.x is a subscope variable *)
let subscope_uid, (subscope_path, subscope_real_uid) = let subscope_uid, subscope_real_uid =
match Ident.Map.find y scope_vars with match Ident.Map.find y scope_vars with
| SubScope (sub, sc) -> sub, sc | SubScope (sub, sc) -> sub, sc
| ScopeVar _ -> assert false | ScopeVar _ -> assert false
in in
let subscope_var_uid = let subscope_var_uid =
let ctxt = Name_resolution.module_ctx ctxt subscope_path in
Name_resolution.get_var_uid subscope_real_uid ctxt x Name_resolution.get_var_uid subscope_real_uid ctxt x
in in
Expr.elocation Expr.elocation
(SubScopeVar (SubScopeVar
{ {
path = subscope_path;
scope = subscope_real_uid; scope = subscope_real_uid;
alias = subscope_uid, pos; alias = subscope_uid, pos;
var = subscope_var_uid, pos; var = subscope_var_uid, pos;
@ -418,6 +417,7 @@ let rec translate_expr
| [] -> None | [] -> None
| [c] -> Some (Name_resolution.get_struct ctxt c) | [c] -> Some (Name_resolution.get_struct ctxt c)
| (modname, mpos) :: path -> ( | (modname, mpos) :: path -> (
let modname = ModuleName.of_string modname in
match ModuleName.Map.find_opt modname ctxt.modules with match ModuleName.Map.find_opt modname ctxt.modules with
| None -> | None ->
Message.raise_spanned_error mpos "Module %a not found" Message.raise_spanned_error mpos "Module %a not found"
@ -425,7 +425,7 @@ let rec translate_expr
| Some ctxt -> get_str ctxt path) | Some ctxt -> get_str ctxt path)
in in
Expr.edstructaccess ~e ~field:(Mark.remove x) Expr.edstructaccess ~e ~field:(Mark.remove x)
~name_opt:(get_str ctxt path) ~path emark) ~name_opt:(get_str ctxt path) emark)
| FunCall (f, args) -> | FunCall (f, args) ->
Expr.eapp (rec_helper f) (List.map rec_helper args) emark Expr.eapp (rec_helper f) (List.map rec_helper args) emark
| ScopeCall (((path, id), _), fields) -> | ScopeCall (((path, id), _), fields) ->
@ -467,7 +467,7 @@ let rec translate_expr
acc) acc)
ScopeVar.Map.empty fields ScopeVar.Map.empty fields
in in
Expr.escopecall ~path ~scope:called_scope ~args:in_struct emark Expr.escopecall ~scope:called_scope ~args:in_struct emark
| LetIn (x, e1, e2) -> | LetIn (x, e1, e2) ->
let v = Var.make (Mark.remove x) in let v = Var.make (Mark.remove x) in
let local_vars = Ident.Map.add (Mark.remove x) v local_vars in let local_vars = Ident.Map.add (Mark.remove x) v local_vars in
@ -1391,11 +1391,11 @@ let init_scope_defs
(scope_def_map, 0) states (scope_def_map, 0) states
in in
scope_def) scope_def)
| Name_resolution.SubScope (v0, (path, subscope_uid)) -> | Name_resolution.SubScope (v0, subscope_uid) ->
let ctxt = Name_resolution.module_ctx ctxt path in
let sub_scope_def = let sub_scope_def =
ScopeName.Map.find subscope_uid ctxt.Name_resolution.scopes Name_resolution.get_scope_context ctxt subscope_uid
in in
let ctxt = List.fold_left (fun ctx m -> ModuleName.Map.find m ctx.Name_resolution.modules) ctxt (ScopeName.path subscope_uid) in
Ident.Map.fold Ident.Map.fold
(fun _ v scope_def_map -> (fun _ v scope_def_map ->
match v with match v with
@ -1469,34 +1469,25 @@ let translate_program (ctxt : Name_resolution.context) (surface : S.program) :
Ast.program_ctx = Ast.program_ctx =
{ {
(* After name resolution, type definitions (structs and enums) are (* After name resolution, type definitions (structs and enums) are
exposed at toplevel for easier lookup, but their paths need to exposed at toplevel for easier lookup *)
remain available for printing and later passes *)
ctx_structs = ctx_structs =
ModuleName.Map.fold ModuleName.Map.fold
(fun modname prg acc -> (fun _ prg acc ->
StructName.Map.union StructName.Map.union
(fun _ _ _ -> assert false) (fun _ _ _ -> assert false)
acc acc
(StructName.Map.map prg.Ast.program_ctx.ctx_structs)
(fun (path, def) -> (modname, Pos.no_pos) :: path, def)
prg.Ast.program_ctx.ctx_structs))
submodules submodules
(StructName.Map.map ctxt.Name_resolution.structs;
(fun def -> [], def)
ctxt.Name_resolution.structs);
ctx_enums = ctx_enums =
ModuleName.Map.fold ModuleName.Map.fold
(fun modname prg acc -> (fun _ prg acc ->
EnumName.Map.union EnumName.Map.union
(fun _ _ _ -> assert false) (fun _ _ _ -> assert false)
acc acc
(EnumName.Map.map prg.Ast.program_ctx.ctx_enums)
(fun (path, def) -> (modname, Pos.no_pos) :: path, def)
prg.Ast.program_ctx.ctx_enums))
submodules submodules
(EnumName.Map.map ctxt.Name_resolution.enums;
(fun def -> [], def)
ctxt.Name_resolution.enums);
ctx_scopes = ctx_scopes =
Ident.Map.fold Ident.Map.fold
(fun _ def acc -> (fun _ def acc ->
@ -1546,10 +1537,11 @@ let translate_program (ctxt : Name_resolution.context) (surface : S.program) :
let desugared = let desugared =
List.fold_left List.fold_left
(fun acc (id, intf) -> (fun acc (id, intf) ->
let id = ModuleName.of_string id in
let modul = ModuleName.Map.find id acc.Ast.program_modules in let modul = ModuleName.Map.find id acc.Ast.program_modules in
let modul = let modul =
process_code_block process_code_block
(Name_resolution.module_ctx ctxt [id, Pos.no_pos]) (ModuleName.Map.find id ctxt.modules)
modul intf modul intf
in in
{ {

View File

@ -109,7 +109,7 @@ let detect_unused_struct_fields (p : program) : unit =
let rec structs_fields_used_expr e struct_fields_used = let rec structs_fields_used_expr e struct_fields_used =
match Mark.remove e with match Mark.remove e with
| EDStructAccess | EDStructAccess
{ name_opt = Some name; e = e_struct; field; path = _ } -> { name_opt = Some name; e = e_struct; field } ->
let field = let field =
StructName.Map.find name StructName.Map.find name
(Ident.Map.find field p.program_ctx.ctx_struct_fields) (Ident.Map.find field p.program_ctx.ctx_struct_fields)
@ -136,8 +136,8 @@ let detect_unused_struct_fields (p : program) : unit =
p.program_ctx.ctx_scopes StructField.Set.empty p.program_ctx.ctx_scopes StructField.Set.empty
in in
StructName.Map.iter StructName.Map.iter
(fun s_name (path, fields) -> (fun s_name fields ->
if path <> [] then () if StructName.path s_name <> [] then ()
else if else if
(not (StructField.Map.is_empty fields)) (not (StructField.Map.is_empty fields))
&& StructField.Map.for_all && StructField.Map.for_all
@ -192,8 +192,8 @@ let detect_unused_enum_constructors (p : program) : unit =
~init:EnumConstructor.Set.empty p ~init:EnumConstructor.Set.empty p
in in
EnumName.Map.iter EnumName.Map.iter
(fun e_name (path, constructors) -> (fun e_name constructors ->
if path <> [] then () if EnumName.path e_name <> [] then ()
else if else if
EnumConstructor.Map.for_all EnumConstructor.Map.for_all
(fun cons _ -> (fun cons _ ->

View File

@ -32,7 +32,7 @@ type scope_def_context = {
type scope_var_or_subscope = type scope_var_or_subscope =
| ScopeVar of ScopeVar.t | ScopeVar of ScopeVar.t
| SubScope of SubScopeName.t * (path * ScopeName.t) | SubScope of SubScopeName.t * ScopeName.t
type scope_context = { type scope_context = {
var_idmap : scope_var_or_subscope Ident.Map.t; var_idmap : scope_var_or_subscope Ident.Map.t;
@ -68,6 +68,7 @@ type typedef =
| TScope of ScopeName.t * scope_info (** Implicitly defined output struct *) | TScope of ScopeName.t * scope_info (** Implicitly defined output struct *)
type context = { type context = {
path : Uid.Path.t;
typedefs : typedef Ident.Map.t; typedefs : typedef Ident.Map.t;
(** Gathers the names of the scopes, structs and enums *) (** Gathers the names of the scopes, structs and enums *)
field_idmap : StructField.t StructName.Map.t Ident.Map.t; field_idmap : StructField.t StructName.Map.t Ident.Map.t;
@ -112,12 +113,23 @@ let get_var_io (ctxt : context) (uid : ScopeVar.t) :
Surface.Ast.scope_decl_context_io = Surface.Ast.scope_decl_context_io =
(ScopeVar.Map.find uid ctxt.var_typs).var_sig_io (ScopeVar.Map.find uid ctxt.var_typs).var_sig_io
let get_scope_context (ctxt: context) (scope: ScopeName.t) : scope_context =
let rec remove_common_prefix curpath scpath = match curpath, scpath with
| m1 :: cp, m2 :: sp when ModuleName.equal m1 m2 -> remove_common_prefix cp sp
| _ -> scpath
in
let path = remove_common_prefix ctxt.path (ScopeName.path scope) in
let ctxt =
List.fold_left (fun ctx m -> ModuleName.Map.find m ctx.modules) ctxt path
in
ScopeName.Map.find scope ctxt.scopes
(** Get the variable uid inside the scope given in argument *) (** Get the variable uid inside the scope given in argument *)
let get_var_uid let get_var_uid
(scope_uid : ScopeName.t) (scope_uid : ScopeName.t)
(ctxt : context) (ctxt : context)
((x, pos) : Ident.t Mark.pos) : ScopeVar.t = ((x, pos) : Ident.t Mark.pos) : ScopeVar.t =
let scope = ScopeName.Map.find scope_uid ctxt.scopes in let scope = get_scope_context ctxt scope_uid in
match Ident.Map.find_opt x scope.var_idmap with match Ident.Map.find_opt x scope.var_idmap with
| Some (ScopeVar uid) -> uid | Some (ScopeVar uid) -> uid
| _ -> | _ ->
@ -130,7 +142,7 @@ let get_subscope_uid
(scope_uid : ScopeName.t) (scope_uid : ScopeName.t)
(ctxt : context) (ctxt : context)
((y, pos) : Ident.t Mark.pos) : SubScopeName.t = ((y, pos) : Ident.t Mark.pos) : SubScopeName.t =
let scope = ScopeName.Map.find scope_uid ctxt.scopes in let scope = get_scope_context ctxt scope_uid in
match Ident.Map.find_opt y scope.var_idmap with match Ident.Map.find_opt y scope.var_idmap with
| Some (SubScope (sub_uid, _sub_id)) -> sub_uid | Some (SubScope (sub_uid, _sub_id)) -> sub_uid
| _ -> raise_unknown_identifier "for a subscope of this scope" (y, pos) | _ -> raise_unknown_identifier "for a subscope of this scope" (y, pos)
@ -139,7 +151,7 @@ let get_subscope_uid
subscopes of [scope_uid]. *) subscopes of [scope_uid]. *)
let is_subscope_uid (scope_uid : ScopeName.t) (ctxt : context) (y : Ident.t) : let is_subscope_uid (scope_uid : ScopeName.t) (ctxt : context) (y : Ident.t) :
bool = bool =
let scope = ScopeName.Map.find scope_uid ctxt.scopes in let scope = get_scope_context ctxt scope_uid in
match Ident.Map.find_opt y scope.var_idmap with match Ident.Map.find_opt y scope.var_idmap with
| Some (SubScope _) -> true | Some (SubScope _) -> true
| _ -> false | _ -> false
@ -147,7 +159,7 @@ let is_subscope_uid (scope_uid : ScopeName.t) (ctxt : context) (y : Ident.t) :
(** Checks if the var_uid belongs to the scope scope_uid *) (** Checks if the var_uid belongs to the scope scope_uid *)
let belongs_to (ctxt : context) (uid : ScopeVar.t) (scope_uid : ScopeName.t) : let belongs_to (ctxt : context) (uid : ScopeVar.t) (scope_uid : ScopeName.t) :
bool = bool =
let scope = ScopeName.Map.find scope_uid ctxt.scopes in let scope = get_scope_context ctxt scope_uid in
Ident.Map.exists Ident.Map.exists
(fun _ -> function (fun _ -> function
| ScopeVar var_uid -> ScopeVar.equal uid var_uid | ScopeVar var_uid -> ScopeVar.equal uid var_uid
@ -241,6 +253,7 @@ let rec module_ctx ctxt path =
match path with match path with
| [] -> ctxt | [] -> ctxt
| (modname, mpos) :: path -> ( | (modname, mpos) :: path -> (
let modname = ModuleName.of_string modname in
match ModuleName.Map.find_opt modname ctxt.modules with match ModuleName.Map.find_opt modname ctxt.modules with
| None -> | None ->
Message.raise_spanned_error mpos "Module %a not found" ModuleName.format Message.raise_spanned_error mpos "Module %a not found" ModuleName.format
@ -256,7 +269,7 @@ let process_subscope_decl
(decl : Surface.Ast.scope_decl_context_scope) : context = (decl : Surface.Ast.scope_decl_context_scope) : context =
let name, name_pos = decl.scope_decl_context_scope_name in let name, name_pos = decl.scope_decl_context_scope_name in
let (path, subscope), s_pos = decl.scope_decl_context_scope_sub_scope in let (path, subscope), s_pos = decl.scope_decl_context_scope_sub_scope in
let scope_ctxt = ScopeName.Map.find scope ctxt.scopes in let scope_ctxt = get_scope_context ctxt scope in
match Ident.Map.find_opt (Mark.remove subscope) scope_ctxt.var_idmap with match Ident.Map.find_opt (Mark.remove subscope) scope_ctxt.var_idmap with
| Some use -> | Some use ->
let info = let info =
@ -278,7 +291,7 @@ let process_subscope_decl
scope_ctxt with scope_ctxt with
var_idmap = var_idmap =
Ident.Map.add name Ident.Map.add name
(SubScope (sub_scope_uid, (path, original_subscope_uid))) (SubScope (sub_scope_uid, original_subscope_uid))
scope_ctxt.var_idmap; scope_ctxt.var_idmap;
sub_scopes = sub_scopes =
ScopeName.Set.add original_subscope_uid scope_ctxt.sub_scopes; ScopeName.Set.add original_subscope_uid scope_ctxt.sub_scopes;
@ -324,6 +337,7 @@ let rec process_base_typ
declared" declared"
ident) ident)
| Surface.Ast.Named ((modul, mpos) :: path, id) -> ( | Surface.Ast.Named ((modul, mpos) :: path, id) -> (
let modul = ModuleName.of_string modul in
match ModuleName.Map.find_opt modul ctxt.modules with match ModuleName.Map.find_opt modul ctxt.modules with
| None -> | None ->
Message.raise_spanned_error mpos Message.raise_spanned_error mpos
@ -351,7 +365,7 @@ let process_data_decl
let data_typ = process_type ctxt decl.scope_decl_context_item_typ in let data_typ = process_type ctxt decl.scope_decl_context_item_typ in
let is_cond = is_type_cond decl.scope_decl_context_item_typ in let is_cond = is_type_cond decl.scope_decl_context_item_typ in
let name, pos = decl.scope_decl_context_item_name in let name, pos = decl.scope_decl_context_item_name in
let scope_ctxt = ScopeName.Map.find scope ctxt.scopes in let scope_ctxt = get_scope_context ctxt scope in
match Ident.Map.find_opt name scope_ctxt.var_idmap with match Ident.Map.find_opt name scope_ctxt.var_idmap with
| Some use -> | Some use ->
let info = let info =
@ -568,7 +582,7 @@ let process_scope_decl (ctxt : context) (decl : Surface.Ast.scope_decl) :
} }
in in
let out_struct_fields = let out_struct_fields =
let sco = ScopeName.Map.find scope_uid ctxt.scopes in let sco = get_scope_context ctxt scope_uid in
let str = get_struct ctxt decl.scope_decl_name in let str = get_struct ctxt decl.scope_decl_name in
Ident.Map.fold Ident.Map.fold
(fun id var svmap -> (fun id var svmap ->
@ -621,9 +635,9 @@ let process_name_item (ctxt : context) (item : Surface.Ast.code_item Mark.pos) :
(fun use -> (fun use ->
raise_already_defined_error (typedef_info use) name pos "scope") raise_already_defined_error (typedef_info use) name pos "scope")
(Ident.Map.find_opt name ctxt.typedefs); (Ident.Map.find_opt name ctxt.typedefs);
let scope_uid = ScopeName.fresh (name, pos) in let scope_uid = ScopeName.fresh ctxt.path (name, pos) in
let in_struct_name = StructName.fresh (name ^ "_in", pos) in let in_struct_name = StructName.fresh ctxt.path (name ^ "_in", pos) in
let out_struct_name = StructName.fresh (name, pos) in let out_struct_name = StructName.fresh ctxt.path (name, pos) in
{ {
ctxt with ctxt with
typedefs = typedefs =
@ -651,7 +665,7 @@ let process_name_item (ctxt : context) (item : Surface.Ast.code_item Mark.pos) :
(fun use -> (fun use ->
raise_already_defined_error (typedef_info use) name pos "struct") raise_already_defined_error (typedef_info use) name pos "struct")
(Ident.Map.find_opt name ctxt.typedefs); (Ident.Map.find_opt name ctxt.typedefs);
let s_uid = StructName.fresh sdecl.struct_decl_name in let s_uid = StructName.fresh ctxt.path sdecl.struct_decl_name in
{ {
ctxt with ctxt with
typedefs = typedefs =
@ -665,7 +679,7 @@ let process_name_item (ctxt : context) (item : Surface.Ast.code_item Mark.pos) :
(fun use -> (fun use ->
raise_already_defined_error (typedef_info use) name pos "enum") raise_already_defined_error (typedef_info use) name pos "enum")
(Ident.Map.find_opt name ctxt.typedefs); (Ident.Map.find_opt name ctxt.typedefs);
let e_uid = EnumName.fresh edecl.enum_decl_name in let e_uid = EnumName.fresh ctxt.path edecl.enum_decl_name in
{ {
ctxt with ctxt with
typedefs = typedefs =
@ -681,7 +695,7 @@ let process_name_item (ctxt : context) (item : Surface.Ast.code_item Mark.pos) :
raise_already_defined_error (TopdefName.get_info use) name pos raise_already_defined_error (TopdefName.get_info use) name pos
"toplevel definition") "toplevel definition")
(Ident.Map.find_opt name ctxt.topdefs); (Ident.Map.find_opt name ctxt.topdefs);
let uid = TopdefName.fresh def.topdef_name in let uid = TopdefName.fresh ctxt.path def.topdef_name in
{ {
ctxt with ctxt with
topdefs = Ident.Map.add name uid ctxt.topdefs; topdefs = Ident.Map.add name uid ctxt.topdefs;
@ -762,8 +776,8 @@ let get_def_key
ScopeVar.format x_uid ScopeVar.format x_uid
else None ) else None )
| [y; x] -> | [y; x] ->
let (subscope_uid, (path, subscope_real_uid)) let (subscope_uid, subscope_real_uid)
: SubScopeName.t * (path * ScopeName.t) = : SubScopeName.t * ScopeName.t =
match Ident.Map.find_opt (Mark.remove y) scope_ctxt.var_idmap with match Ident.Map.find_opt (Mark.remove y) scope_ctxt.var_idmap with
| Some (SubScope (v, u)) -> v, u | Some (SubScope (v, u)) -> v, u
| Some _ -> | Some _ ->
@ -775,7 +789,6 @@ let get_def_key
Print.lit_style (Mark.remove y) Print.lit_style (Mark.remove y)
in in
let x_uid = let x_uid =
let ctxt = module_ctx ctxt path in
get_var_uid subscope_real_uid ctxt x get_var_uid subscope_real_uid ctxt x
in in
Ast.ScopeDef.SubScopeVar (subscope_uid, x_uid, pos) Ast.ScopeDef.SubScopeVar (subscope_uid, x_uid, pos)
@ -924,6 +937,7 @@ let process_use_item (ctxt : context) (item : Surface.Ast.code_item Mark.pos) :
let empty_ctxt = let empty_ctxt =
{ {
path = [];
typedefs = Ident.Map.empty; typedefs = Ident.Map.empty;
scopes = ScopeName.Map.empty; scopes = ScopeName.Map.empty;
topdefs = Ident.Map.empty; topdefs = Ident.Map.empty;
@ -937,13 +951,14 @@ let empty_ctxt =
} }
let import_module modules (name, intf) = let import_module modules (name, intf) =
let ctxt = { empty_ctxt with modules } in let mname = ModuleName.of_string name in
let ctxt = { empty_ctxt with modules; path = [mname] } in
let ctxt = List.fold_left process_name_item ctxt intf in let ctxt = List.fold_left process_name_item ctxt intf in
let ctxt = List.fold_left process_decl_item ctxt intf in let ctxt = List.fold_left process_decl_item ctxt intf in
let ctxt = { ctxt with modules = empty_ctxt.modules } in let ctxt = { ctxt with modules = empty_ctxt.modules } in
(* No submodules at the moment, a module may use the ones loaded before it, (* No submodules at the moment, a module may use the ones loaded before it,
but doesn't reexport them *) but doesn't reexport them *)
ModuleName.Map.add name ctxt modules ModuleName.Map.add mname ctxt modules
(** Derive the context from metadata, in one pass over the declarations *) (** Derive the context from metadata, in one pass over the declarations *)
let form_context (prgm : Surface.Ast.program) : context = let form_context (prgm : Surface.Ast.program) : context =

View File

@ -32,7 +32,7 @@ type scope_def_context = {
type scope_var_or_subscope = type scope_var_or_subscope =
| ScopeVar of ScopeVar.t | ScopeVar of ScopeVar.t
| SubScope of SubScopeName.t * (path * ScopeName.t) | SubScope of SubScopeName.t * ScopeName.t
type scope_context = { type scope_context = {
var_idmap : scope_var_or_subscope Ident.Map.t; var_idmap : scope_var_or_subscope Ident.Map.t;
@ -68,6 +68,8 @@ type typedef =
| TScope of ScopeName.t * scope_info (** Implicitly defined output struct *) | TScope of ScopeName.t * scope_info (** Implicitly defined output struct *)
type context = { type context = {
path : ModuleName.t list;
(** The current path being processed. Used for generating the Uids. *)
typedefs : typedef Ident.Map.t; typedefs : typedef Ident.Map.t;
(** Gathers the names of the scopes, structs and enums *) (** Gathers the names of the scopes, structs and enums *)
field_idmap : StructField.t StructName.Map.t Ident.Map.t; field_idmap : StructField.t StructName.Map.t Ident.Map.t;
@ -105,6 +107,9 @@ val get_var_typ : context -> ScopeVar.t -> typ
val is_var_cond : context -> ScopeVar.t -> bool val is_var_cond : context -> ScopeVar.t -> bool
val get_var_io : context -> ScopeVar.t -> Surface.Ast.scope_decl_context_io val get_var_io : context -> ScopeVar.t -> Surface.Ast.scope_decl_context_io
val get_scope_context : context -> ScopeName.t -> scope_context
(** Get the corresponding scope context from the context, looking up into nested submodules as necessary, following the path information in the scope name *)
val get_var_uid : ScopeName.t -> context -> Ident.t Mark.pos -> ScopeVar.t val get_var_uid : ScopeName.t -> context -> Ident.t Mark.pos -> ScopeVar.t
(** Get the variable uid inside the scope given in argument *) (** Get the variable uid inside the scope given in argument *)
@ -151,7 +156,7 @@ val get_scope : context -> Ident.t Mark.pos -> ScopeName.t
(** Find a scope definition from the typedefs, failing if there is none or it (** Find a scope definition from the typedefs, failing if there is none or it
has a different kind *) has a different kind *)
val module_ctx : context -> path -> context val module_ctx : context -> Surface.Ast.path -> context
(** Returns the context corresponding to the given module path; raises a user (** Returns the context corresponding to the given module path; raises a user
error if the module is not found *) error if the module is not found *)

View File

@ -255,7 +255,7 @@ module Commands = struct
variable ScopeName.format scope_uid variable ScopeName.format scope_uid
| Some | Some
(Desugared.Name_resolution.SubScope (Desugared.Name_resolution.SubScope
(subscope_var_name, (subscope_path, subscope_name))) -> ( (subscope_var_name, subscope_name)) -> (
match second_part with match second_part with
| None -> | None ->
Message.raise_error Message.raise_error
@ -265,7 +265,10 @@ module Commands = struct
SubScopeName.format subscope_var_name ScopeName.format scope_uid SubScopeName.format subscope_var_name ScopeName.format scope_uid
| Some second_part -> ( | Some second_part -> (
match match
let ctxt = Desugared.Name_resolution.module_ctx ctxt subscope_path in let ctxt = Desugared.Name_resolution.module_ctx ctxt
(List.map (fun m -> ModuleName.to_string m, Pos.no_pos)
(ScopeName.path subscope_name))
in
Ident.Map.find_opt second_part Ident.Map.find_opt second_part
(ScopeName.Map.find subscope_name ctxt.scopes).var_idmap (ScopeName.Map.find subscope_name ctxt.scopes).var_idmap
with with

View File

@ -333,11 +333,11 @@ let transform_closures_program (p : 'm program) : 'm program Bindlib.box =
| TEnum e -> | TEnum e ->
EnumConstructor.Map.exists EnumConstructor.Map.exists
(fun _ t' -> type_contains_arrow t') (fun _ t' -> type_contains_arrow t')
(snd (EnumName.Map.find e p.decl_ctx.ctx_enums)) (EnumName.Map.find e p.decl_ctx.ctx_enums)
| TStruct s -> | TStruct s ->
StructField.Map.exists StructField.Map.exists
(fun _ t' -> type_contains_arrow t') (fun _ t' -> type_contains_arrow t')
(snd (StructName.Map.find s p.decl_ctx.ctx_structs)) (StructName.Map.find s p.decl_ctx.ctx_structs)
in in
let replace_fun_typs t = let replace_fun_typs t =
if type_contains_arrow t then Mark.copy t TAny else t if type_contains_arrow t then Mark.copy t TAny else t
@ -346,11 +346,11 @@ let transform_closures_program (p : 'm program) : 'm program Bindlib.box =
p.decl_ctx with p.decl_ctx with
ctx_structs = ctx_structs =
StructName.Map.map StructName.Map.map
(fun (p, def) -> p, StructField.Map.map replace_fun_typs def) (StructField.Map.map replace_fun_typs)
p.decl_ctx.ctx_structs; p.decl_ctx.ctx_structs;
ctx_enums = ctx_enums =
EnumName.Map.map EnumName.Map.map
(fun (p, def) -> p, EnumConstructor.Map.map replace_fun_typs def) (EnumConstructor.Map.map replace_fun_typs)
p.decl_ctx.ctx_enums; p.decl_ctx.ctx_enums;
} }
in in
@ -552,7 +552,7 @@ let rec hoist_closures_code_item_list
(fun next_code_items closure -> (fun next_code_items closure ->
Cons Cons
( Topdef ( Topdef
( TopdefName.fresh ( TopdefName.fresh []
( Bindlib.name_of hoisted_closure.name, ( Bindlib.name_of hoisted_closure.name,
Expr.mark_pos closure_mark ), Expr.mark_pos closure_mark ),
hoisted_closure.ty, hoisted_closure.ty,

View File

@ -745,7 +745,7 @@ let translate_program (prgm : typed D.program) : untyped A.program =
prgm.decl_ctx with prgm.decl_ctx with
ctx_enums = ctx_enums =
prgm.decl_ctx.ctx_enums prgm.decl_ctx.ctx_enums
|> EnumName.Map.add Expr.option_enum ([], Expr.option_enum_config); |> EnumName.Map.add Expr.option_enum Expr.option_enum_config;
} }
in in
let decl_ctx = let decl_ctx =
@ -753,8 +753,8 @@ let translate_program (prgm : typed D.program) : untyped A.program =
decl_ctx with decl_ctx with
ctx_structs = ctx_structs =
prgm.decl_ctx.ctx_structs prgm.decl_ctx.ctx_structs
|> StructName.Map.mapi (fun _n (path, str) -> |> StructName.Map.mapi (fun _n str ->
path, StructField.Map.map trans_typ_keep str); StructField.Map.map trans_typ_keep str);
} }
in in

View File

@ -274,8 +274,7 @@ let rec format_expr (ctx : decl_ctx) (fmt : Format.formatter) (e : 'm expr) :
in in
match Mark.remove e with match Mark.remove e with
| EVar v -> Format.fprintf fmt "%a" format_var v | EVar v -> Format.fprintf fmt "%a" format_var v
| EExternal { path; name } -> ( | EExternal { name } -> (
Print.path fmt path;
(* FIXME: this is wrong in general !! We assume the idents exposed by the (* FIXME: this is wrong in general !! We assume the idents exposed by the
module depend only on the original name, while they actually get through module depend only on the original name, while they actually get through
Bindlib and may have been renamed. A correct implem could use the runtime Bindlib and may have been renamed. A correct implem could use the runtime
@ -555,11 +554,13 @@ let format_ctx
(fun struct_or_enum -> (fun struct_or_enum ->
match struct_or_enum with match struct_or_enum with
| Scopelang.Dependency.TVertex.Struct s -> | Scopelang.Dependency.TVertex.Struct s ->
let path, def = StructName.Map.find s ctx.ctx_structs in let def = StructName.Map.find s ctx.ctx_structs in
if path = [] then Format.fprintf fmt "%a@\n" format_struct_decl (s, def) if StructName.path s = [] then
Format.fprintf fmt "%a@\n" format_struct_decl (s, def)
| Scopelang.Dependency.TVertex.Enum e -> | Scopelang.Dependency.TVertex.Enum e ->
let path, def = EnumName.Map.find e ctx.ctx_enums in let def = EnumName.Map.find e ctx.ctx_enums in
if path = [] then Format.fprintf fmt "%a@\n" format_enum_decl (e, def)) if EnumName.path e = [] then
Format.fprintf fmt "%a@\n" format_enum_decl (e, def))
(type_ordering @ scope_structs) (type_ordering @ scope_structs)
let rename_vars e = let rename_vars e =
@ -618,7 +619,7 @@ let format_scope_exec
scope_body = scope_body =
let scope_name_str = Mark.remove (ScopeName.get_info scope_name) in let scope_name_str = Mark.remove (ScopeName.get_info scope_name) in
let scope_var = String.Map.find scope_name_str bnd in let scope_var = String.Map.find scope_name_str bnd in
let _, scope_input = let scope_input =
StructName.Map.find scope_body.scope_body_input_struct ctx.ctx_structs StructName.Map.find scope_body.scope_body_input_struct ctx.ctx_structs
in in
if not (StructField.Map.is_empty scope_input) then if not (StructField.Map.is_empty scope_input) then

View File

@ -139,10 +139,9 @@ module To_jsoo = struct
| TArrow _ -> Format.fprintf fmt "Js.meth" | TArrow _ -> Format.fprintf fmt "Js.meth"
| _ -> Format.fprintf fmt "Js.readonly_prop" | _ -> Format.fprintf fmt "Js.readonly_prop"
in in
let format_struct_decl fmt (struct_name, (path, struct_fields)) = let format_struct_decl fmt (struct_name, struct_fields) =
let fmt_struct_name fmt _ = format_struct_name fmt struct_name in let fmt_struct_name fmt _ = format_struct_name fmt struct_name in
let fmt_module_struct_name fmt _ = let fmt_module_struct_name fmt _ =
Print.path fmt path;
To_ocaml.format_to_module_name fmt (`Sname struct_name) To_ocaml.format_to_module_name fmt (`Sname struct_name)
in in
let fmt_to_jsoo fmt _ = let fmt_to_jsoo fmt _ =
@ -233,10 +232,9 @@ module To_jsoo = struct
in in
let format_enum_decl let format_enum_decl
fmt fmt
(enum_name, (path, (enum_cons : typ EnumConstructor.Map.t))) = (enum_name, (enum_cons : typ EnumConstructor.Map.t)) =
let fmt_enum_name fmt _ = format_enum_name fmt enum_name in let fmt_enum_name fmt _ = format_enum_name fmt enum_name in
let fmt_module_enum_name fmt () = let fmt_module_enum_name fmt () =
Print.path fmt path;
To_ocaml.format_to_module_name fmt (`Ename enum_name) To_ocaml.format_to_module_name fmt (`Ename enum_name)
in in
let fmt_to_jsoo fmt _ = let fmt_to_jsoo fmt _ =

View File

@ -76,11 +76,11 @@ module To_json = struct
(ctx : decl_ctx) (ctx : decl_ctx)
(fmt : Format.formatter) (fmt : Format.formatter)
(sname : StructName.t) = (sname : StructName.t) =
let path, fields = StructName.Map.find sname ctx.ctx_structs in let fields = StructName.Map.find sname ctx.ctx_structs in
Format.pp_print_list Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt ",@\n") ~pp_sep:(fun fmt () -> Format.fprintf fmt ",@\n")
(fun fmt (field_name, field_type) -> (fun fmt (field_name, field_type) ->
Format.fprintf fmt "@[<hov 2>\"%a%a\": {@\n%a@]@\n}" Print.path path Format.fprintf fmt "@[<hov 2>\"%a\": {@\n%a@]@\n}"
format_struct_field_name_camel_case field_name fmt_type field_type) format_struct_field_name_camel_case field_name fmt_type field_type)
fmt fmt
(StructField.Map.bindings fields) (StructField.Map.bindings fields)
@ -105,18 +105,17 @@ module To_json = struct
| TEnum e -> | TEnum e ->
List.fold_left collect (t :: acc) List.fold_left collect (t :: acc)
(EnumConstructor.Map.values (EnumConstructor.Map.values
(snd (EnumName.Map.find e ctx.ctx_enums))) (EnumName.Map.find e ctx.ctx_enums))
| TArray t -> collect acc t | TArray t -> collect acc t
| _ -> acc | _ -> acc
in in
StructName.Map.find input_struct ctx.ctx_structs StructName.Map.find input_struct ctx.ctx_structs
|> snd
|> StructField.Map.values |> StructField.Map.values
|> List.fold_left (fun acc field_typ -> collect acc field_typ) [] |> List.fold_left (fun acc field_typ -> collect acc field_typ) []
|> List.sort_uniq (fun t t' -> String.compare (get_name t) (get_name t')) |> List.sort_uniq (fun t t' -> String.compare (get_name t) (get_name t'))
in in
let fmt_enum_properties fmt ename = let fmt_enum_properties fmt ename =
let _path, enum_def = EnumName.Map.find ename ctx.ctx_enums in let enum_def = EnumName.Map.find ename ctx.ctx_enums in
Format.fprintf fmt Format.fprintf fmt
"@[<hov 2>\"kind\": {@\n\ "@[<hov 2>\"kind\": {@\n\
\"type\": \"string\",@\n\ \"type\": \"string\",@\n\

View File

@ -243,7 +243,7 @@ let interpret_program (prg : ('dcalc, 'm) gexpr program) (scope : ScopeName.t) :
(Bindlib.box EEmptyError, Expr.with_ty m ty_out) (Bindlib.box EEmptyError, Expr.with_ty m ty_out)
ty_in (Expr.mark_pos m) ty_in (Expr.mark_pos m)
| ty -> Expr.evar (Var.make "undefined_input") (Expr.with_ty m ty)) | ty -> Expr.evar (Var.make "undefined_input") (Expr.with_ty m ty))
(snd (StructName.Map.find scope_arg_struct ctx.ctx_structs))) (StructName.Map.find scope_arg_struct ctx.ctx_structs))
m m
in in
let e_app = Expr.eapp (Expr.box e) [application_arg] m in let e_app = Expr.eapp (Expr.box e) [application_arg] m in

View File

@ -42,8 +42,8 @@ let rec format_expr
| EVar v -> Format.fprintf fmt "%a" format_var_name v | EVar v -> Format.fprintf fmt "%a" format_var_name v
| EFunc v -> Format.fprintf fmt "%a" format_func_name v | EFunc v -> Format.fprintf fmt "%a" format_func_name v
| EStruct (es, s) -> | EStruct (es, s) ->
let path, fields = StructName.Map.find s decl_ctx.ctx_structs in let fields = StructName.Map.find s decl_ctx.ctx_structs in
Format.fprintf fmt "@[<hov 2>%a%a@ %a%a%a@]" Print.path path Format.fprintf fmt "@[<hov 2>%a@ %a%a%a@]"
StructName.format s Print.punctuation "{" StructName.format s Print.punctuation "{"
(Format.pp_print_list (Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt ",@ ") ~pp_sep:(fun fmt () -> Format.fprintf fmt ",@ ")
@ -142,15 +142,15 @@ let rec format_statement
(format_expr decl_ctx ~debug) (format_expr decl_ctx ~debug)
(naked_expr, Mark.get stmt) (naked_expr, Mark.get stmt)
| SSwitch (e_switch, enum, arms) -> | SSwitch (e_switch, enum, arms) ->
let path, cons = EnumName.Map.find enum decl_ctx.ctx_enums in let cons = EnumName.Map.find enum decl_ctx.ctx_enums in
Format.fprintf fmt "@[<v 0>%a @[<hov 2>%a@]%a@]%a" Print.keyword "switch" Format.fprintf fmt "@[<v 0>%a @[<hov 2>%a@]%a@]%a" Print.keyword "switch"
(format_expr decl_ctx ~debug) (format_expr decl_ctx ~debug)
e_switch Print.punctuation ":" e_switch Print.punctuation ":"
(Format.pp_print_list (Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n") ~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
(fun fmt ((case, _), (arm_block, payload_name)) -> (fun fmt ((case, _), (arm_block, payload_name)) ->
Format.fprintf fmt "%a %a%a%a@ %a @[<v 2>%a@ %a@]" Print.punctuation Format.fprintf fmt "%a %a%a@ %a @[<v 2>%a@ %a@]" Print.punctuation
"|" Print.path path Print.enum_constructor case Print.punctuation "|" Print.enum_constructor case Print.punctuation
":" format_var_name payload_name Print.punctuation "" ":" format_var_name payload_name Print.punctuation ""
(format_block decl_ctx ~debug) (format_block decl_ctx ~debug)
arm_block)) arm_block))

View File

@ -274,8 +274,8 @@ let rec format_expression (ctx : decl_ctx) (fmt : Format.formatter) (e : expr) :
| EVar v -> format_var fmt v | EVar v -> format_var fmt v
| EFunc f -> format_func_name fmt f | EFunc f -> format_func_name fmt f
| EStruct (es, s) -> | EStruct (es, s) ->
let path, fields = StructName.Map.find s ctx.ctx_structs in let fields = StructName.Map.find s ctx.ctx_structs in
Format.fprintf fmt "%a%a(%a)" Print.path path format_struct_name s Format.fprintf fmt "%a(%a)" format_struct_name s
(Format.pp_print_list (Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt ",@ ") ~pp_sep:(fun fmt () -> Format.fprintf fmt ",@ ")
(fun fmt (e, (struct_field, _)) -> (fun fmt (e, (struct_field, _)) ->
@ -426,7 +426,7 @@ let rec format_statement
(format_block ctx) case_none format_var case_some_var format_var tmp_var (format_block ctx) case_none format_var case_some_var format_var tmp_var
(format_block ctx) case_some (format_block ctx) case_some
| SSwitch (e1, e_name, cases) -> | SSwitch (e1, e_name, cases) ->
let path, cons_map = EnumName.Map.find e_name ctx.ctx_enums in let cons_map = EnumName.Map.find e_name ctx.ctx_enums in
let cases = let cases =
List.map2 List.map2
(fun (x, y) (cons, _) -> x, y, cons) (fun (x, y) (cons, _) -> x, y, cons)
@ -439,8 +439,8 @@ let rec format_statement
(Format.pp_print_list (Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "@]@\n@[<hov 4>elif ") ~pp_sep:(fun fmt () -> Format.fprintf fmt "@]@\n@[<hov 4>elif ")
(fun fmt (case_block, payload_var, cons_name) -> (fun fmt (case_block, payload_var, cons_name) ->
Format.fprintf fmt "%a.code == %a%a_Code.%a:@\n%a = %a.value@\n%a" Format.fprintf fmt "%a.code == %a_Code.%a:@\n%a = %a.value@\n%a"
format_var tmp_var Print.path path format_enum_name e_name format_var tmp_var format_enum_name e_name
format_enum_cons_name cons_name format_var payload_var format_var format_enum_cons_name cons_name format_var payload_var format_var
tmp_var (format_block ctx) case_block)) tmp_var (format_block ctx) case_block))
cases cases
@ -585,10 +585,10 @@ let format_ctx
match struct_or_enum with match struct_or_enum with
| Scopelang.Dependency.TVertex.Struct s -> | Scopelang.Dependency.TVertex.Struct s ->
Format.fprintf fmt "%a@\n@\n" format_struct_decl Format.fprintf fmt "%a@\n@\n" format_struct_decl
(s, snd (StructName.Map.find s ctx.ctx_structs)) (s, StructName.Map.find s ctx.ctx_structs)
| Scopelang.Dependency.TVertex.Enum e -> | Scopelang.Dependency.TVertex.Enum e ->
Format.fprintf fmt "%a@\n@\n" format_enum_decl Format.fprintf fmt "%a@\n@\n" format_enum_decl
(e, snd (EnumName.Map.find e ctx.ctx_enums))) (e, EnumName.Map.find e ctx.ctx_enums))
(type_ordering @ scope_structs) (type_ordering @ scope_structs)
let format_program let format_program

View File

@ -41,7 +41,7 @@ let rec locations_used (e : 'm expr) : LocationSet.t =
type 'm rule = type 'm rule =
| Definition of location Mark.pos * typ * Desugared.Ast.io * 'm expr | Definition of location Mark.pos * typ * Desugared.Ast.io * 'm expr
| Assertion of 'm expr | Assertion of 'm expr
| Call of (path * ScopeName.t) * SubScopeName.t * 'm mark | Call of ScopeName.t * SubScopeName.t * 'm mark
type 'm scope_decl = { type 'm scope_decl = {
scope_decl_name : ScopeName.t; scope_decl_name : ScopeName.t;

View File

@ -34,7 +34,7 @@ val locations_used : 'm expr -> LocationSet.t
type 'm rule = type 'm rule =
| Definition of location Mark.pos * typ * Desugared.Ast.io * 'm expr | Definition of location Mark.pos * typ * Desugared.Ast.io * 'm expr
| Assertion of 'm expr | Assertion of 'm expr
| Call of (path * ScopeName.t) * SubScopeName.t * 'm mark | Call of ScopeName.t * SubScopeName.t * 'm mark
type 'm scope_decl = { type 'm scope_decl = {
scope_decl_name : ScopeName.t; scope_decl_name : ScopeName.t;

View File

@ -82,9 +82,9 @@ let rec expr_used_defs e =
e VMap.empty e VMap.empty
in in
match e with match e with
| ELocation (ToplevelVar { path = []; name = v, pos }), _ -> | ELocation (ToplevelVar { name = v, pos }), _ ->
VMap.singleton (Topdef v) pos VMap.singleton (Topdef v) pos
| (EScopeCall { path = []; scope; _ }, m) as e -> | (EScopeCall { scope; _ }, m) as e ->
VMap.add (Scope scope) (Expr.mark_pos m) (recurse_subterms e) VMap.add (Scope scope) (Expr.mark_pos m) (recurse_subterms e)
| EAbs { binder; _ }, _ -> | EAbs { binder; _ }, _ ->
let _, body = Bindlib.unmbind binder in let _, body = Bindlib.unmbind binder in
@ -96,9 +96,10 @@ let rule_used_defs = function
(* TODO: maybe this info could be passed on from previous passes without (* TODO: maybe this info could be passed on from previous passes without
walking through all exprs again *) walking through all exprs again *)
expr_used_defs e expr_used_defs e
| Ast.Call ((_ :: _path, _), _, _) -> VMap.empty | Ast.Call (subscope, subindex, _) ->
| Ast.Call (([], subscope), subindex, _) -> if ScopeName.path subscope = [] then
VMap.singleton (Scope subscope) (Mark.get (SubScopeName.get_info subindex)) VMap.singleton (Scope subscope) (Mark.get (SubScopeName.get_info subindex))
else VMap.empty
let build_program_dep_graph (prgm : 'm Ast.program) : SDependencies.t = let build_program_dep_graph (prgm : 'm Ast.program) : SDependencies.t =
let g = SDependencies.empty in let g = SDependencies.empty in
@ -272,7 +273,7 @@ let build_type_graph (structs : struct_ctx) (enums : enum_ctx) : TDependencies.t
let g = TDependencies.empty in let g = TDependencies.empty in
let g = let g =
StructName.Map.fold StructName.Map.fold
(fun s (path, fields) g -> (fun s fields g ->
StructField.Map.fold StructField.Map.fold
(fun _ typ g -> (fun _ typ g ->
let def = TVertex.Struct s in let def = TVertex.Struct s in
@ -282,9 +283,9 @@ let build_type_graph (structs : struct_ctx) (enums : enum_ctx) : TDependencies.t
(fun used g -> (fun used g ->
if TVertex.equal used def then if TVertex.equal used def then
Message.raise_spanned_error (Mark.get typ) Message.raise_spanned_error (Mark.get typ)
"The type %a%a is defined using itself, which is forbidden \ "The type %a is defined using itself, which is forbidden \
since Catala does not provide recursive types" since Catala does not provide recursive types"
Print.path path TVertex.format used TVertex.format used
else else
let edge = TDependencies.E.create used (Mark.get typ) def in let edge = TDependencies.E.create used (Mark.get typ) def in
TDependencies.add_edge_e g edge) TDependencies.add_edge_e g edge)
@ -294,7 +295,7 @@ let build_type_graph (structs : struct_ctx) (enums : enum_ctx) : TDependencies.t
in in
let g = let g =
EnumName.Map.fold EnumName.Map.fold
(fun e (path, cases) g -> (fun e cases g ->
EnumConstructor.Map.fold EnumConstructor.Map.fold
(fun _ typ g -> (fun _ typ g ->
let def = TVertex.Enum e in let def = TVertex.Enum e in
@ -304,9 +305,9 @@ let build_type_graph (structs : struct_ctx) (enums : enum_ctx) : TDependencies.t
(fun used g -> (fun used g ->
if TVertex.equal used def then if TVertex.equal used def then
Message.raise_spanned_error (Mark.get typ) Message.raise_spanned_error (Mark.get typ)
"The type %a%a is defined using itself, which is forbidden \ "The type %a is defined using itself, which is forbidden \
since Catala does not provide recursive types" since Catala does not provide recursive types"
Print.path path TVertex.format used TVertex.format used
else else
let edge = TDependencies.E.create used (Mark.get typ) def in let edge = TDependencies.E.create used (Mark.get typ) def in
TDependencies.add_edge_e g edge) TDependencies.add_edge_e g edge)

View File

@ -39,7 +39,7 @@ module TVertex : sig
type t = Struct of StructName.t | Enum of EnumName.t type t = Struct of StructName.t | Enum of EnumName.t
val format : Format.formatter -> t -> unit val format : Format.formatter -> t -> unit
val get_info : t -> StructName.info val get_info : t -> Uid.MarkedString.info
include Graph.Sig.COMPARABLE with type t := t include Graph.Sig.COMPARABLE with type t := t
end end

View File

@ -33,15 +33,6 @@ type ctx = {
modules : ctx ModuleName.Map.t; modules : ctx ModuleName.Map.t;
} }
let rec module_ctx ctx = function
| [] -> ctx
| (modname, mpos) :: path -> (
match ModuleName.Map.find_opt modname ctx.modules with
| None ->
Message.raise_spanned_error mpos "Module %a not found" ModuleName.format
modname
| Some ctx -> module_ctx ctx path)
let tag_with_log_entry let tag_with_log_entry
(e : untyped Ast.expr boxed) (e : untyped Ast.expr boxed)
(l : log_entry) (l : log_entry)
@ -66,16 +57,16 @@ let rec translate_expr (ctx : ctx) (e : D.expr) : untyped Ast.expr boxed =
ctx (Array.to_list vars) (Array.to_list new_vars) ctx (Array.to_list vars) (Array.to_list new_vars)
in in
Expr.eabs (Expr.bind new_vars (translate_expr ctx body)) tys m Expr.eabs (Expr.bind new_vars (translate_expr ctx body)) tys m
| ELocation (SubScopeVar { path; scope; alias; var }) -> | ELocation (SubScopeVar { scope; alias; var }) ->
(* When referring to a subscope variable in an expression, we are referring (* When referring to a subscope variable in an expression, we are referring
to the output, hence we take the last state. *) to the output, hence we take the last state. *)
let ctx = module_ctx ctx path in let ctx = List.fold_left (fun ctx m -> ModuleName.Map.find m ctx.modules) ctx (ScopeName.path scope) in
let var = let var =
match ScopeVar.Map.find (Mark.remove var) ctx.scope_var_mapping with match ScopeVar.Map.find (Mark.remove var) ctx.scope_var_mapping with
| WholeVar new_s_var -> Mark.copy var new_s_var | WholeVar new_s_var -> Mark.copy var new_s_var
| States states -> Mark.copy var (snd (List.hd (List.rev states))) | States states -> Mark.copy var (snd (List.hd (List.rev states)))
in in
Expr.elocation (SubScopeVar { path; scope; alias; var }) m Expr.elocation (SubScopeVar { scope; alias; var }) m
| ELocation (DesugaredScopeVar { name; state = None }) -> | ELocation (DesugaredScopeVar { name; state = None }) ->
Expr.elocation Expr.elocation
(ScopelangScopeVar (ScopelangScopeVar
@ -107,7 +98,7 @@ let rec translate_expr (ctx : ctx) (e : D.expr) : untyped Ast.expr boxed =
one possible matching structure *) one possible matching structure *)
Message.raise_spanned_error (Expr.mark_pos m) Message.raise_spanned_error (Expr.mark_pos m)
"Ambiguous structure field access" "Ambiguous structure field access"
| EDStructAccess { e; field; path = _; name_opt = Some name } -> | EDStructAccess { e; field; name_opt = Some name } ->
let e' = translate_expr ctx e in let e' = translate_expr ctx e in
let field = let field =
try try
@ -121,8 +112,8 @@ let rec translate_expr (ctx : ctx) (e : D.expr) : untyped Ast.expr boxed =
field StructName.format name field StructName.format name
in in
Expr.estructaccess ~e:e' ~field ~name m Expr.estructaccess ~e:e' ~field ~name m
| EScopeCall { path; scope; args } -> | EScopeCall { scope; args } ->
Expr.escopecall ~path ~scope Expr.escopecall ~scope
~args: ~args:
(ScopeVar.Map.fold (ScopeVar.Map.fold
(fun v e args' -> (fun v e args' ->
@ -624,13 +615,12 @@ let translate_rule
(D.ScopeDef.Map.find def_key exc_graphs) (D.ScopeDef.Map.find def_key exc_graphs)
~is_cond ~is_subscope_var:true ~is_cond ~is_subscope_var:true
in in
let subscop_path, subscop_real_name = let subscop_real_name =
SubScopeName.Map.find sub_scope_index scope.scope_sub_scopes SubScopeName.Map.find sub_scope_index scope.scope_sub_scopes
in in
Ast.Definition Ast.Definition
( ( SubScopeVar ( ( SubScopeVar
{ {
path = subscop_path;
scope = subscop_real_name; scope = subscop_real_name;
alias = sub_scope_index, var_pos; alias = sub_scope_index, var_pos;
var = var =

View File

@ -22,9 +22,9 @@ let struc
ctx ctx
(fmt : Format.formatter) (fmt : Format.formatter)
(name : StructName.t) (name : StructName.t)
((path, fields) : path * typ StructField.Map.t) : unit = (fields : typ StructField.Map.t) : unit =
Format.fprintf fmt "%a %a%a %a %a@\n@[<hov 2> %a@]@\n%a" Print.keyword Format.fprintf fmt "%a %a %a %a@\n@[<hov 2> %a@]@\n%a" Print.keyword
"struct" Print.path path StructName.format name Print.punctuation "=" "struct" StructName.format name Print.punctuation "="
Print.punctuation "{" Print.punctuation "{"
(Format.pp_print_list (Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n") ~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
@ -38,9 +38,9 @@ let enum
ctx ctx
(fmt : Format.formatter) (fmt : Format.formatter)
(name : EnumName.t) (name : EnumName.t)
((path, cases) : path * typ EnumConstructor.Map.t) : unit = (cases : typ EnumConstructor.Map.t) : unit =
Format.fprintf fmt "%a %a%a %a @\n@[<hov 2> %a@]" Print.keyword "enum" Format.fprintf fmt "%a %a %a @\n@[<hov 2> %a@]" Print.keyword "enum"
Print.path path EnumName.format name Print.punctuation "=" EnumName.format name Print.punctuation "="
(Format.pp_print_list (Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n") ~pp_sep:(fun fmt () -> Format.fprintf fmt "@\n")
(fun fmt (field_name, typ) -> (fun fmt (field_name, typ) ->
@ -93,9 +93,9 @@ let scope ?debug ctx fmt (name, (decl, _pos)) =
| Assertion e -> | Assertion e ->
Format.fprintf fmt "%a %a" Print.keyword "assert" Format.fprintf fmt "%a %a" Print.keyword "assert"
(Print.expr ?debug ()) e (Print.expr ?debug ()) e
| Call ((scope_path, scope_name), subscope_name, _) -> | Call (scope_name, subscope_name, _) ->
Format.fprintf fmt "%a %a%a%a%a%a" Print.keyword "call" Print.path Format.fprintf fmt "%a %a%a%a%a" Print.keyword "call"
scope_path ScopeName.format scope_name Print.punctuation "[" ScopeName.format scope_name Print.punctuation "["
SubScopeName.format subscope_name Print.punctuation "]")) SubScopeName.format subscope_name Print.punctuation "]"))
decl.scope_decl_rules decl.scope_decl_rules

View File

@ -22,16 +22,13 @@
open Catala_utils open Catala_utils
module Runtime = Runtime_ocaml.Runtime module Runtime = Runtime_ocaml.Runtime
module ModuleName = String module ModuleName = Uid.Module
(* TODO: should probably be turned into an Uid once we implement module import
directives; that will incur an additional resolution work on all paths
though *)
module ScopeName = Uid.Gen () module ScopeName = Uid.Gen_qualified ()
module TopdefName = Uid.Gen () module TopdefName = Uid.Gen_qualified ()
module StructName = Uid.Gen () module StructName = Uid.Gen_qualified ()
module StructField = Uid.Gen () module StructField = Uid.Gen ()
module EnumName = Uid.Gen () module EnumName = Uid.Gen_qualified ()
module EnumConstructor = Uid.Gen () module EnumConstructor = Uid.Gen ()
(** Only used by surface *) (** Only used by surface *)
@ -348,8 +345,6 @@ type lit =
| LDate of date | LDate of date
| LDuration of duration | LDuration of duration
type path = ModuleName.t Mark.pos list
(** External references are resolved to strings that point to functions or (** External references are resolved to strings that point to functions or
constants in the end, but we need to keep different references for typing *) constants in the end, but we need to keep different references for typing *)
type external_ref = type external_ref =
@ -368,14 +363,12 @@ type 'a glocation =
} }
-> < scopeVarSimpl : yes ; .. > glocation -> < scopeVarSimpl : yes ; .. > glocation
| SubScopeVar : { | SubScopeVar : {
path : path;
scope : ScopeName.t; scope : ScopeName.t;
alias : SubScopeName.t Mark.pos; alias : SubScopeName.t Mark.pos;
var : ScopeVar.t Mark.pos; var : ScopeVar.t Mark.pos;
} }
-> < explicitScopes : yes ; .. > glocation -> < explicitScopes : yes ; .. > glocation
| ToplevelVar : { | ToplevelVar : {
path : path;
name : TopdefName.t Mark.pos; name : TopdefName.t Mark.pos;
} }
-> < explicitScopes : yes ; .. > glocation -> < explicitScopes : yes ; .. > glocation
@ -456,13 +449,11 @@ and ('a, 'b, 'm) base_gexpr =
(* Early stages *) (* Early stages *)
| ELocation : 'b glocation -> ('a, (< .. > as 'b), 'm) base_gexpr | ELocation : 'b glocation -> ('a, (< .. > as 'b), 'm) base_gexpr
| EScopeCall : { | EScopeCall : {
path : path;
scope : ScopeName.t; scope : ScopeName.t;
args : ('a, 'm) gexpr ScopeVar.Map.t; args : ('a, 'm) gexpr ScopeVar.Map.t;
} }
-> ('a, < explicitScopes : yes ; .. >, 'm) base_gexpr -> ('a, < explicitScopes : yes ; .. >, 'm) base_gexpr
| EDStructAccess : { | EDStructAccess : {
path : path;
name_opt : StructName.t option; name_opt : StructName.t option;
e : ('a, 'm) gexpr; e : ('a, 'm) gexpr;
field : Ident.t; field : Ident.t;
@ -478,7 +469,6 @@ and ('a, 'b, 'm) base_gexpr =
(** Resolved struct/enums, after [desugared] *) (** Resolved struct/enums, after [desugared] *)
(* Lambda-like *) (* Lambda-like *)
| EExternal : { | EExternal : {
path : path;
name : external_ref Mark.pos; name : external_ref Mark.pos;
} }
-> ('a, < explicitScopes : no ; .. >, 't) base_gexpr -> ('a, < explicitScopes : no ; .. >, 't) base_gexpr
@ -594,8 +584,8 @@ type 'e code_item_list =
| Nil | Nil
| Cons of 'e code_item * ('e, 'e code_item_list) binder | Cons of 'e code_item * ('e, 'e code_item_list) binder
type struct_ctx = (path * typ StructField.Map.t) StructName.Map.t type struct_ctx = typ StructField.Map.t StructName.Map.t
type enum_ctx = (path * typ EnumConstructor.Map.t) EnumName.Map.t type enum_ctx = typ EnumConstructor.Map.t EnumName.Map.t
type scope_info = { type scope_info = {
in_struct_name : StructName.t; in_struct_name : StructName.t;

View File

@ -110,8 +110,8 @@ let subst binder vars =
let evar v mark = Mark.add mark (Bindlib.box_var v) let evar v mark = Mark.add mark (Bindlib.box_var v)
let eexternal ~path ~name mark = let eexternal ~name mark =
Mark.add mark (Bindlib.box (EExternal { path; name })) Mark.add mark (Bindlib.box (EExternal { name }))
let etuple args = Box.appn args @@ fun args -> ETuple args let etuple args = Box.appn args @@ fun args -> ETuple args
@ -155,8 +155,8 @@ let estruct ~name ~(fields : ('a, 't) boxed_gexpr StructField.Map.t) mark =
(fun fields -> EStruct { name; fields }) (fun fields -> EStruct { name; fields })
(Box.lift_struct (StructField.Map.map Box.lift fields)) (Box.lift_struct (StructField.Map.map Box.lift fields))
let edstructaccess ~path ~name_opt ~field ~e = let edstructaccess ~name_opt ~field ~e =
Box.app1 e @@ fun e -> EDStructAccess { path; name_opt; field; e } Box.app1 e @@ fun e -> EDStructAccess { name_opt; field; e }
let estructaccess ~name ~field ~e = let estructaccess ~name ~field ~e =
Box.app1 e @@ fun e -> EStructAccess { name; field; e } Box.app1 e @@ fun e -> EStructAccess { name; field; e }
@ -170,10 +170,10 @@ let ematch ~name ~e ~cases mark =
(Box.lift e) (Box.lift e)
(Box.lift_enum (EnumConstructor.Map.map Box.lift cases)) (Box.lift_enum (EnumConstructor.Map.map Box.lift cases))
let escopecall ~path ~scope ~args mark = let escopecall ~scope ~args mark =
Mark.add mark Mark.add mark
@@ Bindlib.box_apply @@ Bindlib.box_apply
(fun args -> EScopeCall { path; scope; args }) (fun args -> EScopeCall { scope; args })
(Box.lift_scope_vars (ScopeVar.Map.map Box.lift args)) (Box.lift_scope_vars (ScopeVar.Map.map Box.lift args))
(* - Manipulation of marks - *) (* - Manipulation of marks - *)
@ -253,7 +253,7 @@ let maybe_ty (type m) ?(typ = TAny) (m : m mark) : typ =
(* - Predefined types (option) - *) (* - Predefined types (option) - *)
let option_enum = EnumName.fresh ("eoption", Pos.no_pos) let option_enum = EnumName.fresh [] ("eoption", Pos.no_pos)
let none_constr = EnumConstructor.fresh ("ENone", Pos.no_pos) let none_constr = EnumConstructor.fresh ("ENone", Pos.no_pos)
let some_constr = EnumConstructor.fresh ("ESome", Pos.no_pos) let some_constr = EnumConstructor.fresh ("ESome", Pos.no_pos)
@ -275,7 +275,7 @@ let map
| EOp { op; tys } -> eop op tys m | EOp { op; tys } -> eop op tys m
| EArray args -> earray (List.map f args) m | EArray args -> earray (List.map f args) m
| EVar v -> evar (Var.translate v) m | EVar v -> evar (Var.translate v) m
| EExternal { path; name } -> eexternal ~path ~name m | EExternal { name } -> eexternal ~name m
| EAbs { binder; tys } -> | EAbs { binder; tys } ->
let vars, body = Bindlib.unmbind binder in let vars, body = Bindlib.unmbind binder in
let body = f body in let body = f body in
@ -297,15 +297,15 @@ let map
| EStruct { name; fields } -> | EStruct { name; fields } ->
let fields = StructField.Map.map f fields in let fields = StructField.Map.map f fields in
estruct ~name ~fields m estruct ~name ~fields m
| EDStructAccess { path; name_opt; field; e } -> | EDStructAccess { name_opt; field; e } ->
edstructaccess ~path ~name_opt ~field ~e:(f e) m edstructaccess ~name_opt ~field ~e:(f e) m
| EStructAccess { name; field; e } -> estructaccess ~name ~field ~e:(f e) m | EStructAccess { name; field; e } -> estructaccess ~name ~field ~e:(f e) m
| EMatch { name; e; cases } -> | EMatch { name; e; cases } ->
let cases = EnumConstructor.Map.map f cases in let cases = EnumConstructor.Map.map f cases in
ematch ~name ~e:(f e) ~cases m ematch ~name ~e:(f e) ~cases m
| EScopeCall { path; scope; args } -> | EScopeCall { scope; args } ->
let args = ScopeVar.Map.map f args in let args = ScopeVar.Map.map f args in
escopecall ~path ~scope ~args m escopecall ~scope ~args m
| ECustom { obj; targs; tret } -> ecustom obj targs tret m | ECustom { obj; targs; tret } -> ecustom obj targs tret m
let rec map_top_down ~f e = map ~f:(map_top_down ~f) (f e) let rec map_top_down ~f e = map ~f:(map_top_down ~f) (f e)
@ -372,7 +372,7 @@ let map_gather
let acc, args = lfoldmap args in let acc, args = lfoldmap args in
acc, earray args m acc, earray args m
| EVar v -> acc, evar (Var.translate v) m | EVar v -> acc, evar (Var.translate v) m
| EExternal { path; name } -> acc, eexternal ~path ~name m | EExternal { name } -> acc, eexternal ~name m
| EAbs { binder; tys } -> | EAbs { binder; tys } ->
let vars, body = Bindlib.unmbind binder in let vars, body = Bindlib.unmbind binder in
let acc, body = f body in let acc, body = f body in
@ -420,9 +420,9 @@ let map_gather
(acc, StructField.Map.empty) (acc, StructField.Map.empty)
in in
acc, estruct ~name ~fields m acc, estruct ~name ~fields m
| EDStructAccess { path; name_opt; field; e } -> | EDStructAccess { name_opt; field; e } ->
let acc, e = f e in let acc, e = f e in
acc, edstructaccess ~path ~name_opt ~field ~e m acc, edstructaccess ~name_opt ~field ~e m
| EStructAccess { name; field; e } -> | EStructAccess { name; field; e } ->
let acc, e = f e in let acc, e = f e in
acc, estructaccess ~name ~field ~e m acc, estructaccess ~name ~field ~e m
@ -437,7 +437,7 @@ let map_gather
(acc, EnumConstructor.Map.empty) (acc, EnumConstructor.Map.empty)
in in
acc, ematch ~name ~e ~cases m acc, ematch ~name ~e ~cases m
| EScopeCall { path; scope; args } -> | EScopeCall { scope; args } ->
let acc, args = let acc, args =
ScopeVar.Map.fold ScopeVar.Map.fold
(fun var e (acc, args) -> (fun var e (acc, args) ->
@ -445,7 +445,7 @@ let map_gather
join acc acc1, ScopeVar.Map.add var e args) join acc acc1, ScopeVar.Map.add var e args)
args (acc, ScopeVar.Map.empty) args (acc, ScopeVar.Map.empty)
in in
acc, escopecall ~path ~scope ~args m acc, escopecall ~scope ~args m
| ECustom { obj; targs; tret } -> acc, ecustom obj targs tret m | ECustom { obj; targs; tret } -> acc, ecustom obj targs tret m
(* - *) (* - *)
@ -518,8 +518,6 @@ let compare_lit (l1 : lit) (l2 : lit) =
| LDuration _, _ -> . | LDuration _, _ -> .
| _, LDuration _ -> . | _, LDuration _ -> .
let compare_path = List.compare (Mark.compare ModuleName.compare)
let compare_location let compare_location
(type a) (type a)
(x : a glocation Mark.pos) (x : a glocation Mark.pos)
@ -542,9 +540,9 @@ let compare_location
SubScopeVar { alias = ysubindex, _; var = ysubvar, _; _ } ) -> SubScopeVar { alias = ysubindex, _; var = ysubvar, _; _ } ) ->
let c = SubScopeName.compare xsubindex ysubindex in let c = SubScopeName.compare xsubindex ysubindex in
if c = 0 then ScopeVar.compare xsubvar ysubvar else c if c = 0 then ScopeVar.compare xsubvar ysubvar else c
| ( ToplevelVar { path = px; name = vx, _ }, | ( ToplevelVar { name = vx, _ },
ToplevelVar { path = py; name = vy, _ } ) -> ( ToplevelVar { name = vy, _ } ) ->
match compare_path px py with 0 -> TopdefName.compare vx vy | n -> n) TopdefName.compare vx vy
| DesugaredScopeVar _, _ -> -1 | DesugaredScopeVar _, _ -> -1
| _, DesugaredScopeVar _ -> 1 | _, DesugaredScopeVar _ -> 1
| ScopelangScopeVar _, _ -> -1 | ScopelangScopeVar _, _ -> -1
@ -554,7 +552,6 @@ let compare_location
| ToplevelVar _, _ -> . | ToplevelVar _, _ -> .
| _, ToplevelVar _ -> . | _, ToplevelVar _ -> .
let equal_path = List.equal (Mark.equal ModuleName.equal)
let equal_location a b = compare_location a b = 0 let equal_location a b = compare_location a b = 0
let equal_except ex1 ex2 = ex1 = ex2 let equal_except ex1 ex2 = ex1 = ex2
let compare_except ex1 ex2 = Stdlib.compare ex1 ex2 let compare_except ex1 ex2 = Stdlib.compare ex1 ex2
@ -583,8 +580,8 @@ and equal : type a. (a, 't) gexpr -> (a, 't) gexpr -> bool =
fun e1 e2 -> fun e1 e2 ->
match Mark.remove e1, Mark.remove e2 with match Mark.remove e1, Mark.remove e2 with
| EVar v1, EVar v2 -> Bindlib.eq_vars v1 v2 | EVar v1, EVar v2 -> Bindlib.eq_vars v1 v2
| EExternal { path = p1; name = n1 }, EExternal { path = p2; name = n2 } -> | EExternal { name = n1 }, EExternal { name = n2 } ->
Mark.equal equal_external_ref n1 n2 && equal_path p1 p2 Mark.equal equal_external_ref n1 n2
| ETuple es1, ETuple es2 -> equal_list es1 es2 | ETuple es1, ETuple es2 -> equal_list es1 es2
| ( ETupleAccess { e = e1; index = id1; size = s1 }, | ( ETupleAccess { e = e1; index = id1; size = s1 },
ETupleAccess { e = e2; index = id2; size = s2 } ) -> ETupleAccess { e = e2; index = id2; size = s2 } ) ->
@ -615,10 +612,9 @@ and equal : type a. (a, 't) gexpr -> (a, 't) gexpr -> bool =
| ( EStruct { name = s1; fields = fields1 }, | ( EStruct { name = s1; fields = fields1 },
EStruct { name = s2; fields = fields2 } ) -> EStruct { name = s2; fields = fields2 } ) ->
StructName.equal s1 s2 && StructField.Map.equal equal fields1 fields2 StructName.equal s1 s2 && StructField.Map.equal equal fields1 fields2
| ( EDStructAccess { e = e1; field = f1; name_opt = s1; path = p1 }, | ( EDStructAccess { e = e1; field = f1; name_opt = s1 },
EDStructAccess { e = e2; field = f2; name_opt = s2; path = p2 } ) -> EDStructAccess { e = e2; field = f2; name_opt = s2 } ) ->
Option.equal StructName.equal s1 s2 Option.equal StructName.equal s1 s2
&& equal_path p1 p2
&& Ident.equal f1 f2 && Ident.equal f1 f2
&& equal e1 e2 && equal e1 e2
| ( EStructAccess { e = e1; field = f1; name = s1 }, | ( EStructAccess { e = e1; field = f1; name = s1 },
@ -632,10 +628,9 @@ and equal : type a. (a, 't) gexpr -> (a, 't) gexpr -> bool =
EnumName.equal n1 n2 EnumName.equal n1 n2
&& equal e1 e2 && equal e1 e2
&& EnumConstructor.Map.equal equal cases1 cases2 && EnumConstructor.Map.equal equal cases1 cases2
| ( EScopeCall { path = p1; scope = s1; args = fields1 }, | ( EScopeCall { scope = s1; args = fields1 },
EScopeCall { path = p2; scope = s2; args = fields2 } ) -> EScopeCall { scope = s2; args = fields2 } ) ->
ScopeName.equal s1 s2 ScopeName.equal s1 s2
&& equal_path p1 p2
&& ScopeVar.Map.equal equal fields1 fields2 && ScopeVar.Map.equal equal fields1 fields2
| ( ECustom { obj = obj1; targs = targs1; tret = tret1 }, | ( ECustom { obj = obj1; targs = targs1; tret = tret1 },
ECustom { obj = obj2; targs = targs2; tret = tret2 } ) -> ECustom { obj = obj2; targs = targs2; tret = tret2 } ) ->
@ -667,8 +662,8 @@ let rec compare : type a. (a, _) gexpr -> (a, _) gexpr -> int =
List.compare compare a1 a2 List.compare compare a1 a2
| EVar v1, EVar v2 -> | EVar v1, EVar v2 ->
Bindlib.compare_vars v1 v2 Bindlib.compare_vars v1 v2
| EExternal { path = p1; name = n1 }, EExternal { path = p2; name = n2 } -> | EExternal { name = n1 }, EExternal { name = n2 } ->
compare_path p1 p2 @@< fun () -> Mark.compare compare_external_ref n1 n2 Mark.compare compare_external_ref n1 n2
| EAbs {binder=binder1; tys=typs1}, | EAbs {binder=binder1; tys=typs1},
EAbs {binder=binder2; tys=typs2} -> EAbs {binder=binder2; tys=typs2} ->
List.compare Type.compare typs1 typs2 @@< fun () -> List.compare Type.compare typs1 typs2 @@< fun () ->
@ -685,10 +680,9 @@ let rec compare : type a. (a, _) gexpr -> (a, _) gexpr -> int =
EStruct {name=name2; fields=field_map2 } -> EStruct {name=name2; fields=field_map2 } ->
StructName.compare name1 name2 @@< fun () -> StructName.compare name1 name2 @@< fun () ->
StructField.Map.compare compare field_map1 field_map2 StructField.Map.compare compare field_map1 field_map2
| EDStructAccess {e=e1; field=field_name1; name_opt=struct_name1; path=p1}, | EDStructAccess {e=e1; field=field_name1; name_opt=struct_name1},
EDStructAccess {e=e2; field=field_name2; name_opt=struct_name2; path=p2} -> EDStructAccess {e=e2; field=field_name2; name_opt=struct_name2} ->
compare e1 e2 @@< fun () -> compare e1 e2 @@< fun () ->
compare_path p1 p2 @@< fun () ->
Ident.compare field_name1 field_name2 @@< fun () -> Ident.compare field_name1 field_name2 @@< fun () ->
Option.compare StructName.compare struct_name1 struct_name2 Option.compare StructName.compare struct_name1 struct_name2
| EStructAccess {e=e1; field=field_name1; name=struct_name1 }, | EStructAccess {e=e1; field=field_name1; name=struct_name1 },
@ -701,9 +695,8 @@ let rec compare : type a. (a, _) gexpr -> (a, _) gexpr -> int =
EnumName.compare name1 name2 @@< fun () -> EnumName.compare name1 name2 @@< fun () ->
compare e1 e2 @@< fun () -> compare e1 e2 @@< fun () ->
EnumConstructor.Map.compare compare emap1 emap2 EnumConstructor.Map.compare compare emap1 emap2
| EScopeCall {path = p1; scope=name1; args=field_map1}, | EScopeCall {scope=name1; args=field_map1},
EScopeCall {path = p2; scope=name2; args=field_map2} -> EScopeCall {scope=name2; args=field_map2} ->
compare_path p1 p2 @@< fun () ->
ScopeName.compare name1 name2 @@< fun () -> ScopeName.compare name1 name2 @@< fun () ->
ScopeVar.Map.compare compare field_map1 field_map2 ScopeVar.Map.compare compare field_map1 field_map2
| ETuple es1, ETuple es2 -> | ETuple es1, ETuple es2 ->

View File

@ -38,7 +38,6 @@ val rebox : ('a any, 'm) gexpr -> ('a, 'm) boxed_gexpr
val evar : ('a, 'm) gexpr Var.t -> 'm mark -> ('a, 'm) boxed_gexpr val evar : ('a, 'm) gexpr Var.t -> 'm mark -> ('a, 'm) boxed_gexpr
val eexternal : val eexternal :
path:path ->
name:external_ref Mark.pos -> name:external_ref Mark.pos ->
'm mark -> 'm mark ->
(< explicitScopes : no ; .. >, 'm) boxed_gexpr (< explicitScopes : no ; .. >, 'm) boxed_gexpr
@ -119,7 +118,6 @@ val estruct :
('a any, 'm) boxed_gexpr ('a any, 'm) boxed_gexpr
val edstructaccess : val edstructaccess :
path:path ->
name_opt:StructName.t option -> name_opt:StructName.t option ->
field:Ident.t -> field:Ident.t ->
e:('a, 'm) boxed_gexpr -> e:('a, 'm) boxed_gexpr ->
@ -148,7 +146,6 @@ val ematch :
('a any, 'm) boxed_gexpr ('a any, 'm) boxed_gexpr
val escopecall : val escopecall :
path:path ->
scope:ScopeName.t -> scope:ScopeName.t ->
args:('a, 'm) boxed_gexpr ScopeVar.Map.t -> args:('a, 'm) boxed_gexpr ScopeVar.Map.t ->
'm mark -> 'm mark ->
@ -389,8 +386,6 @@ val format : Format.formatter -> ('a, 'm) gexpr -> unit
val equal_lit : lit -> lit -> bool val equal_lit : lit -> lit -> bool
val compare_lit : lit -> lit -> int val compare_lit : lit -> lit -> int
val equal_path : path -> path -> bool
val compare_path : path -> path -> int
val equal_location : 'a glocation Mark.pos -> 'a glocation Mark.pos -> bool val equal_location : 'a glocation Mark.pos -> 'a glocation Mark.pos -> bool
val compare_location : 'a glocation Mark.pos -> 'a glocation Mark.pos -> int val compare_location : 'a glocation Mark.pos -> 'a glocation Mark.pos -> int
val equal_except : except -> except -> bool val equal_except : except -> except -> bool

View File

@ -448,7 +448,6 @@ let rec runtime_to_val :
m ) m )
| TStruct name -> | TStruct name ->
StructName.Map.find name ctx.ctx_structs StructName.Map.find name ctx.ctx_structs
|> snd
|> StructField.Map.to_seq |> StructField.Map.to_seq
|> Seq.map2 |> Seq.map2
(fun o (fld, ty) -> fld, runtime_to_val eval_expr ctx m ty o) (fun o (fld, ty) -> fld, runtime_to_val eval_expr ctx m ty o)
@ -459,7 +458,7 @@ let rec runtime_to_val :
(* we only use non-constant constructors of arity 1, which allows us to (* we only use non-constant constructors of arity 1, which allows us to
always use the tag directly (ordered as declared in the constr map), and always use the tag directly (ordered as declared in the constr map), and
the field 0 *) the field 0 *)
let _path, cons_map = EnumName.Map.find name ctx.ctx_enums in let cons_map = EnumName.Map.find name ctx.ctx_enums in
let cons, ty = let cons, ty =
List.nth List.nth
(EnumConstructor.Map.bindings cons_map) (EnumConstructor.Map.bindings cons_map)
@ -497,7 +496,7 @@ and val_to_runtime :
List.map2 (val_to_runtime eval_expr ctx) ts es |> Array.of_list |> Obj.repr List.map2 (val_to_runtime eval_expr ctx) ts es |> Array.of_list |> Obj.repr
| TStruct name1, EStruct { name; fields } -> | TStruct name1, EStruct { name; fields } ->
assert (StructName.equal name name1); assert (StructName.equal name name1);
let _path, fld_tys = StructName.Map.find name ctx.ctx_structs in let fld_tys = StructName.Map.find name ctx.ctx_structs in
Seq.map2 Seq.map2
(fun (_, ty) (_, v) -> val_to_runtime eval_expr ctx ty v) (fun (_, ty) (_, v) -> val_to_runtime eval_expr ctx ty v)
(StructField.Map.to_seq fld_tys) (StructField.Map.to_seq fld_tys)
@ -506,7 +505,7 @@ and val_to_runtime :
|> Obj.repr |> Obj.repr
| TEnum name1, EInj { name; cons; e } -> | TEnum name1, EInj { name; cons; e } ->
assert (EnumName.equal name name1); assert (EnumName.equal name name1);
let _path, cons_map = EnumName.Map.find name ctx.ctx_enums in let cons_map = EnumName.Map.find name ctx.ctx_enums in
let rec find_tag n = function let rec find_tag n = function
| [] -> assert false | [] -> assert false
| (c, ty) :: _ when EnumConstructor.equal c cons -> n, ty | (c, ty) :: _ when EnumConstructor.equal c cons -> n, ty
@ -549,7 +548,11 @@ let rec evaluate_expr :
Message.raise_spanned_error pos Message.raise_spanned_error pos
"free variable found at evaluation (should not happen if term was \ "free variable found at evaluation (should not happen if term was \
well-typed)" well-typed)"
| EExternal { path; name } -> | EExternal { name } ->
let path = match Mark.remove name with
| External_value td -> TopdefName.path td
| External_scope s -> ScopeName.path s
in
let ty = let ty =
try try
let ctx = Program.module_ctx ctx path in let ctx = Program.module_ctx ctx path in
@ -563,11 +566,11 @@ let rec evaluate_expr :
pos ) pos )
with TopdefName.Map.Not_found _ | ScopeName.Map.Not_found _ -> with TopdefName.Map.Not_found _ | ScopeName.Map.Not_found _ ->
Message.raise_spanned_error pos Message.raise_spanned_error pos
"Reference to %a%a could not be resolved" Print.path path "Reference to %a could not be resolved"
Print.external_ref name Print.external_ref name
in in
let runtime_path = let runtime_path =
( List.map Mark.remove path, ( List.map ModuleName.to_string path,
match Mark.remove name with match Mark.remove name with
| External_value name -> Mark.remove (TopdefName.get_info name) | External_value name -> Mark.remove (TopdefName.get_info name)
| External_scope name -> Mark.remove (ScopeName.get_info name) ) | External_scope name -> Mark.remove (ScopeName.get_info name) )
@ -814,7 +817,7 @@ let interpret_program_lcalc p s : (Uid.MarkedString.info * ('a, 'm) gexpr) list
the types of the scope arguments. For [context] arguments, we can provide the types of the scope arguments. For [context] arguments, we can provide
an empty thunked term. But for [input] arguments of another type, we an empty thunked term. But for [input] arguments of another type, we
cannot provide anything so we have to fail. *) cannot provide anything so we have to fail. *)
let _path, taus = StructName.Map.find s_in ctx.ctx_structs in let taus = StructName.Map.find s_in ctx.ctx_structs in
let application_term = let application_term =
StructField.Map.map StructField.Map.map
(fun ty -> (fun ty ->
@ -864,7 +867,7 @@ let interpret_program_dcalc p s : (Uid.MarkedString.info * ('a, 'm) gexpr) list
the types of the scope arguments. For [context] arguments, we can provide the types of the scope arguments. For [context] arguments, we can provide
an empty thunked term. But for [input] arguments of another type, we an empty thunked term. But for [input] arguments of another type, we
cannot provide anything so we have to fail. *) cannot provide anything so we have to fail. *)
let _path, taus = StructName.Map.find s_in ctx.ctx_structs in let taus = StructName.Map.find s_in ctx.ctx_structs in
let application_term = let application_term =
StructField.Map.map StructField.Map.map
(fun ty -> (fun ty ->

View File

@ -347,7 +347,7 @@ let optimize_program (p : 'm program) : 'm program =
let test_iota_reduction_1 () = let test_iota_reduction_1 () =
let x = Var.make "x" in let x = Var.make "x" in
let enumT = EnumName.fresh ("t", Pos.no_pos) in let enumT = EnumName.fresh [] ("t", Pos.no_pos) in
let consA = EnumConstructor.fresh ("A", Pos.no_pos) in let consA = EnumConstructor.fresh ("A", Pos.no_pos) in
let consB = EnumConstructor.fresh ("B", Pos.no_pos) in let consB = EnumConstructor.fresh ("B", Pos.no_pos) in
let consC = EnumConstructor.fresh ("C", Pos.no_pos) in let consC = EnumConstructor.fresh ("C", Pos.no_pos) in
@ -387,7 +387,7 @@ let cases_of_list l : ('a, 't) boxed_gexpr EnumConstructor.Map.t =
(Untyped { pos = Pos.no_pos }) )) (Untyped { pos = Pos.no_pos }) ))
let test_iota_reduction_2 () = let test_iota_reduction_2 () =
let enumT = EnumName.fresh ("t", Pos.no_pos) in let enumT = EnumName.fresh [] ("t", Pos.no_pos) in
let consA = EnumConstructor.fresh ("A", Pos.no_pos) in let consA = EnumConstructor.fresh ("A", Pos.no_pos) in
let consB = EnumConstructor.fresh ("B", Pos.no_pos) in let consB = EnumConstructor.fresh ("B", Pos.no_pos) in
let consC = EnumConstructor.fresh ("C", Pos.no_pos) in let consC = EnumConstructor.fresh ("C", Pos.no_pos) in

View File

@ -86,8 +86,7 @@ let location (type a) (fmt : Format.formatter) (l : a glocation) : unit =
| SubScopeVar { alias = subindex; var = subvar; _ } -> | SubScopeVar { alias = subindex; var = subvar; _ } ->
Format.fprintf fmt "%a.%a" SubScopeName.format (Mark.remove subindex) Format.fprintf fmt "%a.%a" SubScopeName.format (Mark.remove subindex)
ScopeVar.format (Mark.remove subvar) ScopeVar.format (Mark.remove subvar)
| ToplevelVar { path = p; name } -> | ToplevelVar { name } ->
path fmt p;
TopdefName.format fmt (Mark.remove name) TopdefName.format fmt (Mark.remove name)
let enum_constructor (fmt : Format.formatter) (c : EnumConstructor.t) : unit = let enum_constructor (fmt : Format.formatter) (c : EnumConstructor.t) : unit =
@ -131,12 +130,11 @@ let rec typ_gen
match ctx with match ctx with
| None -> StructName.format fmt s | None -> StructName.format fmt s
| Some ctx -> | Some ctx ->
let p, fields = StructName.Map.find s ctx.ctx_structs in let fields = StructName.Map.find s ctx.ctx_structs in
if StructField.Map.is_empty fields then ( if StructField.Map.is_empty fields then (
path fmt p;
StructName.format fmt s) StructName.format fmt s)
else else
Format.fprintf fmt "@[<hv 2>%a%a %a@,%a@;<0 -2>%a@]" path p Format.fprintf fmt "@[<hv 2>%a %a@,%a@;<0 -2>%a@]"
StructName.format s StructName.format s
(pp_color_string (List.hd colors)) (pp_color_string (List.hd colors))
"{" "{"
@ -156,8 +154,8 @@ let rec typ_gen
match ctx with match ctx with
| None -> Format.fprintf fmt "@[<hov 2>%a@]" EnumName.format e | None -> Format.fprintf fmt "@[<hov 2>%a@]" EnumName.format e
| Some ctx -> | Some ctx ->
let p, def = EnumName.Map.find e ctx.ctx_enums in let def = EnumName.Map.find e ctx.ctx_enums in
Format.fprintf fmt "@[<hov 2>%a%a%a%a%a@]" path p EnumName.format e Format.fprintf fmt "@[<hov 2>%a%a%a%a@]" EnumName.format e
punctuation "[" punctuation "["
(EnumConstructor.Map.format_bindings (EnumConstructor.Map.format_bindings
~pp_sep:(fun fmt () -> Format.fprintf fmt "@ %a@ " punctuation "|") ~pp_sep:(fun fmt () -> Format.fprintf fmt "@ %a@ " punctuation "|")
@ -519,8 +517,7 @@ module ExprGen (C : EXPR_PARAM) = struct
else else
match Mark.remove e with match Mark.remove e with
| EVar v -> var fmt v | EVar v -> var fmt v
| EExternal { path = p; name } -> | EExternal { name } ->
path fmt p;
external_ref fmt name external_ref fmt name
| ETuple es -> | ETuple es ->
Format.fprintf fmt "@[<hov 2>%a%a%a@]" Format.fprintf fmt "@[<hov 2>%a%a%a@]"
@ -718,9 +715,8 @@ module ExprGen (C : EXPR_PARAM) = struct
Format.fprintf fmt "@[<hov 2>%a %t@ %a@ %a@]" punctuation "|" Format.fprintf fmt "@[<hov 2>%a %t@ %a@ %a@]" punctuation "|"
pp_cons_name punctuation "" (rhs exprc) e)) pp_cons_name punctuation "" (rhs exprc) e))
cases cases
| EScopeCall { path = scope_path; scope; args } -> | EScopeCall { scope; args } ->
Format.pp_open_hovbox fmt 2; Format.pp_open_hovbox fmt 2;
path fmt scope_path;
ScopeName.format fmt scope; ScopeName.format fmt scope;
Format.pp_print_space fmt (); Format.pp_print_space fmt ();
keyword fmt "of"; keyword fmt "of";
@ -862,8 +858,8 @@ let enum
decl_ctx decl_ctx
fmt fmt
(pp_name : Format.formatter -> unit) (pp_name : Format.formatter -> unit)
((p, c) : path * typ EnumConstructor.Map.t) = (c : typ EnumConstructor.Map.t) =
Format.fprintf fmt "@[<h 0>%a %a%t %a@ %a@]" keyword "type" path p pp_name Format.fprintf fmt "@[<h 0>%a %t %a@ %a@]" keyword "type" pp_name
punctuation "=" punctuation "="
(EnumConstructor.Map.format_bindings (EnumConstructor.Map.format_bindings
~pp_sep:(fun _ _ -> ()) ~pp_sep:(fun _ _ -> ())
@ -879,9 +875,9 @@ let struct_
decl_ctx decl_ctx
fmt fmt
(pp_name : Format.formatter -> unit) (pp_name : Format.formatter -> unit)
((p, c) : path * typ StructField.Map.t) = (c : typ StructField.Map.t) =
Format.fprintf fmt "@[<hv 0>@[<hv 2>@[<h>%a %a%t %a@;%a@]@;%a@]%a@]@;" keyword Format.fprintf fmt "@[<hv 0>@[<hv 2>@[<h>%a %t %a@;%a@]@;%a@]%a@]@;" keyword
"type" path p pp_name punctuation "=" punctuation "{" "type" pp_name punctuation "=" punctuation "{"
(StructField.Map.format_bindings (StructField.Map.format_bindings
~pp_sep:(fun _ _ -> ()) ~pp_sep:(fun _ _ -> ())
(fun fmt pp_n ty -> (fun fmt pp_n ty ->

View File

@ -15,7 +15,6 @@
License for the specific language governing permissions and limitations under License for the specific language governing permissions and limitations under
the License. *) the License. *)
open Catala_utils
open Definitions open Definitions
let map_exprs ~f ~varf { code_items; decl_ctx } = let map_exprs ~f ~varf { code_items; decl_ctx } =
@ -39,14 +38,9 @@ let empty_ctx =
ctx_modules = ModuleName.Map.empty; ctx_modules = ModuleName.Map.empty;
} }
let rec module_ctx ctx = function let module_ctx ctx path =
| [] -> ctx List.fold_left (fun ctx m -> ModuleName.Map.find m ctx.ctx_modules)
| (modname, mpos) :: path -> ( ctx path
match ModuleName.Map.find_opt modname ctx.ctx_modules with
| None ->
Message.raise_spanned_error mpos "Module %a not found" ModuleName.format
modname
| Some ctx -> module_ctx ctx path)
let get_scope_body { code_items; _ } scope = let get_scope_body { code_items; _ } scope =
match match

View File

@ -22,9 +22,9 @@ open Definitions
val empty_ctx : decl_ctx val empty_ctx : decl_ctx
val module_ctx : decl_ctx -> ModuleName.t Mark.pos list -> decl_ctx val module_ctx : decl_ctx -> Uid.Path.t -> decl_ctx
(** Follows a path to get the corresponding context for type and value (** Follows a path to get the corresponding context for type and value
declarations. Errors out if the module is not found *) declarations. *)
(** {2 Transformations} *) (** {2 Transformations} *)

View File

@ -130,10 +130,8 @@ let rec format_typ
(pp_color_string (List.hd colors)) (pp_color_string (List.hd colors))
")" ")"
| TStruct s -> | TStruct s ->
Print.path fmt (fst (A.StructName.Map.find s ctx.A.ctx_structs));
A.StructName.format fmt s A.StructName.format fmt s
| TEnum e -> | TEnum e ->
Print.path fmt (fst (A.EnumName.Map.find e ctx.A.ctx_enums));
A.EnumName.format fmt e A.EnumName.format fmt e
| TOption t -> | TOption t ->
Format.fprintf fmt "@[<hov 2>option %a@]" Format.fprintf fmt "@[<hov 2>option %a@]"
@ -325,11 +323,11 @@ module Env = struct
{ {
structs = structs =
A.StructName.Map.map A.StructName.Map.map
(fun (_path, ty) -> A.StructField.Map.map ast_to_typ ty) (fun ty -> A.StructField.Map.map ast_to_typ ty)
decl_ctx.ctx_structs; decl_ctx.ctx_structs;
enums = enums =
A.EnumName.Map.map A.EnumName.Map.map
(fun (_path, ty) -> A.EnumConstructor.Map.map ast_to_typ ty) (fun ty -> A.EnumConstructor.Map.map ast_to_typ ty)
decl_ctx.ctx_enums; decl_ctx.ctx_enums;
vars = Var.Map.empty; vars = Var.Map.empty;
scope_vars = A.ScopeVar.Map.empty; scope_vars = A.ScopeVar.Map.empty;
@ -347,14 +345,7 @@ module Env = struct
A.ScopeVar.Map.find_opt var vmap) A.ScopeVar.Map.find_opt var vmap)
let rec module_env path env = let rec module_env path env =
match path with List.fold_left (fun env m -> A.ModuleName.Map.find m env.modules) env path
| [] -> env
| (modname, mpos) :: path -> (
match A.ModuleName.Map.find_opt modname env.modules with
| None ->
Message.raise_spanned_error mpos "Module %a not found"
A.ModuleName.format modname
| Some env -> module_env path env)
let add v tau t = { t with vars = Var.Map.add v tau t.vars } let add v tau t = { t with vars = Var.Map.add v tau t.vars }
let add_var v typ t = add v (ast_to_typ typ) t let add_var v typ t = add v (ast_to_typ typ) t
@ -435,11 +426,11 @@ and typecheck_expr_top_down :
match loc with match loc with
| DesugaredScopeVar { name; _ } | ScopelangScopeVar { name } -> | DesugaredScopeVar { name; _ } | ScopelangScopeVar { name } ->
Env.get_scope_var env (Mark.remove name) Env.get_scope_var env (Mark.remove name)
| SubScopeVar { path; scope; var; _ } -> | SubScopeVar { scope; var; _ } ->
let env = Env.module_env path env in let env = Env.module_env (A.ScopeName.path scope) env in
Env.get_subscope_out_var env scope (Mark.remove var) Env.get_subscope_out_var env scope (Mark.remove var)
| ToplevelVar { path; name } -> | ToplevelVar { name } ->
let env = Env.module_env path env in let env = Env.module_env (A.TopdefName.path (Mark.remove name)) env in
Env.get_toplevel_var env (Mark.remove name) Env.get_toplevel_var env (Mark.remove name)
in in
let ty = let ty =
@ -452,7 +443,7 @@ and typecheck_expr_top_down :
Expr.elocation loc (mark_with_tau_and_unify (ast_to_typ ty)) Expr.elocation loc (mark_with_tau_and_unify (ast_to_typ ty))
| A.EStruct { name; fields } -> | A.EStruct { name; fields } ->
let mark = ty_mark (TStruct name) in let mark = ty_mark (TStruct name) in
let _path, str_ast = A.StructName.Map.find name ctx.A.ctx_structs in let str_ast = A.StructName.Map.find name ctx.A.ctx_structs in
let str = A.StructName.Map.find name env.structs in let str = A.StructName.Map.find name env.structs in
let _check_fields : unit = let _check_fields : unit =
let missing_fields, extra_fields = let missing_fields, extra_fields =
@ -493,7 +484,7 @@ and typecheck_expr_top_down :
fields fields
in in
Expr.estruct ~name ~fields mark Expr.estruct ~name ~fields mark
| A.EDStructAccess { e = e_struct; path = _; name_opt; field } -> | A.EDStructAccess { e = e_struct; name_opt; field } ->
let t_struct = let t_struct =
match name_opt with match name_opt with
| Some name -> TStruct name | Some name -> TStruct name
@ -514,7 +505,6 @@ and typecheck_expr_top_down :
"This is not a structure, cannot access field %s (%a)" field "This is not a structure, cannot access field %s (%a)" field
(format_typ ctx) (ty e_struct') (format_typ ctx) (ty e_struct')
in in
let path, _ = A.StructName.Map.find name ctx.ctx_structs in
let fld_ty = let fld_ty =
let str = let str =
try A.StructName.Map.find name env.structs try A.StructName.Map.find name env.structs
@ -549,7 +539,7 @@ and typecheck_expr_top_down :
A.StructField.Map.find field str A.StructField.Map.find field str
in in
let mark = mark_with_tau_and_unify fld_ty in let mark = mark_with_tau_and_unify fld_ty in
Expr.edstructaccess ~e:e_struct' ~path ~name_opt:(Some name) ~field mark Expr.edstructaccess ~e:e_struct' ~name_opt:(Some name) ~field mark
| A.EStructAccess { e = e_struct; name; field } -> | A.EStructAccess { e = e_struct; name; field } ->
let fld_ty = let fld_ty =
let str = let str =
@ -628,7 +618,7 @@ and typecheck_expr_top_down :
in in
Expr.ematch ~e:e1' ~name ~cases mark Expr.ematch ~e:e1' ~name ~cases mark
| A.EMatch { e = e1; name; cases } -> | A.EMatch { e = e1; name; cases } ->
let _path, cases_ty = A.EnumName.Map.find name ctx.A.ctx_enums in let cases_ty = A.EnumName.Map.find name ctx.A.ctx_enums in
let t_ret = unionfind ~pos:e1 (TAny (Any.fresh ())) in let t_ret = unionfind ~pos:e1 (TAny (Any.fresh ())) in
let mark = mark_with_tau_and_unify t_ret in let mark = mark_with_tau_and_unify t_ret in
let e1' = let e1' =
@ -647,7 +637,8 @@ and typecheck_expr_top_down :
cases cases
in in
Expr.ematch ~e:e1' ~name ~cases mark Expr.ematch ~e:e1' ~name ~cases mark
| A.EScopeCall { path; scope; args } -> | A.EScopeCall { scope; args } ->
let path = A.ScopeName.path scope in
let scope_out_struct = let scope_out_struct =
let ctx = Program.module_ctx ctx path in let ctx = Program.module_ctx ctx path in
(A.ScopeName.Map.find scope ctx.ctx_scopes).out_struct_name (A.ScopeName.Map.find scope ctx.ctx_scopes).out_struct_name
@ -664,7 +655,7 @@ and typecheck_expr_top_down :
(ast_to_typ (A.ScopeVar.Map.find name vars))) (ast_to_typ (A.ScopeVar.Map.find name vars)))
args args
in in
Expr.escopecall ~path ~scope ~args:args' mark Expr.escopecall ~scope ~args:args' mark
| A.ERaise ex -> Expr.eraise ex context_mark | A.ERaise ex -> Expr.eraise ex context_mark
| A.ECatch { body; exn; handler } -> | A.ECatch { body; exn; handler } ->
let body' = typecheck_expr_top_down ~leave_unresolved ctx env tau body in let body' = typecheck_expr_top_down ~leave_unresolved ctx env tau body in
@ -681,14 +672,18 @@ and typecheck_expr_top_down :
"Variable %s not found in the current context" (Bindlib.name_of v) "Variable %s not found in the current context" (Bindlib.name_of v)
in in
Expr.evar (Var.translate v) (mark_with_tau_and_unify tau') Expr.evar (Var.translate v) (mark_with_tau_and_unify tau')
| A.EExternal { path; name } -> | A.EExternal { name } ->
let path = match Mark.remove name with
| External_value td -> A.TopdefName.path td
| External_scope s -> A.ScopeName.path s
in
let ctx = Program.module_ctx ctx path in let ctx = Program.module_ctx ctx path in
let ty = let ty =
let not_found pr x = let not_found pr x =
Message.raise_spanned_error pos_e Message.raise_spanned_error pos_e
"Could not resolve the reference to %a%a.@ Make sure the \ "Could not resolve the reference to %a.@ Make sure the \
corresponding module was properly loaded?" corresponding module was properly loaded?"
Print.path path pr x pr x
in in
match Mark.remove name with match Mark.remove name with
| A.External_value name -> ( | A.External_value name -> (
@ -705,7 +700,7 @@ and typecheck_expr_top_down :
pos_e ) pos_e )
with A.ScopeName.Map.Not_found _ -> not_found A.ScopeName.format name) with A.ScopeName.Map.Not_found _ -> not_found A.ScopeName.format name)
in in
Expr.eexternal ~path ~name (mark_with_tau_and_unify ty) Expr.eexternal ~name (mark_with_tau_and_unify ty)
| A.ELit lit -> Expr.elit lit (ty_mark (lit_type lit)) | A.ELit lit -> Expr.elit lit (ty_mark (lit_type lit))
| A.ETuple es -> | A.ETuple es ->
let tys = List.map (fun _ -> unionfind (TAny (Any.fresh ()))) es in let tys = List.map (fun _ -> unionfind (TAny (Any.fresh ()))) es in
@ -1031,9 +1026,8 @@ let program ~leave_unresolved prg =
prg.decl_ctx with prg.decl_ctx with
ctx_structs = ctx_structs =
A.StructName.Map.mapi A.StructName.Map.mapi
(fun s_name (path, fields) -> (fun s_name (fields) ->
( path, ( A.StructField.Map.mapi
A.StructField.Map.mapi
(fun f_name (t : A.typ) -> (fun f_name (t : A.typ) ->
match Mark.remove t with match Mark.remove t with
| TAny -> | TAny ->
@ -1045,9 +1039,8 @@ let program ~leave_unresolved prg =
prg.decl_ctx.ctx_structs; prg.decl_ctx.ctx_structs;
ctx_enums = ctx_enums =
A.EnumName.Map.mapi A.EnumName.Map.mapi
(fun e_name (path, cons) -> (fun e_name (cons) ->
( path, ( A.EnumConstructor.Map.mapi
A.EnumConstructor.Map.mapi
(fun cons_name (t : A.typ) -> (fun cons_name (t : A.typ) ->
match Mark.remove t with match Mark.remove t with
| TAny -> | TAny ->

View File

@ -17,6 +17,7 @@
(** Typing for the default calculus. Because of the error terms, we perform type (** Typing for the default calculus. Because of the error terms, we perform type
inference using the classical W algorithm with union-find unification. *) inference using the classical W algorithm with union-find unification. *)
open Catala_utils
open Definitions open Definitions
module Env : sig module Env : sig
@ -28,7 +29,7 @@ module Env : sig
val add_scope_var : ScopeVar.t -> typ -> 'e t -> 'e t val add_scope_var : ScopeVar.t -> typ -> 'e t -> 'e t
val add_scope : ScopeName.t -> vars:typ ScopeVar.Map.t -> 'e t -> 'e t val add_scope : ScopeName.t -> vars:typ ScopeVar.Map.t -> 'e t -> 'e t
val add_module : ModuleName.t -> module_env:'e t -> 'e t -> 'e t val add_module : ModuleName.t -> module_env:'e t -> 'e t -> 'e t
val module_env : path -> 'e t -> 'e t val module_env : Uid.Path.t -> 'e t -> 'e t
val open_scope : ScopeName.t -> 'e t -> 'e t val open_scope : ScopeName.t -> 'e t -> 'e t
end end

View File

@ -162,7 +162,7 @@ let rec print_z3model_expr (ctx : context) (ty : typ) (e : Expr.expr) : string =
match Mark.remove ty with match Mark.remove ty with
| TLit ty -> print_lit ty | TLit ty -> print_lit ty
| TStruct name -> | TStruct name ->
let _path, s = StructName.Map.find name ctx.ctx_decl.ctx_structs in let s = StructName.Map.find name ctx.ctx_decl.ctx_structs in
let get_fieldname (fn : StructField.t) : string = let get_fieldname (fn : StructField.t) : string =
Mark.remove (StructField.get_info fn) Mark.remove (StructField.get_info fn)
in in
@ -188,7 +188,7 @@ let rec print_z3model_expr (ctx : context) (ty : typ) (e : Expr.expr) : string =
let fd = Expr.get_func_decl e in let fd = Expr.get_func_decl e in
let fd_name = Symbol.to_string (FuncDecl.get_name fd) in let fd_name = Symbol.to_string (FuncDecl.get_name fd) in
let _path, enum_ctrs = EnumName.Map.find name ctx.ctx_decl.ctx_enums in let enum_ctrs = EnumName.Map.find name ctx.ctx_decl.ctx_enums in
let case = let case =
List.find List.find
(fun (ctr, _) -> (fun (ctr, _) ->
@ -315,7 +315,7 @@ and find_or_create_enum (ctx : context) (enum : EnumName.t) :
match EnumName.Map.find_opt enum ctx.ctx_z3datatypes with match EnumName.Map.find_opt enum ctx.ctx_z3datatypes with
| Some e -> ctx, e | Some e -> ctx, e
| None -> | None ->
let _path, ctrs = EnumName.Map.find enum ctx.ctx_decl.ctx_enums in let ctrs = EnumName.Map.find enum ctx.ctx_decl.ctx_enums in
let ctx, z3_ctrs = let ctx, z3_ctrs =
EnumConstructor.Map.fold EnumConstructor.Map.fold
(fun ctr ty (ctx, ctrs) -> (fun ctr ty (ctx, ctrs) ->
@ -340,7 +340,7 @@ and find_or_create_struct (ctx : context) (s : StructName.t) :
| Some s -> ctx, s | Some s -> ctx, s
| None -> | None ->
let s_name = Mark.remove (StructName.get_info s) in let s_name = Mark.remove (StructName.get_info s) in
let _path, fields = StructName.Map.find s ctx.ctx_decl.ctx_structs in let fields = StructName.Map.find s ctx.ctx_decl.ctx_structs in
let z3_fieldnames = let z3_fieldnames =
List.map List.map
(fun f -> (fun f ->
@ -666,7 +666,7 @@ and translate_expr (ctx : context) (vc : typed expr) : context * Expr.expr =
mk_struct. The accessors of this constructor correspond to the field mk_struct. The accessors of this constructor correspond to the field
accesses *) accesses *)
let accessors = List.hd (Datatype.get_accessors z3_struct) in let accessors = List.hd (Datatype.get_accessors z3_struct) in
let _path, fields = StructName.Map.find name ctx.ctx_decl.ctx_structs in let fields = StructName.Map.find name ctx.ctx_decl.ctx_structs in
let idx_mappings = List.combine (StructField.Map.keys fields) accessors in let idx_mappings = List.combine (StructField.Map.keys fields) accessors in
let _, accessor = let _, accessor =
List.find (fun (field1, _) -> StructField.equal field field1) idx_mappings List.find (fun (field1, _) -> StructField.equal field field1) idx_mappings
@ -681,7 +681,7 @@ and translate_expr (ctx : context) (vc : typed expr) : context * Expr.expr =
let ctx, z3_enum = find_or_create_enum ctx name in let ctx, z3_enum = find_or_create_enum ctx name in
let ctx, z3_arg = translate_expr ctx e in let ctx, z3_arg = translate_expr ctx e in
let ctrs = Datatype.get_constructors z3_enum in let ctrs = Datatype.get_constructors z3_enum in
let _path, cons_map = EnumName.Map.find name ctx.ctx_decl.ctx_enums in let cons_map = EnumName.Map.find name ctx.ctx_decl.ctx_enums in
(* This should always succeed if the expression is well-typed in dcalc *) (* This should always succeed if the expression is well-typed in dcalc *)
let idx_mappings = List.combine (EnumConstructor.Map.keys cons_map) ctrs in let idx_mappings = List.combine (EnumConstructor.Map.keys cons_map) ctrs in
let _, ctr = let _, ctr =

View File

@ -12,6 +12,9 @@ scope T2:
definition o1 equals Mod_def.Enum1.No definition o1 equals Mod_def.Enum1.No
definition o2 equals t1.e1 definition o2 equals t1.e1
definition o3 equals t1.sr definition o3 equals t1.sr
assertion o1 = Mod_def.Enum1.No
assertion o2 = Mod_def.Enum1.Maybe
assertion o3 = $1000
``` ```
```catala-test-inline ```catala-test-inline