package codept-lib
Module M2lSource
The M2l module (for Module Meta Language) defines the codept AST.
This AST is a restriction of the Ocaml parsetree AST, that can describe all constructions at the module level but have a very simplified view of value (and type) level expressions.
For instance,
module A = struct
module Inner = struct let f x = x end
end
let x = 1
open A
module B = struct let y = Inner.f x endis translated to
module A = struct
module Inner = struct end
end
open A
module B = struct [%access {Inner}] endMain types
'a bind is an auxilliary type used for module/module type binding
An m2l ast/code fragment is a list of module level expression
and expression = | Open of module_expr(*
*)open A.B.C⇒Open [A;B;C]| Include of module_expr(*
*)struct include A end| SigInclude of module_type(*
*)struct include A end| Bind of module_expr bind(*
*)struct module A = struct … end| Bind_sig of module_type bind(*
*)struct module type A = sig … end| Bind_rec of module_expr bind list(*
*)module rec A = … and B = … and …| Minor of minor list(*value level expression. Invariant: for any pure outliner
*)f,f (Minor m :: q ) ≡ f q, i.e, this expression constructor is only meaningful for dependencies tracking.| Extension_node of extension(*
*)[%ext …]
The expression type is the basic building block of the m2l AST
and minor = | Access of access| Pack of module_expr Loc.ext(*(module struct ... end)
*)| Extension_node of extension Loc.ext(*
*)%ext ...| Local_open of Loc.t * module_expr * minor list(*let open struct ... end in ...
*)| Local_bind of Loc.t * module_expr bind * minor list(*let module M = ... in ...
*)
A minor element represents a short description of type or value level constructions, that contains only the information relevant for dependency tracking.
M.N.L.x ⇒ access {M.N.L = Normal } type t = A.t ⇒ access { A = ε }
and module_expr = | Ident of Paths.Simple.t(*
*)A.B…*| Apply of {f : module_expr;x : module_expr;
}(*
*)F(X)| Fun of module_expr fn(*
*)functor (X:S) -> M| Constraint of module_expr * module_type(*
*)M:S| Str of m2l(*
*)struct … end| Val of minor list(*
*)val …| Extension_node of extension(*
*)[%ext …]| Abstract(*empty module expression, used as a placeholder. In particular, it is useful for constraining first class module unpacking as
*)Constraint(Abstract, signature).| Unpacked(*
*)(module M)| Open_me of {opens : Paths.Simple.t Loc.ext list;expr : module_expr;
}(*
*)M.(…N.( module_expr)…)Note: This construction does not exist (yet?) in OCaml proper. It is used here to simplify the interaction between pattern open and first class module.| Proj of {me : module_expr;proj : Paths.Simple.t;
}
Module level expression representation
and module_type = | Alias of Paths.Simple.t(*
*)module m = A…| Ident of Paths.Expr.t(*
*)module M : F(X).sNote: Paths.Expr is used due toF.(X).sexpressions that do not have an equivalent on the module level| Sig of m2l(*
*)sig … end| Fun of module_type fn(*
*)functor (X:S) → M| Of of module_expr(*
*)module type of …| Extension_node of extension(*
*)%%…| Abstract(*module type T
*)| With of {body : module_type;with_constraints : with_constraint list;
}(*
*)S with ...
Module type level representation
and with_rhs = | Type of minor list(*
*)S with type t =/:= ...| Module of Paths.S.t Loc.ext(*
*)S with module N.M := …we need to track abstract module type strenghthening.| Module_type of module_type
Functor auxiliary type
An specific represention for an extension node
Schematic serialization