This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
3
unikernel/duniverse/ppxlib/test/gencopy/dune
Normal file
3
unikernel/duniverse/ppxlib/test/gencopy/dune
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
(cram
|
||||
(package ppxlib)
|
||||
(deps ../../dev/gencopy/gencopy.exe))
|
||||
123
unikernel/duniverse/ppxlib/test/gencopy/run.t
Normal file
123
unikernel/duniverse/ppxlib/test/gencopy/run.t
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
gencopy is a dev utility tool that we use to generate migration functions
|
||||
skeletons when adding support for new compiler versions.
|
||||
|
||||
We can run it on two empty .ml files:
|
||||
|
||||
$ touch in.ml
|
||||
$ touch out.ml
|
||||
|
||||
$ ../../dev/gencopy/gencopy.exe in.ml out.ml
|
||||
open Stdlib0
|
||||
let copy_location x = x
|
||||
|
||||
It then simply generates the headers which are a global open to stdlib0 and a
|
||||
default copy function for location that one could overwrite if needed.
|
||||
|
||||
================= Simple types =================
|
||||
|
||||
We can test it on a pair of simple types, note that all types are expected to be
|
||||
defined in submodules and not at the root as the ast_X.ml files are laid out that
|
||||
way:
|
||||
|
||||
$ cat > in.ml << EOF
|
||||
> module X = struct
|
||||
> type r = {a: int; b: string}
|
||||
> end
|
||||
>
|
||||
> module Y = struct
|
||||
> type s = A of int | B of string
|
||||
> end
|
||||
> EOF
|
||||
|
||||
$ ../../dev/gencopy/gencopy.exe in.ml out.ml
|
||||
open Stdlib0
|
||||
let copy_location x = x
|
||||
let rec copy_r : In.X.r -> Out.X.r =
|
||||
fun { In.X.a = a; In.X.b = b } -> { Out.X.a = a; Out.X.b = b }
|
||||
and copy_s : In.Y.s -> Out.Y.s =
|
||||
function | In.Y.A x0 -> Out.Y.A x0 | In.Y.B x0 -> Out.Y.B x0
|
||||
|
||||
Note that it just copies the base types (string, int, etc...) directly and does
|
||||
not expect a copy_string function.
|
||||
|
||||
================= Recursive types ===============
|
||||
|
||||
Recursive types should be handled properly:
|
||||
|
||||
$ cat > in.ml << EOF
|
||||
> module X = struct
|
||||
> type a = b list
|
||||
> and b = A of a | B
|
||||
> end
|
||||
> EOF
|
||||
|
||||
$ ../../dev/gencopy/gencopy.exe in.ml out.ml
|
||||
open Stdlib0
|
||||
let copy_location x = x
|
||||
let rec copy_a : In.X.a -> Out.X.a = fun x -> List.map copy_b x
|
||||
and copy_b : In.X.b -> Out.X.b =
|
||||
function | In.X.A x0 -> Out.X.A (copy_a x0) | In.X.B -> Out.X.B
|
||||
|
||||
Any type it encounters a non base type, it assumes that a copy_ function
|
||||
for this type will be defined. If the type is defined in the input file, it
|
||||
should generate it itself, otherwise it will have to be added manually.
|
||||
|
||||
================= Parametrized types ===============
|
||||
|
||||
A copy_function for a parametrized type should be polymorphic and take
|
||||
one extra argument per type parameter. It should also properly pass that
|
||||
argument when copying instances of a parametrized type.
|
||||
|
||||
$ cat > in.ml << EOF
|
||||
> module X = struct
|
||||
> type 'a loc = { loc: location; txt: 'a }
|
||||
> and u = A | B
|
||||
> and v = { u : u loc; flags : int }
|
||||
> end
|
||||
> EOF
|
||||
|
||||
$ ../../dev/gencopy/gencopy.exe in.ml out.ml
|
||||
open Stdlib0
|
||||
let copy_location x = x
|
||||
let rec copy_loc : 'f0 'g0 . ('f0 -> 'g0) -> 'f0 In.X.loc -> 'g0 Out.X.loc =
|
||||
fun f0 { In.X.loc = loc; In.X.txt = txt } ->
|
||||
{ Out.X.loc = (copy_location loc); Out.X.txt = (f0 txt) }
|
||||
and copy_u : In.X.u -> Out.X.u =
|
||||
function | In.X.A -> Out.X.A | In.X.B -> Out.X.B
|
||||
and copy_v : In.X.v -> Out.X.v =
|
||||
fun { In.X.u = u; In.X.flags = flags } ->
|
||||
{ Out.X.u = (copy_loc copy_u u); Out.X.flags = flags }
|
||||
|
||||
=================== Inline records =================
|
||||
|
||||
Inline record fields should not be qualified (e.g. Modname.fiel_name) as this
|
||||
would trigger a compile error. gencopy should properly handle this:
|
||||
|
||||
$ cat > in.ml << EOF
|
||||
> module X = struct
|
||||
> type x =
|
||||
> | A of {i: int; s: string}
|
||||
> end
|
||||
> EOF
|
||||
|
||||
$ ../../dev/gencopy/gencopy.exe in.ml out.ml
|
||||
open Stdlib0
|
||||
let copy_location x = x
|
||||
let rec copy_x : In.X.x -> Out.X.x =
|
||||
function | In.X.A { i; s } -> Out.X.A { i; s }
|
||||
|
||||
====================== X.t as x ====================
|
||||
|
||||
For convenience, gencopy the copy function for X.t as copy_x:
|
||||
|
||||
$ cat > in.ml << EOF
|
||||
> module X = struct
|
||||
> type t = int
|
||||
> end
|
||||
> EOF
|
||||
|
||||
$ ../../dev/gencopy/gencopy.exe in.ml out.ml
|
||||
open Stdlib0
|
||||
let copy_location x = x
|
||||
let rec copy_x : In.X.t -> Out.X.t = fun x -> x
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue