Module Melange_compiler_libs.Lambda

type compile_time_constant =
  1. | Big_endian
  2. | Word_size
  3. | Int_size
  4. | Max_wosize
  5. | Ostype_unix
  6. | Ostype_win32
  7. | Ostype_cygwin
  8. | Backend_type
;
type tag_info =
  1. | Blk_constructor of {
    1. name: string,
    2. num_nonconst: int,
    3. attributes: Parsetree.attributes,
    }
  2. | Blk_tuple
  3. | Blk_array
  4. | Blk_poly_var(string)
  5. | Blk_record(array(string))
  6. | Blk_module(list(string))
  7. | Blk_module_export(list(Ident.t))
  8. | Blk_extension_slot
  9. | Blk_extension
  10. | Blk_na(string)
  11. | Blk_some
  12. | Blk_some_not_nested
  13. | Blk_record_inlined of {
    1. name: string,
    2. num_nonconst: int,
    3. fields: array(string),
    }
  14. | Blk_record_ext(array(string))
  15. | Blk_lazy_general
  16. | Blk_class
;
let blk_record: Stdlib.ref((array((Types.label_description, Typedtree.record_label_definition)) => tag_info));
let blk_record_ext: Stdlib.ref((array((Types.label_description, Typedtree.record_label_definition)) => tag_info));
let blk_record_inlined: Stdlib.ref((array((Types.label_description, Typedtree.record_label_definition)) => string => int => tag_info));
let default_tag_info: tag_info;
let ref_tag_info: tag_info;
type field_dbg_info =
  1. | Fld_na(string)
  2. | Fld_record of {
    1. name: string,
    2. mutable_flag: Asttypes.mutable_flag,
    }
  3. | Fld_module of {
    1. name: string,
    }
  4. | Fld_record_inline of {
    1. name: string,
    }
  5. | Fld_record_extension of {
    1. name: string,
    }
  6. | Fld_tuple
  7. | Fld_poly_var_tag
  8. | Fld_poly_var_content
  9. | Fld_extension
  10. | Fld_variant
  11. | Fld_cons
  12. | Fld_array
;
let fld_record: Stdlib.ref((Types.label_description => field_dbg_info));
let fld_record_inline: Stdlib.ref((Types.label_description => field_dbg_info));
let fld_record_extension: Stdlib.ref((Types.label_description => field_dbg_info));
let ref_field_info: field_dbg_info;
let fld_na: field_dbg_info;
type set_field_dbg_info =
  1. | Fld_set_na
  2. | Fld_record_set(string)
  3. | Fld_record_inline_set(string)
  4. | Fld_record_extension_set(string)
;
let ref_field_set_info: set_field_dbg_info;
let fld_record_set: Stdlib.ref((Types.label_description => set_field_dbg_info));
let fld_record_inline_set: Stdlib.ref((Types.label_description => set_field_dbg_info));
let fld_record_extension_set: Stdlib.ref((Types.label_description => set_field_dbg_info));
type immediate_or_pointer =
  1. | Immediate
  2. | Pointer
;
type initialization_or_assignment =
  1. | Assignment
  2. | Heap_initialization
  3. | Root_initialization
;
type is_safe =
  1. | Safe
  2. | Unsafe
;
type pointer_info =
  1. | Pt_constructor of {
    1. name: string,
    2. const: int,
    3. non_const: int,
    4. attributes: Parsetree.attributes,
    }
  2. | Pt_constructor_access of {
    1. cstr_name: string,
    }
  3. | Pt_variant of {
    1. name: string,
    }
  4. | Pt_module_alias
  5. | Pt_builtin_boolean
  6. | Pt_shape_none
  7. | Pt_assertfalse
  8. | Pt_na
