package metapp

  1. Overview
  2. Docs
Meta-preprocessor for OCaml

Install

Dune Dependency

Authors

Maintainers

Sources

0.1.0.tar.gz
sha512=9d383a8751fbe6514ba1cee4efde0172f86268eb65758936d29e6b86f96df01d9eeaca4ed44bf8d318bf56c62a98650e2e64fbbdc359d6c120d5311dda97377a

Description

Meta-preprocessor for OCaml: extends the language with [%meta ... ] construction where ... stands for OCaml code evaluated at compile-time.

Published: 28 Feb 2020

README

metapp: meta-preprocessor for OCaml

metapp is a PPX rewriter that provides a [%meta ...] extension, where the dots ... are arbitrary OCaml expressions that are substituted at compile-time by the AST nodes they evaluate into. These expressions build AST nodes either by quoting some code directly, or by using compiler-libs (Parsetree, Ast_helper, ...).

In particular, this preprocessor is easy to use for conditional compilation, and is an alternative to cppo and ppx_optcomp.

let option_get o =
  [%meta if Sys.ocaml_version >= "4.08.0" then
     [%e Option.get o]
  else
     [%e match o with
     | None -> invalid_arg "option_get"
     | Some x -> x]]

metapp can be used with dune by using the preprocess field.

(executable
  ...
  (preprocess (pps metapp.ppx))
  ...)

Inside [%meta ...] code, the [%e ...] extension quotes expressions (of type [Parsetree.expression]). There are other quotations available: the full list is given below.

Quotation Type
[%e ...] or [%expr ...] Parsetree.expression
[%p? ...] or [%pat? ...] Parsetree.pattern
[%t: ...] or [%type: ...] Parsetree.core_type
[%sig: ...] Parsetree.signature
[%sigi: ...] Parsetree.signature_item
[%str ...] Parsetree.structure
[%stri ...] Parsetree.structure_item

Quoted expressions can in turn contain further [%meta ...] code. Moreover, [%meta ...] code can itself contain other levels of [%meta ...] code, for multi-stage programming.

In addition to this syntax extension, the Metapp module provided by the metapp package provides convenient functions for AST constructions. In particular, this module provides an OCaml-version-independent interface. Moveover, this module provides a common signature ValueS for constructing and transforming expressions (module Exp), patterns (module Pat) or both at the same time (module Value).

The Metapp module also provides a filter mapper, which handles [@if <bool>] attributes à la ppx_optcomp. The [@if <bool>] attribute can appear mostly everywhere syntax elements are enumerated, including tuples, function applications, arrays, etc.

[%%meta Metapp.include_structure (
  Metapp.filter.structure Metapp.filter [%str
    type t =
    | A of int
    | B of int * int
        [@if [%meta Metapp.Exp.of_bool (Sys.ocaml_version >= "4.04.0")]]
    ...

    match (v: t) with
    | A x -> something x
    | B (y,z)
      [@if [%meta Metapp.Exp.of_bool (Sys.ocaml_version >= "4.04.0")]] ->
        something' y z
    ... ])]

Global definitions for meta-code can be included with [%%metadef ...]. By default, the meta-code is compiled with the compiler-libs package. Other packages can be loaded with [%%metapackage ...]. More generally, flags can be passed to the compiler to compile meta-code with [%%metaflag ...] (there is another convenient notation for adding interface directories: [%%metadir ...]). [%%metaload ...] loads a particular compilation unit. For instance, [%%metapackage metapp] links the meta-code with the metapp package in order to use the Metapp module. All these notations can be applied to multiple arguments at once by using comma as separator.

Dependencies (5)

  1. dune >= "1.11.0"
  2. ocamlfind >= "1.8.1"
  3. ocaml-migrate-parsetree >= "1.5.0" & < "2.0.0"
  4. stdcompat >= "12" & < "19"
  5. ocaml >= "4.03.0" & < "4.11.0"

Dev Dependencies

None

Used by (3)

  1. metaquot < "0.2.0"
  2. pattern = "0.2.0"
  3. traverse < "0.2.0"

Conflicts

None

OCaml

Innovation. Community. Security.