mirror of
https://github.com/CatalaLang/catala.git
synced 2024-11-08 07:51:43 +03:00
Renaming: more customisation
in particular, this avoids regression with reused struct fields getting renamed with indices, which would have required changes in e.g. `french_law/ocaml/bench.ml`
This commit is contained in:
parent
acc13867bf
commit
8b06511915
@ -735,7 +735,7 @@ let format_program
|
|||||||
~reserved:ocaml_keywords
|
~reserved:ocaml_keywords
|
||||||
(* TODO: add catala runtime built-ins as reserved as well ? *)
|
(* TODO: add catala runtime built-ins as reserved as well ? *)
|
||||||
~reset_context_for_closed_terms:true ~skip_constant_binders:true
|
~reset_context_for_closed_terms:true ~skip_constant_binders:true
|
||||||
~constant_binder_name:(Some "_")
|
~constant_binder_name:(Some "_") ~namespaced_fields_constrs:true
|
||||||
in
|
in
|
||||||
let type_ordering =
|
let type_ordering =
|
||||||
let open Scopelang.Dependency.TVertex in
|
let open Scopelang.Dependency.TVertex in
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
open Catala_utils
|
open Catala_utils
|
||||||
open Shared_ast
|
open Shared_ast
|
||||||
|
|
||||||
|
val ocaml_keywords : string list
|
||||||
|
|
||||||
(** Formats a lambda calculus program into a valid OCaml program *)
|
(** Formats a lambda calculus program into a valid OCaml program *)
|
||||||
|
|
||||||
val typ_needs_parens : typ -> bool
|
val typ_needs_parens : typ -> bool
|
||||||
|
@ -37,16 +37,18 @@ module To_jsoo = struct
|
|||||||
other modules: here everything is flattened in the current namespace *)
|
other modules: here everything is flattened in the current namespace *)
|
||||||
let format_struct_name ppf name =
|
let format_struct_name ppf name =
|
||||||
StructName.to_string name
|
StructName.to_string name
|
||||||
|
|> String.to_ascii
|
||||||
|
|> String.uncapitalize_ascii
|
||||||
|> String.map (function '.' -> '_' | c -> c)
|
|> String.map (function '.' -> '_' | c -> c)
|
||||||
|> String.to_snake_case
|
|
||||||
|> Format.pp_print_string ppf
|
|> Format.pp_print_string ppf
|
||||||
|
|
||||||
(* Supersedes [To_ocaml.format_enum_name], which can refer to enums from other
|
(* Supersedes [To_ocaml.format_enum_name], which can refer to enums from other
|
||||||
modules: here everything is flattened in the current namespace *)
|
modules: here everything is flattened in the current namespace *)
|
||||||
let format_enum_name ppf name =
|
let format_enum_name ppf name =
|
||||||
EnumName.to_string name
|
EnumName.to_string name
|
||||||
|
|> String.to_ascii
|
||||||
|
|> String.uncapitalize_ascii
|
||||||
|> String.map (function '.' -> '_' | c -> c)
|
|> String.map (function '.' -> '_' | c -> c)
|
||||||
|> String.to_snake_case
|
|
||||||
|> Format.pp_print_string ppf
|
|> Format.pp_print_string ppf
|
||||||
|
|
||||||
let format_tlit (fmt : Format.formatter) (l : typ_lit) : unit =
|
let format_tlit (fmt : Format.formatter) (l : typ_lit) : unit =
|
||||||
@ -477,6 +479,19 @@ let run
|
|||||||
Driver.Passes.lcalc options ~includes ~optimize ~check_invariants
|
Driver.Passes.lcalc options ~includes ~optimize ~check_invariants
|
||||||
~closure_conversion ~typed:Expr.typed ~monomorphize_types
|
~closure_conversion ~typed:Expr.typed ~monomorphize_types
|
||||||
in
|
in
|
||||||
|
let prg, ren_ctx =
|
||||||
|
Program.rename_ids prg ~reserved:To_ocaml.ocaml_keywords
|
||||||
|
~reset_context_for_closed_terms:true ~skip_constant_binders:true
|
||||||
|
~constant_binder_name:None ~namespaced_fields_constrs:true
|
||||||
|
in
|
||||||
|
let type_ordering =
|
||||||
|
let open Scopelang.Dependency.TVertex in
|
||||||
|
List.map
|
||||||
|
(function
|
||||||
|
| Struct s -> Struct (Expr.Renaming.struct_name ren_ctx s)
|
||||||
|
| Enum e -> Enum (Expr.Renaming.enum_name ren_ctx e))
|
||||||
|
type_ordering
|
||||||
|
in
|
||||||
let jsoo_output_file, with_formatter =
|
let jsoo_output_file, with_formatter =
|
||||||
Driver.Commands.get_output_format options ~ext:"_api_web.ml" output
|
Driver.Commands.get_output_format options ~ext:"_api_web.ml" output
|
||||||
in
|
in
|
||||||
|
@ -624,6 +624,7 @@ let program_to_graph
|
|||||||
(Expr.Renaming.get_ctx
|
(Expr.Renaming.get_ctx
|
||||||
{
|
{
|
||||||
Expr.Renaming.reserved = [];
|
Expr.Renaming.reserved = [];
|
||||||
|
sanitize_varname = String.to_snake_case;
|
||||||
reset_context_for_closed_terms = false;
|
reset_context_for_closed_terms = false;
|
||||||
skip_constant_binders = false;
|
skip_constant_binders = false;
|
||||||
constant_binder_name = None;
|
constant_binder_name = None;
|
||||||
|
@ -879,6 +879,7 @@ module Renaming = struct
|
|||||||
|
|
||||||
type config = {
|
type config = {
|
||||||
reserved : string list;
|
reserved : string list;
|
||||||
|
sanitize_varname : string -> string;
|
||||||
reset_context_for_closed_terms : bool;
|
reset_context_for_closed_terms : bool;
|
||||||
skip_constant_binders : bool;
|
skip_constant_binders : bool;
|
||||||
constant_binder_name : string option;
|
constant_binder_name : string option;
|
||||||
@ -887,6 +888,7 @@ module Renaming = struct
|
|||||||
type context = {
|
type context = {
|
||||||
bindCtx : (module BindlibCtxt);
|
bindCtx : (module BindlibCtxt);
|
||||||
bcontext : DefaultBindlibCtxRename.ctxt;
|
bcontext : DefaultBindlibCtxRename.ctxt;
|
||||||
|
vars : string -> string;
|
||||||
scopes : ScopeName.t -> ScopeName.t;
|
scopes : ScopeName.t -> ScopeName.t;
|
||||||
topdefs : TopdefName.t -> TopdefName.t;
|
topdefs : TopdefName.t -> TopdefName.t;
|
||||||
structs : StructName.t -> StructName.t;
|
structs : StructName.t -> StructName.t;
|
||||||
@ -956,6 +958,7 @@ module Renaming = struct
|
|||||||
List.fold_left
|
List.fold_left
|
||||||
(fun ctx name -> DefaultBindlibCtxRename.reserve_name name ctx)
|
(fun ctx name -> DefaultBindlibCtxRename.reserve_name name ctx)
|
||||||
BindCtx.empty_ctxt cfg.reserved;
|
BindCtx.empty_ctxt cfg.reserved;
|
||||||
|
vars = cfg.sanitize_varname;
|
||||||
scopes = Fun.id;
|
scopes = Fun.id;
|
||||||
topdefs = Fun.id;
|
topdefs = Fun.id;
|
||||||
structs = Fun.id;
|
structs = Fun.id;
|
||||||
@ -976,7 +979,7 @@ module Renaming = struct
|
|||||||
| EExternal { name = External_value d, pos }, m ->
|
| EExternal { name = External_value d, pos }, m ->
|
||||||
eexternal ~name:(External_value (ctx.topdefs d), pos) m
|
eexternal ~name:(External_value (ctx.topdefs d), pos) m
|
||||||
| EAbs { binder; tys }, m ->
|
| EAbs { binder; tys }, m ->
|
||||||
let vars, body, ctx = unmbind_in ctx ~fname:String.to_snake_case binder in
|
let vars, body, ctx = unmbind_in ctx ~fname:ctx.vars binder in
|
||||||
let body = expr ctx body in
|
let body = expr ctx body in
|
||||||
let binder = bind vars body in
|
let binder = bind vars body in
|
||||||
eabs binder (List.map (typ ctx) tys) m
|
eabs binder (List.map (typ ctx) tys) m
|
||||||
|
@ -398,6 +398,7 @@ val remove_logging_calls :
|
|||||||
module Renaming : sig
|
module Renaming : sig
|
||||||
type config = {
|
type config = {
|
||||||
reserved : string list; (** Use for keywords and built-ins *)
|
reserved : string list; (** Use for keywords and built-ins *)
|
||||||
|
sanitize_varname : string -> string; (** Typically String.to_snake_case *)
|
||||||
reset_context_for_closed_terms : bool; (** See [Bindlib.Rename] *)
|
reset_context_for_closed_terms : bool; (** See [Bindlib.Rename] *)
|
||||||
skip_constant_binders : bool; (** See [Bindlib.Rename] *)
|
skip_constant_binders : bool; (** See [Bindlib.Rename] *)
|
||||||
constant_binder_name : string option; (** See [Bindlib.Rename] *)
|
constant_binder_name : string option; (** See [Bindlib.Rename] *)
|
||||||
|
@ -97,19 +97,28 @@ let modules_to_list (mt : module_tree) =
|
|||||||
in
|
in
|
||||||
List.rev (aux [] mt)
|
List.rev (aux [] mt)
|
||||||
|
|
||||||
(* Todo? - add handling for specific naming constraints (automatically convert
|
let cap s = String.to_ascii s |> String.capitalize_ascii
|
||||||
to camel/snake-case, etc.) - register module names as reserved names *)
|
let uncap s = String.to_ascii s |> String.uncapitalize_ascii
|
||||||
|
|
||||||
|
(* Todo? - handle separate namespaces ? (e.g. allow a field and var to have the
|
||||||
|
same name for backends that support it) - register module names as reserved
|
||||||
|
names *)
|
||||||
let rename_ids
|
let rename_ids
|
||||||
~reserved
|
~reserved
|
||||||
~reset_context_for_closed_terms
|
~reset_context_for_closed_terms
|
||||||
~skip_constant_binders
|
~skip_constant_binders
|
||||||
~constant_binder_name
|
~constant_binder_name
|
||||||
|
~namespaced_fields_constrs
|
||||||
|
?(f_var = String.to_snake_case)
|
||||||
|
?(f_struct = cap)
|
||||||
|
?(f_field = uncap)
|
||||||
|
?(f_enum = cap)
|
||||||
|
?(f_constr = cap)
|
||||||
p =
|
p =
|
||||||
let cap s = String.to_camel_case s in
|
|
||||||
let uncap s = String.to_snake_case s in
|
|
||||||
let cfg =
|
let cfg =
|
||||||
{
|
{
|
||||||
Expr.Renaming.reserved;
|
Expr.Renaming.reserved;
|
||||||
|
sanitize_varname = f_var;
|
||||||
reset_context_for_closed_terms;
|
reset_context_for_closed_terms;
|
||||||
skip_constant_binders;
|
skip_constant_binders;
|
||||||
constant_binder_name;
|
constant_binder_name;
|
||||||
@ -119,6 +128,7 @@ let rename_ids
|
|||||||
(* Each module needs its separate ctx since resolution is qualified ; and name
|
(* Each module needs its separate ctx since resolution is qualified ; and name
|
||||||
resolution in a given module must be processed consistently independently
|
resolution in a given module must be processed consistently independently
|
||||||
on the current context. *)
|
on the current context. *)
|
||||||
|
let ctx0 = ctx in
|
||||||
let module PathMap = Map.Make (Uid.Path) in
|
let module PathMap = Map.Make (Uid.Path) in
|
||||||
let pctxmap = PathMap.singleton [] ctx in
|
let pctxmap = PathMap.singleton [] ctx in
|
||||||
let pctxmap, structs_map, fields_map, ctx_structs =
|
let pctxmap, structs_map, fields_map, ctx_structs =
|
||||||
@ -134,20 +144,23 @@ let rename_ids
|
|||||||
try pctxmap, PathMap.find path pctxmap
|
try pctxmap, PathMap.find path pctxmap
|
||||||
with PathMap.Not_found _ -> PathMap.add path ctx pctxmap, ctx
|
with PathMap.Not_found _ -> PathMap.add path ctx pctxmap, ctx
|
||||||
in
|
in
|
||||||
let id, ctx = Expr.Renaming.new_id ctx (cap str) in
|
let id, ctx = Expr.Renaming.new_id ctx (f_struct str) in
|
||||||
let new_name = StructName.fresh path (id, pos) in
|
let new_name = StructName.fresh path (id, pos) in
|
||||||
let ctx, fields_map, ctx_fields =
|
let ctx1, fields_map, ctx_fields =
|
||||||
StructField.Map.fold
|
StructField.Map.fold
|
||||||
(fun name ty (ctx, fields_map, ctx_fields) ->
|
(fun name ty (ctx, fields_map, ctx_fields) ->
|
||||||
let str, pos = StructField.get_info name in
|
let str, pos = StructField.get_info name in
|
||||||
let id, ctx = Expr.Renaming.new_id ctx (uncap str) in
|
let id, ctx = Expr.Renaming.new_id ctx (f_field str) in
|
||||||
let new_name = StructField.fresh (id, pos) in
|
let new_name = StructField.fresh (id, pos) in
|
||||||
( ctx,
|
( ctx,
|
||||||
StructField.Map.add name new_name fields_map,
|
StructField.Map.add name new_name fields_map,
|
||||||
StructField.Map.add new_name ty ctx_fields ))
|
StructField.Map.add new_name ty ctx_fields ))
|
||||||
fields
|
fields
|
||||||
(ctx, fields_map, StructField.Map.empty)
|
( (if namespaced_fields_constrs then ctx0 else ctx),
|
||||||
|
fields_map,
|
||||||
|
StructField.Map.empty )
|
||||||
in
|
in
|
||||||
|
let ctx = if namespaced_fields_constrs then ctx else ctx1 in
|
||||||
( PathMap.add path ctx pctxmap,
|
( PathMap.add path ctx pctxmap,
|
||||||
StructName.Map.add name new_name structs_map,
|
StructName.Map.add name new_name structs_map,
|
||||||
fields_map,
|
fields_map,
|
||||||
@ -167,20 +180,23 @@ let rename_ids
|
|||||||
try pctxmap, PathMap.find path pctxmap
|
try pctxmap, PathMap.find path pctxmap
|
||||||
with Not_found -> PathMap.add path ctx pctxmap, ctx
|
with Not_found -> PathMap.add path ctx pctxmap, ctx
|
||||||
in
|
in
|
||||||
let id, ctx = Expr.Renaming.new_id ctx (cap str) in
|
let id, ctx = Expr.Renaming.new_id ctx (f_enum str) in
|
||||||
let new_name = EnumName.fresh path (id, pos) in
|
let new_name = EnumName.fresh path (id, pos) in
|
||||||
let ctx, constrs_map, ctx_constrs =
|
let ctx1, constrs_map, ctx_constrs =
|
||||||
EnumConstructor.Map.fold
|
EnumConstructor.Map.fold
|
||||||
(fun name ty (ctx, constrs_map, ctx_constrs) ->
|
(fun name ty (ctx, constrs_map, ctx_constrs) ->
|
||||||
let str, pos = EnumConstructor.get_info name in
|
let str, pos = EnumConstructor.get_info name in
|
||||||
let id, ctx = Expr.Renaming.new_id ctx (cap str) in
|
let id, ctx = Expr.Renaming.new_id ctx (f_constr str) in
|
||||||
let new_name = EnumConstructor.fresh (id, pos) in
|
let new_name = EnumConstructor.fresh (id, pos) in
|
||||||
( ctx,
|
( ctx,
|
||||||
EnumConstructor.Map.add name new_name constrs_map,
|
EnumConstructor.Map.add name new_name constrs_map,
|
||||||
EnumConstructor.Map.add new_name ty ctx_constrs ))
|
EnumConstructor.Map.add new_name ty ctx_constrs ))
|
||||||
constrs
|
constrs
|
||||||
(ctx, constrs_map, EnumConstructor.Map.empty)
|
( (if namespaced_fields_constrs then ctx0 else ctx),
|
||||||
|
constrs_map,
|
||||||
|
EnumConstructor.Map.empty )
|
||||||
in
|
in
|
||||||
|
let ctx = if namespaced_fields_constrs then ctx else ctx1 in
|
||||||
( PathMap.add path ctx pctxmap,
|
( PathMap.add path ctx pctxmap,
|
||||||
EnumName.Map.add name new_name enums_map,
|
EnumName.Map.add name new_name enums_map,
|
||||||
constrs_map,
|
constrs_map,
|
||||||
@ -218,7 +234,7 @@ let rename_ids
|
|||||||
try pctxmap, PathMap.find path pctxmap
|
try pctxmap, PathMap.find path pctxmap
|
||||||
with Not_found -> PathMap.add path ctx pctxmap, ctx
|
with Not_found -> PathMap.add path ctx pctxmap, ctx
|
||||||
in
|
in
|
||||||
let id, ctx = Expr.Renaming.new_id ctx (uncap str) in
|
let id, ctx = Expr.Renaming.new_id ctx (f_var str) in
|
||||||
let new_name = ScopeName.fresh path (id, pos) in
|
let new_name = ScopeName.fresh path (id, pos) in
|
||||||
( PathMap.add path ctx pctxmap,
|
( PathMap.add path ctx pctxmap,
|
||||||
ScopeName.Map.add name new_name scopes_map,
|
ScopeName.Map.add name new_name scopes_map,
|
||||||
@ -243,7 +259,7 @@ let rename_ids
|
|||||||
try pctxmap, PathMap.find path pctxmap
|
try pctxmap, PathMap.find path pctxmap
|
||||||
with Not_found -> PathMap.add path ctx pctxmap, ctx
|
with Not_found -> PathMap.add path ctx pctxmap, ctx
|
||||||
in
|
in
|
||||||
let id, ctx = Expr.Renaming.new_id ctx (uncap str) in
|
let id, ctx = Expr.Renaming.new_id ctx (f_var str) in
|
||||||
let new_name = TopdefName.fresh path (id, pos) in
|
let new_name = TopdefName.fresh path (id, pos) in
|
||||||
( PathMap.add path ctx pctxmap,
|
( PathMap.add path ctx pctxmap,
|
||||||
TopdefName.Map.add name new_name topdefs_map,
|
TopdefName.Map.add name new_name topdefs_map,
|
||||||
|
@ -62,12 +62,26 @@ val rename_ids :
|
|||||||
reset_context_for_closed_terms:bool ->
|
reset_context_for_closed_terms:bool ->
|
||||||
skip_constant_binders:bool ->
|
skip_constant_binders:bool ->
|
||||||
constant_binder_name:string option ->
|
constant_binder_name:string option ->
|
||||||
|
namespaced_fields_constrs:bool ->
|
||||||
|
?f_var:(string -> string) ->
|
||||||
|
?f_struct:(string -> string) ->
|
||||||
|
?f_field:(string -> string) ->
|
||||||
|
?f_enum:(string -> string) ->
|
||||||
|
?f_constr:(string -> string) ->
|
||||||
('a, 't) gexpr program ->
|
('a, 't) gexpr program ->
|
||||||
('a, 't) gexpr program * Expr.Renaming.context
|
('a, 't) gexpr program * Expr.Renaming.context
|
||||||
(** Renames all idents (variables, types, struct and enum names, fields and
|
(** Renames all idents (variables, types, struct and enum names, fields and
|
||||||
constructors) to dispel ambiguities in the target language. Names in
|
constructors) to dispel ambiguities in the target language. Names in
|
||||||
[reserved], typically keywords and built-ins, will be avoided ; the meaning
|
[reserved], typically keywords and built-ins, will be avoided ; the meaning
|
||||||
of the flags is described in [Bindlib.Renaming].
|
of the following three flags is described in [Bindlib.Renaming].
|
||||||
|
|
||||||
|
if [namespaced_fields_constrs] is true, then struct fields and enum
|
||||||
|
constructors can reuse names from other fields/constructors or other idents.
|
||||||
|
|
||||||
|
The [f_*] optional arguments sanitize the different kinds of ids. The
|
||||||
|
default is what is used for OCaml: project to ASCII, capitalise structs,
|
||||||
|
enums (both modules in the backend) and constructors, lowercase fields, and
|
||||||
|
rewrite variables to snake case.
|
||||||
|
|
||||||
In the returned program, it is safe to directly use `Bindlib.name_of` on
|
In the returned program, it is safe to directly use `Bindlib.name_of` on
|
||||||
variables for printing. The same is true for `StructName.get_info` etc. *)
|
variables for printing. The same is true for `StructName.get_info` etc. *)
|
||||||
|
@ -19,13 +19,13 @@ module Str1 = struct
|
|||||||
type t = {fld1: Enum1.t; fld2: integer}
|
type t = {fld1: Enum1.t; fld2: integer}
|
||||||
end
|
end
|
||||||
|
|
||||||
module SIn = struct
|
module S_in = struct
|
||||||
type t = unit
|
type t = unit
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
let s (s_in: SIn.t) : S.t =
|
let s (s_in: S_in.t) : S.t =
|
||||||
let sr1: money =
|
let sr: money =
|
||||||
match
|
match
|
||||||
(match
|
(match
|
||||||
(handle_exceptions
|
(handle_exceptions
|
||||||
@ -56,7 +56,7 @@ let s (s_in: SIn.t) : S.t =
|
|||||||
end_line=16; end_column=12;
|
end_line=16; end_column=12;
|
||||||
law_headings=["Test modules + inclusions 1"]}])))
|
law_headings=["Test modules + inclusions 1"]}])))
|
||||||
| Eoption.ESome arg -> arg in
|
| Eoption.ESome arg -> arg in
|
||||||
let e2: Enum1.t =
|
let e1: Enum1.t =
|
||||||
match
|
match
|
||||||
(match
|
(match
|
||||||
(handle_exceptions
|
(handle_exceptions
|
||||||
@ -86,7 +86,7 @@ let s (s_in: SIn.t) : S.t =
|
|||||||
end_line=17; end_column=12;
|
end_line=17; end_column=12;
|
||||||
law_headings=["Test modules + inclusions 1"]}])))
|
law_headings=["Test modules + inclusions 1"]}])))
|
||||||
| Eoption.ESome arg -> arg in
|
| Eoption.ESome arg -> arg in
|
||||||
{S.sr = sr1; S.e1 = e2}
|
{S.sr = sr; S.e1 = e1}
|
||||||
|
|
||||||
let half : integer -> decimal =
|
let half : integer -> decimal =
|
||||||
fun (x: integer) ->
|
fun (x: integer) ->
|
||||||
|
@ -45,20 +45,20 @@ module S = struct
|
|||||||
type t = {a: bool}
|
type t = {a: bool}
|
||||||
end
|
end
|
||||||
|
|
||||||
module SIn = struct
|
module S_in = struct
|
||||||
type t = {a_in: unit -> (bool) Eoption.t}
|
type t = {a_in: unit -> (bool) Eoption.t}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
let s (s_in: SIn.t) : S.t =
|
let s (s_in: S_in.t) : S.t =
|
||||||
let a1: unit -> (bool) Eoption.t = s_in.SIn.a_in in
|
let a: unit -> (bool) Eoption.t = s_in.S_in.a_in in
|
||||||
let a2: bool =
|
let a1: bool =
|
||||||
match
|
match
|
||||||
(match
|
(match
|
||||||
(handle_exceptions
|
(handle_exceptions
|
||||||
[|{filename="tests/name_resolution/good/let_in2.catala_en";
|
[|{filename="tests/name_resolution/good/let_in2.catala_en";
|
||||||
start_line=7; start_column=18; end_line=7; end_column=19;
|
start_line=7; start_column=18; end_line=7; end_column=19;
|
||||||
law_headings=["Article"]}|] ([|(a1 ())|]))
|
law_headings=["Article"]}|] ([|(a ())|]))
|
||||||
with
|
with
|
||||||
| Eoption.ENone _ ->
|
| Eoption.ENone _ ->
|
||||||
( if true then
|
( if true then
|
||||||
@ -79,11 +79,11 @@ let s (s_in: SIn.t) : S.t =
|
|||||||
with
|
with
|
||||||
| Eoption.ENone _1 ->
|
| Eoption.ENone _1 ->
|
||||||
( if true then
|
( if true then
|
||||||
(Eoption.ESome (let a2 : bool = false
|
(Eoption.ESome (let a1 : bool = false
|
||||||
in
|
in
|
||||||
(let a3 : bool = (o_or a2 true)
|
(let a2 : bool = (o_or a1 true)
|
||||||
in
|
in
|
||||||
a3))) else (Eoption.ENone ()))
|
a2))) else (Eoption.ENone ()))
|
||||||
| Eoption.ESome x -> (Eoption.ESome x))|]))
|
| Eoption.ESome x -> (Eoption.ESome x))|]))
|
||||||
with
|
with
|
||||||
| Eoption.ENone _1 ->
|
| Eoption.ENone _1 ->
|
||||||
@ -106,7 +106,7 @@ let s (s_in: SIn.t) : S.t =
|
|||||||
end_line=7; end_column=19;
|
end_line=7; end_column=19;
|
||||||
law_headings=["Article"]}])))
|
law_headings=["Article"]}])))
|
||||||
| Eoption.ESome arg -> arg in
|
| Eoption.ESome arg -> arg in
|
||||||
{S.a = a2}
|
{S.a = a1}
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
Runtime_ocaml.Runtime.register_module "Let_in2"
|
Runtime_ocaml.Runtime.register_module "Let_in2"
|
||||||
|
@ -41,26 +41,26 @@ module ScopeA = struct
|
|||||||
end
|
end
|
||||||
|
|
||||||
module ScopeB = struct
|
module ScopeB = struct
|
||||||
type t = {a1: bool}
|
type t = {a: bool}
|
||||||
end
|
end
|
||||||
|
|
||||||
module ScopeAIn = struct
|
module ScopeA_in = struct
|
||||||
type t = unit
|
type t = unit
|
||||||
end
|
end
|
||||||
|
|
||||||
module ScopeBIn = struct
|
module ScopeB_in = struct
|
||||||
type t = unit
|
type t = unit
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
let scope_a (scope_a_in: ScopeAIn.t) : ScopeA.t =
|
let scope_a (scope_a_in: ScopeA_in.t) : ScopeA.t =
|
||||||
let a2: bool = true in
|
let a: bool = true in
|
||||||
{ScopeA.a = a2}
|
{ScopeA.a = a}
|
||||||
|
|
||||||
let scope_b (scope_b_in: ScopeBIn.t) : ScopeB.t =
|
let scope_b (scope_b_in: ScopeB_in.t) : ScopeB.t =
|
||||||
let scope_a1: ScopeA.t = {ScopeA.a = ((scope_a (())).ScopeA.a)} in
|
let scope_a1: ScopeA.t = {ScopeA.a = ((scope_a (())).ScopeA.a)} in
|
||||||
let a2: bool = scope_a1.ScopeA.a in
|
let a: bool = scope_a1.ScopeA.a in
|
||||||
{ScopeB.a1 = a2}
|
{ScopeB.a = a}
|
||||||
|
|
||||||
|
|
||||||
let entry_scopes = [
|
let entry_scopes = [
|
||||||
|
Loading…
Reference in New Issue
Block a user