;
type primitive =
  1. | Pbytes_to_string
  2. | Pbytes_of_string
  3. | Pignore
  4. | Pgetglobal(Ident.t)
  5. | Psetglobal(Ident.t)
  6. | Pmakeblock(int, tag_info, Asttypes.mutable_flag, block_shape)
  7. | Pfield(int, immediate_or_pointer, Asttypes.mutable_flag, field_dbg_info)
  8. | Pfield_computed
  9. | Psetfield(int, immediate_or_pointer, initialization_or_assignment, set_field_dbg_info)
  10. | Psetfield_computed(immediate_or_pointer, initialization_or_assignment)
  11. | Pfloatfield(int, field_dbg_info)
  12. | Psetfloatfield(int, initialization_or_assignment, set_field_dbg_info)
  13. | Pduprecord(Types.record_representation, int)
  14. | Prunstack
  15. | Pperform
  16. | Presume
  17. | Preperform
  18. | Pccall(Primitive.description)
  19. | Praise(raise_kind)
  20. | Psequand
  21. | Psequor
  22. | Pnot
  23. | Pnegint
  24. | Paddint
  25. | Psubint
  26. | Pmulint
  27. | Pdivint(is_safe)
  28. | Pmodint(is_safe)
  29. | Pandint
  30. | Porint
  31. | Pxorint
  32. | Plslint
  33. | Plsrint
  34. | Pasrint
  35. | Pintcomp(integer_comparison)
  36. | Pcompare_ints
  37. | Pcompare_floats
  38. | Pcompare_bints(boxed_integer)
  39. | Poffsetint(int)
  40. | Poffsetref(int)
  41. | Pintoffloat
  42. | Pfloatofint
  43. | Pnegfloat
  44. | Pabsfloat
  45. | Paddfloat
  46. | Psubfloat
  47. | Pmulfloat
  48. | Pdivfloat
  49. | Pfloatcomp(float_comparison)
  50. | Pstringlength
  51. | Pstringrefu
  52. | Pstringrefs
  53. | Pbyteslength
  54. | Pbytesrefu
  55. | Pbytessetu
  56. | Pbytesrefs
  57. | Pbytessets
  58. | Pmakearray(array_kind, Asttypes.mutable_flag)
  59. | Pduparray(array_kind, Asttypes.mutable_flag)
    /*

    For Pduparray, the argument must be an immutable array. The arguments of Pduparray give the kind and mutability of the array being *produced* by the duplication.

    */
  60. | Parraylength(array_kind)
  61. | Parrayrefu(array_kind)
  62. | Parraysetu(array_kind)
  63. | Parrayrefs(array_kind)
  64. | Parraysets(array_kind)
  65. | Pisint
  66. | Pisout
  67. | Pbintofint(boxed_integer)
  68. | Pintofbint(boxed_integer)
  69. | Pcvtbint(boxed_integer, boxed_integer)
  70. | Pnegbint(boxed_integer)
  71. | Paddbint(boxed_integer)
  72. | Psubbint(boxed_integer)
  73. | Pmulbint(boxed_integer)
  74. | Pdivbint of {
    1. size: boxed_integer,
    2. is_safe: is_safe,
    }
  75. | Pmodbint of {
    1. size: boxed_integer,
    2. is_safe: is_safe,
    }
  76. | Pandbint(boxed_integer)
  77. | Porbint(boxed_integer)
  78. | Pxorbint(boxed_integer)
  79. | Plslbint(boxed_integer)
  80. | Plsrbint(boxed_integer)
  81. | Pasrbint(boxed_integer)
  82. | Pbintcomp(boxed_integer, integer_comparison)
  83. | Pbigarrayref(bool, int, bigarray_kind, bigarray_layout)
  84. | Pbigarrayset(bool, int, bigarray_kind, bigarray_layout)
  85. | Pbigarraydim(int)
  86. | Pstring_load_16(bool)
  87. | Pstring_load_32(bool)
  88. | Pstring_load_64(bool)
  89. | Pbytes_load_16(bool)
  90. | Pbytes_load_32(bool)
  91. | Pbytes_load_64(bool)
  92. | Pbytes_set_16(bool)
  93. | Pbytes_set_32(bool)
  94. | Pbytes_set_64(bool)
  95. | Pbigstring_load_16(bool)
  96. | Pbigstring_load_32(bool)
  97. | Pbigstring_load_64(bool)
  98. | Pbigstring_set_16(bool)
  99. | Pbigstring_set_32(bool)
  100. | Pbigstring_set_64(bool)
  101. | Pctconst(compile_time_constant)
  102. | Pbswap16
  103. | Pbbswap(boxed_integer)
  104. | Pint_as_pointer
  105. | Patomic_load of {
    1. immediate_or_pointer: immediate_or_pointer,
    }
  106. | Patomic_exchange
  107. | Patomic_cas
  108. | Patomic_fetch_add
  109. | Popaque
  110. | Pdls_get
;
and integer_comparison =
  1. | Ceq
  2. | Cne
  3. | Clt
  4. | Cgt
  5. | Cle
  6. | Cge
;
and float_comparison =
  1. | CFeq
  2. | CFneq
  3. | CFlt
  4. | CFnlt
  5. | CFgt
  6. | CFngt
  7. | CFle
  8. | CFnle
  9. | CFge
  10. | CFnge
;
and array_kind =
  1. | Pgenarray
  2. | Paddrarray
  3. | Pintarray
  4. | Pfloatarray
;
and value_kind =
  1. | Pgenval
  2. | Pfloatval
  3. | Pboxedintval(boxed_integer)
  4. | Pintval
;
and block_shape = option(list(value_kind));
and boxed_integer = Primitive.boxed_integer =
  1. | Pnativeint
  2. | Pint32
  3. | Pint64
