2021-02-12 19:20:14 +03:00
|
|
|
(* This file is part of the Catala compiler, a specification language for tax
|
|
|
|
and social benefits computation rules. Copyright (C) 2020 Inria, contributor:
|
|
|
|
Nicolas Chataing <nicolas.chataing@ens.fr> Denis Merigoux
|
|
|
|
<denis.merigoux@inria.fr>
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
|
|
use this file except in compliance with the License. You may obtain a copy of
|
|
|
|
the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
License for the specific language governing permissions and limitations under
|
|
|
|
the License. *)
|
|
|
|
|
|
|
|
(** Builds a context that allows for mapping each name to a precise uid, taking
|
|
|
|
lexical scopes into account *)
|
|
|
|
|
2022-11-21 12:46:17 +03:00
|
|
|
open Catala_utils
|
2022-08-12 23:42:39 +03:00
|
|
|
open Shared_ast
|
2021-02-12 19:20:14 +03:00
|
|
|
|
|
|
|
(** {1 Name resolution context} *)
|
|
|
|
|
2023-05-17 16:44:57 +03:00
|
|
|
type unique_rulename = Ambiguous of Pos.t list | Unique of RuleName.t Mark.pos
|
2021-02-12 19:20:14 +03:00
|
|
|
|
2022-01-03 20:39:59 +03:00
|
|
|
type scope_def_context = {
|
|
|
|
default_exception_rulename : unique_rulename option;
|
2023-04-18 15:39:38 +03:00
|
|
|
label_idmap : LabelName.t Ident.Map.t;
|
2022-01-03 20:39:59 +03:00
|
|
|
}
|
|
|
|
|
2021-02-11 20:48:59 +03:00
|
|
|
type scope_context = {
|
2023-04-18 15:39:38 +03:00
|
|
|
var_idmap : scope_var_or_subscope Ident.Map.t;
|
2022-10-21 16:47:17 +03:00
|
|
|
(** All variables, including scope variables and subscopes *)
|
2023-04-18 11:31:44 +03:00
|
|
|
scope_defs_contexts : scope_def_context Ast.ScopeDef.Map.t;
|
2021-02-12 19:20:14 +03:00
|
|
|
(** What is the default rule to refer to for unnamed exceptions, if any *)
|
2024-03-28 19:05:12 +03:00
|
|
|
scope_in_struct : StructName.t;
|
|
|
|
scope_out_struct : StructName.t;
|
2022-11-21 12:12:45 +03:00
|
|
|
sub_scopes : ScopeName.Set.t;
|
2022-10-21 16:47:17 +03:00
|
|
|
(** Other scopes referred to by this scope. Used for dependency analysis *)
|
2024-05-24 15:26:44 +03:00
|
|
|
scope_visibility : visibility;
|
2021-02-11 20:48:59 +03:00
|
|
|
}
|
2021-02-12 19:20:14 +03:00
|
|
|
(** Inside a scope, we distinguish between the variables and the subscopes. *)
|
|
|
|
|
2022-11-21 12:12:45 +03:00
|
|
|
type struct_context = typ StructField.Map.t
|
2021-02-12 19:20:14 +03:00
|
|
|
(** Types of the fields of a struct *)
|
|
|
|
|
2022-11-21 12:12:45 +03:00
|
|
|
type enum_context = typ EnumConstructor.Map.t
|
2021-02-12 19:20:14 +03:00
|
|
|
(** Types of the payloads of the cases of an enum *)
|
|
|
|
|
2022-02-05 02:04:19 +03:00
|
|
|
type var_sig = {
|
2022-08-25 18:29:00 +03:00
|
|
|
var_sig_typ : typ;
|
2022-02-05 02:04:19 +03:00
|
|
|
var_sig_is_condition : bool;
|
2023-02-28 16:40:05 +03:00
|
|
|
var_sig_parameters :
|
2023-05-17 16:44:57 +03:00
|
|
|
(Uid.MarkedString.info * Shared_ast.typ) list Mark.pos option;
|
2022-11-07 15:50:28 +03:00
|
|
|
var_sig_io : Surface.Ast.scope_decl_context_io;
|
2023-04-18 15:39:38 +03:00
|
|
|
var_sig_states_idmap : StateName.t Ident.Map.t;
|
2022-08-25 13:09:51 +03:00
|
|
|
var_sig_states_list : StateName.t list;
|
2022-02-05 02:04:19 +03:00
|
|
|
}
|
|
|
|
|
2022-10-21 16:47:17 +03:00
|
|
|
(** Capitalised type names share a namespace on the user side, but may
|
|
|
|
correspond to only one of the following *)
|
|
|
|
type typedef =
|
|
|
|
| TStruct of StructName.t
|
|
|
|
| TEnum of EnumName.t
|
|
|
|
| TScope of ScopeName.t * scope_info (** Implicitly defined output struct *)
|
|
|
|
|
2023-11-20 18:01:06 +03:00
|
|
|
type module_context = {
|
|
|
|
path : Uid.Path.t;
|
2023-12-01 01:53:38 +03:00
|
|
|
(** The current path being processed. Used for generating the Uids. *)
|
2023-04-18 15:39:38 +03:00
|
|
|
typedefs : typedef Ident.Map.t;
|
2023-12-01 01:53:38 +03:00
|
|
|
(** Gathers the names of the scopes, structs and enums *)
|
2023-04-18 15:39:38 +03:00
|
|
|
field_idmap : StructField.t StructName.Map.t Ident.Map.t;
|
2023-12-01 01:53:38 +03:00
|
|
|
(** The names of the struct fields. Names of fields can be shared between
|
|
|
|
different structs. Note that fields from submodules are included here
|
|
|
|
for the root module, because disambiguating there is helpful. *)
|
2023-04-18 15:39:38 +03:00
|
|
|
constructor_idmap : EnumConstructor.t EnumName.Map.t Ident.Map.t;
|
2023-12-01 01:53:38 +03:00
|
|
|
(** The names of the enum constructors. Constructor names can be shared
|
|
|
|
between different enums. Note that constructors from its submodules
|
|
|
|
are included here for the root module, because disambiguating there is
|
|
|
|
helpful. *)
|
2023-04-18 15:39:38 +03:00
|
|
|
topdefs : TopdefName.t Ident.Map.t; (** Global definitions *)
|
2023-12-01 01:53:38 +03:00
|
|
|
used_modules : ModuleName.t Ident.Map.t;
|
|
|
|
(** Module aliases and the modules they point to *)
|
2023-11-20 18:01:06 +03:00
|
|
|
}
|
|
|
|
(** Context for name resolution, valid within a given module *)
|
|
|
|
|
|
|
|
type context = {
|
|
|
|
scopes : scope_context ScopeName.Map.t; (** For each scope, its context *)
|
2024-05-24 15:26:44 +03:00
|
|
|
topdefs : (typ * visibility) TopdefName.Map.t;
|
2023-08-25 15:12:02 +03:00
|
|
|
(** Types associated with the global definitions *)
|
2024-05-24 15:26:44 +03:00
|
|
|
structs : (struct_context * visibility) StructName.Map.t;
|
2022-11-21 12:12:45 +03:00
|
|
|
(** For each struct, its context *)
|
2024-05-24 15:26:44 +03:00
|
|
|
enums : (enum_context * visibility) EnumName.Map.t;
|
|
|
|
(** For each enum, its context *)
|
2022-11-21 12:12:45 +03:00
|
|
|
var_typs : var_sig ScopeVar.Map.t;
|
2022-02-05 02:04:19 +03:00
|
|
|
(** The signatures of each scope variable declared *)
|
2023-11-20 18:01:06 +03:00
|
|
|
modules : module_context ModuleName.Map.t;
|
2023-12-01 01:53:38 +03:00
|
|
|
(** The map to the interfaces of all modules (transitively) used by the
|
|
|
|
program. References are made through [local.used_modules] *)
|
2023-11-20 18:01:06 +03:00
|
|
|
local : module_context;
|
2023-12-01 01:53:38 +03:00
|
|
|
(** Local context of the root module corresponding to the program being
|
|
|
|
analysed *)
|
2021-02-11 20:48:59 +03:00
|
|
|
}
|
2023-11-20 18:01:06 +03:00
|
|
|
(** Global context used throughout {!module: Surface.Desugaring} *)
|
2021-02-12 19:20:14 +03:00
|
|
|
|
|
|
|
(** {1 Helpers} *)
|
|
|
|
|
|
|
|
val raise_unsupported_feature : string -> Pos.t -> 'a
|
|
|
|
(** Temporary function raising an error message saying that a feature is not
|
|
|
|
supported yet *)
|
|
|
|
|
2023-04-18 15:39:38 +03:00
|
|
|
val raise_unknown_identifier : string -> Ident.t Mark.pos -> 'a
|
2021-02-12 19:20:14 +03:00
|
|
|
(** Function to call whenever an identifier used somewhere has not been declared
|
|
|
|
in the program previously *)
|
|
|
|
|
2023-11-20 18:01:06 +03:00
|
|
|
val get_modname : context -> Ident.t Mark.pos -> ModuleName.t
|
|
|
|
(** Emits a user error if the module name is not found *)
|
|
|
|
|
|
|
|
val get_module_ctx : context -> Ident.t Mark.pos -> context
|
|
|
|
(** Emits a user error if the module name is not found *)
|
|
|
|
|
2022-08-25 18:29:00 +03:00
|
|
|
val get_var_typ : context -> ScopeVar.t -> typ
|
2021-02-12 19:20:14 +03:00
|
|
|
(** Gets the type associated to an uid *)
|
|
|
|
|
2022-08-25 13:09:51 +03:00
|
|
|
val is_var_cond : context -> ScopeVar.t -> bool
|
2022-11-07 15:50:28 +03:00
|
|
|
val get_var_io : context -> ScopeVar.t -> Surface.Ast.scope_decl_context_io
|
2021-02-12 19:20:14 +03:00
|
|
|
|
2023-08-30 18:49:29 +03:00
|
|
|
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 *)
|
|
|
|
|
2023-04-18 15:39:38 +03:00
|
|
|
val get_var_uid : ScopeName.t -> context -> Ident.t Mark.pos -> ScopeVar.t
|
2021-02-12 19:20:14 +03:00
|
|
|
(** Get the variable uid inside the scope given in argument *)
|
|
|
|
|
2024-04-04 11:56:56 +03:00
|
|
|
val get_subscope_uid : ScopeName.t -> context -> Ident.t Mark.pos -> ScopeVar.t
|
2021-02-12 19:20:14 +03:00
|
|
|
(** Get the subscope uid inside the scope given in argument *)
|
|
|
|
|
2023-04-18 15:39:38 +03:00
|
|
|
val is_subscope_uid : ScopeName.t -> context -> Ident.t -> bool
|
2021-02-12 19:20:14 +03:00
|
|
|
(** [is_subscope_uid scope_uid ctxt y] returns true if [y] belongs to the
|
|
|
|
subscopes of [scope_uid]. *)
|
|
|
|
|
2022-08-25 13:09:51 +03:00
|
|
|
val belongs_to : context -> ScopeVar.t -> ScopeName.t -> bool
|
2021-02-12 19:20:14 +03:00
|
|
|
(** Checks if the var_uid belongs to the scope scope_uid *)
|
|
|
|
|
2023-02-28 16:40:05 +03:00
|
|
|
val get_params :
|
|
|
|
context ->
|
|
|
|
Ast.ScopeDef.t ->
|
2023-05-17 16:44:57 +03:00
|
|
|
(Uid.MarkedString.info * typ) list Mark.pos option
|
2023-02-28 16:40:05 +03:00
|
|
|
|
2022-11-07 15:50:28 +03:00
|
|
|
val is_def_cond : context -> Ast.ScopeDef.t -> bool
|
|
|
|
val is_type_cond : Surface.Ast.typ -> bool
|
2021-02-12 19:20:14 +03:00
|
|
|
|
2021-02-11 20:48:59 +03:00
|
|
|
val get_def_key :
|
2023-01-04 18:12:36 +03:00
|
|
|
Surface.Ast.scope_var ->
|
2023-05-17 16:44:57 +03:00
|
|
|
Surface.Ast.lident Mark.pos option ->
|
2022-08-12 23:42:39 +03:00
|
|
|
ScopeName.t ->
|
2022-02-28 19:19:06 +03:00
|
|
|
context ->
|
|
|
|
Pos.t ->
|
2022-11-07 15:50:28 +03:00
|
|
|
Ast.ScopeDef.t
|
2022-02-28 19:19:06 +03:00
|
|
|
(** Usage: [get_def_key var_name var_state scope_uid ctxt pos]*)
|
2021-02-12 19:20:14 +03:00
|
|
|
|
2023-04-18 15:39:38 +03:00
|
|
|
val get_enum : context -> Ident.t Mark.pos -> EnumName.t
|
2022-10-21 16:47:17 +03:00
|
|
|
(** Find an enum definition from the typedefs, failing if there is none or it
|
|
|
|
has a different kind *)
|
|
|
|
|
2023-04-18 15:39:38 +03:00
|
|
|
val get_struct : context -> Ident.t Mark.pos -> StructName.t
|
2022-10-21 16:47:17 +03:00
|
|
|
(** Find a struct definition from the typedefs (possibly an implicit output
|
|
|
|
struct from a scope), failing if there is none or it has a different kind *)
|
|
|
|
|
2023-04-18 15:39:38 +03:00
|
|
|
val get_scope : context -> Ident.t Mark.pos -> ScopeName.t
|
2022-10-21 16:47:17 +03:00
|
|
|
(** Find a scope definition from the typedefs, failing if there is none or it
|
|
|
|
has a different kind *)
|
|
|
|
|
2023-08-30 18:49:29 +03:00
|
|
|
val module_ctx : context -> Surface.Ast.path -> context
|
2023-08-10 17:52:39 +03:00
|
|
|
(** Returns the context corresponding to the given module path; raises a user
|
|
|
|
error if the module is not found *)
|
|
|
|
|
2023-02-24 12:02:12 +03:00
|
|
|
val process_type : context -> Surface.Ast.typ -> typ
|
2023-01-23 14:19:36 +03:00
|
|
|
(** Convert a surface base type to an AST type *)
|
|
|
|
|
2021-02-12 19:20:14 +03:00
|
|
|
(** {1 API} *)
|
|
|
|
|
2023-11-20 18:01:06 +03:00
|
|
|
val form_context :
|
2023-12-01 01:53:38 +03:00
|
|
|
Surface.Ast.program * ModuleName.t Ident.Map.t ->
|
|
|
|
(Surface.Ast.interface * ModuleName.t Ident.Map.t) ModuleName.Map.t ->
|
|
|
|
context
|
2021-02-12 19:20:14 +03:00
|
|
|
(** Derive the context from metadata, in one pass over the declarations *)
|