From 8124d4dab5be1cfc95143d3361a64bdee95ca0c8 Mon Sep 17 00:00:00 2001 From: Louis Gesbert Date: Wed, 25 May 2022 17:18:35 +0200 Subject: [PATCH] Compiler: add some doc on plugin support --- CONTRIBUTING.md | 7 +++++ compiler/index.mld | 13 ++++++++- compiler/plugins/dune | 4 +++ compiler/plugins/plugins.mld | 51 ++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 compiler/plugins/plugins.mld diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b855538e..5a56593d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -158,6 +158,13 @@ To add support for a new language: Feel free to open a pull request for discussion even if you couldn't go through all these steps, the `lexer_xx.cppo.ml` file is the important part. +### Example: writing custom backends as plugins + +Catala has support for dynamically-loaded plugins to use as alternative +backends. See `compiler/plugins` for examples, and [the +documentation](https://catala-lang.org/ocaml_docs/catala/plugins.html) for more +detail. + ### Automatic formatting Please ensure to submit commits formatted using the included `ocamlformat` diff --git a/compiler/index.mld b/compiler/index.mld index c495f304..1666a4a1 100644 --- a/compiler/index.mld +++ b/compiler/index.mld @@ -99,9 +99,20 @@ verification condition for proof backends. More information can be found here: {li {{: verification.html} Verification}} } -Last, two more modules contain additional features for the compiler: +Two more modules contain additional features for the compiler: {ul {li {{: literate.html} Literate programming}} {li {{: utils.html} Compiler utilities}} } + +Last, it is possible to customize the backend to the compiler using a plugin +mechanism. The API is defined inside the following module: + +{!modules: Driver.Plugin} + +See the examples in the [plugins/] subdirectory: + +{ul +{li {{: plugins.html} Backend plugin examples}} +} diff --git a/compiler/plugins/dune b/compiler/plugins/dune index 9c198f09..6934138d 100644 --- a/compiler/plugins/dune +++ b/compiler/plugins/dune @@ -9,3 +9,7 @@ (modes plugin) (modules jsoo) (libraries catala.driver catala.runtime)) + +(documentation + (package catala) + (mld_files plugins)) diff --git a/compiler/plugins/plugins.mld b/compiler/plugins/plugins.mld new file mode 100644 index 00000000..b94817c7 --- /dev/null +++ b/compiler/plugins/plugins.mld @@ -0,0 +1,51 @@ +{0 Example backend plugins } + +This directory contains backend plugins that demonstrate how those can be +written and used with Catala. They probably don't provide much value otherwise. + +Use [make plugins] from the root of the source tree to build them. + +A plugin is created by writing an OCaml module that calls +[Driver.Plugin.register_lcalc] or [Driver.Plugin.register_scalc] and that links +against [catala.driver]. Here is an example dune stanza to compile it: +{v +(executable + (name my-plugin) + (modes plugin) + (modules my_plugin_main_module) + (libraries catala.driver)) +v} + +See the following module for the registration interface: + +{!modules: Driver.Plugin} + +{1 Using plugins} + +Plugins are dynamically loaded. The Catala compiler will be looking for them at +startup within [/lib/catala/plugins] (assuming that the compiler is +installed into [/bin]), or any other directory specified through the +`--plugin-dir` command-line flag or by setting the [CATALA_PLUGINS] environment +variable. + +The plugin of your choice can then be called just like the built-in backends, using: +{v +$ catala MyPlugin [options] +v} + +{1 Examples} + +{2 python example} + +This trivial example registers a plugin that uses the [scalc] format as input. +It simply calls the code of the built-in Python backend, and should be no +different to using the normal Catala Python output mode. + +{2 jsoo example} + +This slightly more involved plugin reads the [lcalc] format, applies the code of +the [OCaml] backend normally, but then calls the [ocamlc] and [js_of_ocaml] +compiler successively on the output in order to give a Javascript output. + +Note that this output remains a library, it won't provide user-facing features, +and no efforts are made to make it callable from normal JavaScript code.