;
and bigarray_kind =
  1. | Pbigarray_unknown
  2. | Pbigarray_float16
  3. | Pbigarray_float32
  4. | Pbigarray_float64
  5. | Pbigarray_sint8
  6. | Pbigarray_uint8
  7. | Pbigarray_sint16
  8. | Pbigarray_uint16
  9. | Pbigarray_int32
  10. | Pbigarray_int64
  11. | Pbigarray_caml_int
  12. | Pbigarray_native_int
  13. | Pbigarray_complex32
  14. | Pbigarray_complex64
;
and bigarray_layout =
  1. | Pbigarray_unknown_layout
  2. | Pbigarray_c_layout
  3. | Pbigarray_fortran_layout
;
and raise_kind =
  1. | Raise_regular
  2. | Raise_reraise
  3. | Raise_notrace
;
let equal_primitive: primitive => primitive => bool;
let equal_value_kind: value_kind => value_kind => bool;
let equal_boxed_integer: boxed_integer => boxed_integer => bool;
let default_pointer_info: pointer_info;
type structured_constant =
  1. | Const_base(Asttypes.constant, pointer_info)
  2. | Const_block(int, tag_info, list(structured_constant))
  3. | Const_float_array(list(string))
  4. | Const_immstring(string)
;
type tailcall_attribute =
  1. | Tailcall_expectation(bool)
  2. | Default_tailcall
;
type inline_attribute =
  1. | Always_inline
  2. | Never_inline
  3. | Hint_inline
  4. | Unroll(int)
  5. | Default_inline
;
let equal_inline_attribute: inline_attribute => inline_attribute => bool;
type specialise_attribute =
  1. | Always_specialise
  2. | Never_specialise
  3. | Default_specialise
;
let equal_specialise_attribute: specialise_attribute => specialise_attribute => bool;
type local_attribute =
  1. | Always_local
  2. | Never_local
  3. | Default_local
;
type poll_attribute =
  1. | Error_poll
  2. | Default_poll
;
type function_kind =
  1. | Curried
  2. | Tupled
;
type let_kind =
  1. | Strict
  2. | Alias
  3. | StrictOpt
;
type public_info = option(string);
type meth_kind =
  1. | Self
  2. | Public(public_info)
  3. | Cached
;
let equal_meth_kind: meth_kind => meth_kind => bool;
type shared_code = list((int, int));
type function_attribute = {
  1. inline: inline_attribute,
  2. specialise: specialise_attribute,
  3. local: local_attribute,
  4. poll: poll_attribute,
  5. is_a_functor: bool,
  6. stub: bool,
  7. tmc_candidate: bool,
  8. may_fuse_arity: bool,
  9. return_unit: bool,
  10. smuggled_lambda: bool,
};
type scoped_location = Debuginfo.Scoped_location.t;
type switch_names = {
  1. consts: array(string),
  2. blocks: array(string),
};
type lambda =
  1. | Lvar(Ident.t)
  2. | Lmutvar(Ident.t)
  3. | Lconst(structured_constant)
  4. | Lapply(lambda_apply)
  5. | Lfunction(lfunction)
  6. | Llet(let_kind, value_kind, Ident.t, lambda, lambda)
  7. | Lmutlet(value_kind, Ident.t, lambda, lambda)
  8. | Lletrec(list(rec_binding), lambda)
  9. | Lprim(primitive, list(lambda), scoped_location)
  10. | Lswitch(lambda, lambda_switch, scoped_location)
  11. | Lstringswitch(lambda, list((string, lambda)), option(lambda), scoped_location)
  12. | Lstaticraise(int, list(lambda))
  13. | Lstaticcatch(lambda, (int, list((Ident.t, value_kind))), lambda)
  14. | Ltrywith(lambda, Ident.t, lambda)
  15. | Lifthenelse(lambda, lambda, lambda)
  16. | Lsequence(lambda, lambda)
  17. | Lwhile(lambda, lambda)
  18. | Lfor(Ident.t, lambda, lambda, Asttypes.direction_flag, lambda)
  19. | Lassign(Ident.t, lambda)
  20. | Lsend(meth_kind, lambda, lambda, list(lambda), scoped_location)
  21. | Levent(lambda, lambda_event)
  22. | Lifused(Ident.t, lambda)
;
and rec_binding = {
  1. id: Ident.t,
  2. def: lfunction,
};
and lfunction = pri {
  1. kind: function_kind,
  2. params: list((Ident.t, value_kind)),
  3. return: value_kind,
  4. body: lambda,
  5. attr: function_attribute,
  6. loc: scoped_location,
};
and lambda_apply = {
  1. ap_func: lambda,
  2. ap_args: list(lambda),
  3. ap_loc: scoped_location,
  4. ap_tailcall: tailcall_attribute,
  5. ap_inlined: inline_attribute,
  6. ap_specialised: specialise_attribute,
};
and lambda_switch = {
  1. sw_numconsts: int,
  2. sw_consts: list((int, lambda)),
  3. sw_numblocks: int,
  4. sw_blocks: list((int, lambda)),
  5. sw_failaction: option(lambda),
  6. sw_names: option(switch_names),
};
and lambda_event = {
  1. lev_loc: scoped_location,
  2. lev_kind: lambda_event_kind,
  3. lev_repr: option(Stdlib.ref(int)),
  4. lev_env: Env.t,
};
and lambda_event_kind =
  1. | Lev_before
  2. | Lev_after(Types.type_expr)
  3. | Lev_function
  4. | Lev_pseudo
