Sarek_ppx_lib.Sarek_envmodule StringMap : sig ... endtype var_info = {vi_type : Sarek_types.typ;vi_mutable : bool;vi_is_param : bool;Kernel parameter?
*)vi_index : int;For parameter ordering
*)vi_is_vec : bool;Is this a vector parameter?
*)}Information about a variable
Reference to an intrinsic function or constant.
"Sarek_stdlib"; "Float32", "sin") -> Sarek_stdlib.Float32.sin"Sarek_stdlib"; "Int32", "add_int32") -> Sarek_stdlib.Int32.add_int32This enables extensibility: user libraries can define their own intrinsics via %sarek_intrinsic and the PPX will reference them correctly.
val intrinsic_ref_name : intrinsic_ref -> stringGet the qualified name of an intrinsic ref for debugging/printing
val intrinsic_ref_display_name : intrinsic_ref -> stringGet user-friendly display name for error messages (no core prefix)
type intrinsic_fun_info = {intr_type : Sarek_types.typ;intr_ref : intrinsic_ref;Reference to stdlib module function
*)intr_convergence : Sarek_core_primitives.convergence option;Convergence requirement. None means NoEffect. User libraries can specify ConvergencePoint or WarpConvergence.
*)}Information about an intrinsic function. Device code is resolved at JIT time via Sarek_registry.
type intrinsic_const_info = {const_type : Sarek_types.typ;const_ref : intrinsic_ref;Reference to intrinsic constant
*)}Information about an intrinsic constant. Device code is resolved at JIT time via Sarek_registry.
type type_info = | TIRecord of {ti_name : string;ti_fields : (string * Sarek_types.typ * bool) list;name, type, mutable
*)}| TIVariant of {ti_name : string;ti_constrs : (string * Sarek_types.typ option) list;constructor name, optional arg type
*)}Information about a custom type
type t = {vars : var_info StringMap.t;types : type_info StringMap.t;intrinsic_funs : intrinsic_fun_info StringMap.t;intrinsic_consts : intrinsic_const_info StringMap.t;constructors : (string * Sarek_types.typ option) StringMap.t;constr -> (type_name, arg_type)
*)fields : (string * int * Sarek_types.typ * bool) StringMap.t;field -> (type_name, index, type, mutable)
*)current_level : int;For let-polymorphism
*)local_funs : (string * Sarek_scheme.scheme) StringMap.t;Local function definitions with polymorphic schemes
*)}The typing environment - immutable
val empty : tEmpty environment
Environment operations - all return new environments
val add_var : StringMap.key -> var_info -> t -> tval add_type : StringMap.key -> type_info -> t -> tval add_intrinsic_fun : StringMap.key -> intrinsic_fun_info -> t -> tval add_intrinsic_const : StringMap.key -> intrinsic_const_info -> t -> tval add_local_fun : StringMap.key -> Sarek_scheme.scheme -> t -> tval find_var : StringMap.key -> t -> var_info optionval find_type : StringMap.key -> t -> type_info optionval find_intrinsic_fun : StringMap.key -> t -> intrinsic_fun_info optionval find_intrinsic_const : StringMap.key -> t -> intrinsic_const_info optionval find_constructor :
StringMap.key ->
t ->
(string * Sarek_types.typ option) optionval find_field :
StringMap.key ->
t ->
(string * int * Sarek_types.typ * bool) optionval find_local_fun :
StringMap.key ->
t ->
(string * Sarek_scheme.scheme) optionGet the short module name from a module path. E.g., "Sarek_stdlib"; "Float32" -> "Float32"
Open a module: bring its bindings into scope under short names. E.g., open_module "Float32" brings Float32.sin -> sin
Also handles legacy aliases:
Create standard library environment from core primitives and the PPX registry.
Step 1: Add all core primitives from Sarek_core_primitives. These have compile-time semantic properties (variance, convergence, purity) that the PPX uses for analysis. Core primitives use CorePrimitiveRef.
Step 2: Add library intrinsics from Sarek_ppx_registry. These may shadow core primitives if they have the same name (which provides device implementations). Library intrinsics use IntrinsicRef.
Intrinsics are registered under module-qualified names (e.g., "Float32.sin") to avoid ambiguity between Float32.sqrt and Float64.sqrt. Use `open_module` to bring a module's bindings into scope under short names.
IMPORTANT: The caller must ensure stdlib modules are initialized before calling this function (e.g., via Sarek_stdlib.force_init()). This is done in Sarek_ppx.ml to avoid circular dependencies.
type lookup_result = | LVar of var_info| LIntrinsicConst of intrinsic_const_info| LIntrinsicFun of intrinsic_fun_info| LConstructor of string * Sarek_types.typ optiontype_name, arg_type
*)| LLocalFun of string * Sarek_scheme.schemename and type scheme (for polymorphism)
*)| LNotFoundLookup that checks all namespaces for an identifier
val lookup : StringMap.key -> t -> lookup_resultval pp_env : Stdlib.Format.formatter -> t -> unitDebug: print environment contents