Add (mli-to-ml ...) as a hack for mli only modules
This commit is contained in:
parent
c6cc8204bf
commit
f1ebc0ed7d
|
@ -336,7 +336,37 @@ Extra flags can be passed to menhir using the ``flags`` flag:
|
|||
(menhir
|
||||
((flags (<option1> <option2> ...))
|
||||
(modules (<parser1> <parser2> ...))))
|
||||
|
||||
|
||||
ml_of_mli, re_of_rei
|
||||
--------------------
|
||||
|
||||
``(ml_of_mli (<names>))`` produces rules that generate ``.ml`` files
|
||||
from ``.mli`` files, using a hack based on recursive
|
||||
modules. ``re_of_rei`` is the equivalent fot reason files.
|
||||
|
||||
More precisely, given a stanza ``(ml_of_mli (foo))`` the following
|
||||
``.ml`` file is generated:
|
||||
|
||||
.. code:: ocaml
|
||||
|
||||
[@@@warning "-a"]
|
||||
module rec Foo : sig
|
||||
(* contents of foo.mli *)
|
||||
end = Foo
|
||||
|
||||
If you have a ``.mli`` file containing only type declarations, this
|
||||
allows you to automatically produce the corresponding
|
||||
implementation.
|
||||
|
||||
Note that if the ``.mli`` file does contain a value declaration, the
|
||||
compilation of the generated ``.ml`` file will fail with an error
|
||||
about recursive module. In particular declaring an exception or
|
||||
extension constructor implicitely declares a value. The error won't be
|
||||
precide because the compiler doesn't support checking that a mli file
|
||||
doesn't contain value declaration. See ``this ticket
|
||||
<https://github.com/janestreet/jbuilder/issues/9>``__ for a discussion
|
||||
about these issues.
|
||||
|
||||
alias
|
||||
-----
|
||||
|
||||
|
|
|
@ -737,6 +737,22 @@ module Do = struct
|
|||
{ loc = Sexp.Ast.loc sexp
|
||||
; action = Action.Unexpanded.t sexp
|
||||
}
|
||||
|
||||
let ml_of_mli names =
|
||||
List.map names ~f:(fun (loc, name) ->
|
||||
let strf fmt = Printf.ksprintf (String_with_vars.of_string ~loc) fmt in
|
||||
let m = String.capitalize_ascii name in
|
||||
{ loc
|
||||
; action =
|
||||
Redirect
|
||||
(Stdout,
|
||||
strf "%s.ml" name,
|
||||
Progn
|
||||
[ Echo (strf "[@@@warning \"-a\"]\nmodule rec %s : sig\n" m)
|
||||
; Cat (strf "%s.mli" name)
|
||||
; Echo (strf "\nend = %s\ninclude %s\n" m m)
|
||||
])
|
||||
})
|
||||
end
|
||||
|
||||
module Menhir = struct
|
||||
|
@ -921,6 +937,8 @@ module Stanza = struct
|
|||
(fun pat vals sexps ->
|
||||
let sexps = Foreach.expand pat vals sexps in
|
||||
List.concat_map sexps ~f:(v1 pkgs))
|
||||
; cstr "ml_of_mli" (list (located string) @> nil)
|
||||
(fun x -> List.map (Do.ml_of_mli x) ~f:(fun x -> Do x))
|
||||
(* Just for validation and error messages *)
|
||||
; cstr "jbuild_version" (Jbuild_version.t @> nil) (fun _ -> [])
|
||||
]
|
||||
|
|
|
@ -190,6 +190,9 @@ module Of_sexp = struct
|
|||
|
||||
type 'a t = ast -> 'a
|
||||
|
||||
let located f sexp =
|
||||
(Ast.loc sexp, f sexp)
|
||||
|
||||
let of_sexp_error sexp str = raise (Loc.Error (Ast.loc sexp, str))
|
||||
let of_sexp_errorf sexp fmt = ksprintf (of_sexp_error sexp) fmt
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ module Of_sexp : sig
|
|||
val of_sexp_error : Ast.t -> string -> _
|
||||
val of_sexp_errorf : Ast.t -> ('a, unit, string, 'b) format4 -> 'a
|
||||
|
||||
val located : 'a t -> (Loc.t * 'a) t
|
||||
|
||||
(* Record parsing monad *)
|
||||
type 'a record_parser
|
||||
val return : 'a -> 'a record_parser
|
||||
|
|
Loading…
Reference in New Issue