;
type program = {
  1. module_ident: Ident.t,
  2. main_module_block_size: int,
  3. required_globals: Ident.Set.t,
  4. code: lambda,
};
let make_key: lambda => option(lambda);
let const_unit: structured_constant;
let const_int: ?ptr_info:pointer_info => int => structured_constant;
let lambda_unit: lambda;
let lambda_assert_false: lambda;
let lambda_module_alias: lambda;
let dummy_constant: lambda;

dummy_constant produces a plecholder value with a recognizable bit pattern (currently 0xBBBB in its tagged form)

let name_lambda: let_kind => lambda => (Ident.t => lambda) => lambda;
let name_lambda_list: list(lambda) => (list(lambda) => lambda) => lambda;
let lfunction: kind:function_kind => params:list((Ident.t, value_kind)) => return:value_kind => body:lambda => attr:function_attribute => loc:scoped_location => lambda;
let lfunction': kind:function_kind => params:list((Ident.t, value_kind)) => return:value_kind => body:lambda => attr:function_attribute => loc:scoped_location => lfunction;
let iter_head_constructor: (lambda => unit) => lambda => unit;

iter_head_constructor f lam apply f to only the first level of sub expressions of lam. It does not recursively traverse the expression.

let shallow_iter: tail:(lambda => unit) => non_tail:(lambda => unit) => lambda => unit;

Same as iter_head_constructor, but use a different callback for sub-terms which are in tail position or not.

let transl_prim: string => string => lambda;

Translate a value from a persistent module. For instance:

transl_internal_value "CamlinternalLazy" "force"
let free_variables: lambda => Ident.Set.t;
let transl_module_path: scoped_location => Env.t => Path.t => lambda;
let transl_value_path: scoped_location => Env.t => Path.t => lambda;
let transl_extension_path: scoped_location => Env.t => Path.t => lambda;
let transl_class_path: scoped_location => Env.t => Path.t => lambda;
let make_sequence: ('a => lambda) => list('a) => lambda;
let subst: (Ident.t => Types.value_description => Env.t => Env.t) => ?freshen_bound_variables:bool => Ident.Map.t(lambda) => lambda => lambda;

subst update_env ?freshen_bound_variables s lt applies a substitution s to the lambda-term lt.

Assumes that the image of the substitution is out of reach of the bound variables of the lambda-term (no capture).

update_env is used to refresh the environment contained in debug events.

freshen_bound_variables, which defaults to false, freshens the bound variables within lt.

let rename: Ident.Map.t(Ident.t) => lambda => lambda;

A version of subst specialized for the case where we're just renaming idents.

let duplicate_function: lfunction => lfunction;

Duplicate a term, freshening all locally-bound identifiers.

let map: (lambda => lambda) => lambda => lambda;

Bottom-up rewriting, applying the function on each node from the leaves to the root.

let map_lfunction: (lambda => lambda) => lfunction => lfunction;

Apply the given transformation on the function's body

let shallow_map: (lambda => lambda) => lambda => lambda;

Rewrite each immediate sub-term with the function.

let bind: let_kind => Ident.t => lambda => lambda => lambda;
let bind_with_value_kind: let_kind => (Ident.t, value_kind) => lambda => lambda => lambda;
let negate_integer_comparison: integer_comparison => integer_comparison;
let swap_integer_comparison: integer_comparison => integer_comparison;
let negate_float_comparison: float_comparison => float_comparison;
let swap_float_comparison: float_comparison => float_comparison;
let default_function_attribute: function_attribute;
let default_stub_attribute: function_attribute;
let function_is_curried: lfunction => bool;
let find_exact_application: function_kind => arity:int => list(lambda) => option(list(lambda));
let max_arity: unit => int;

Maximal number of parameters for a function, or in other words, maximal length of the params list of a lfunction record. This is unlimited (max_int) for bytecode, but limited (currently to 126) for native code.

let next_raise_count: unit => int;
let staticfail: lambda;
let is_guarded: lambda => bool;
let patch_guarded: lambda => lambda => lambda;
let raise_kind: raise_kind => string;
let merge_inline_attributes: inline_attribute => inline_attribute => option(inline_attribute);
let reset: unit => unit;