Skip to content

Commit 6834be5

Browse files
committed
[docs] Migrate to RTD theme and move all files to RST
1 parent 1c1522d commit 6834be5

15 files changed

+402
-300
lines changed

README.rst

Lines changed: 0 additions & 107 deletions
This file was deleted.

README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docs/index.rst

docs/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Minimal makefile for Sphinx documentation
2+
#
3+
4+
# You can set these variables from the command line.
5+
SPHINXOPTS =
6+
SPHINXBUILD = python -msphinx
7+
SPHINXPROJ = NEAL
8+
SOURCEDIR = .
9+
BUILDDIR = _build
10+
11+
# Put it first so that "make" without argument is like "make help".
12+
help:
13+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14+
15+
.PHONY: help Makefile
16+
17+
# Catch-all target: route all unknown targets to Sphinx using the new
18+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19+
%: Makefile
20+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

docs/basics.md renamed to docs/basics.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
# How it works?
1+
How it works?
2+
=============
23

34
The two key principles of NEAL's design are **composability** and **flexibility**.
45

5-
**Composability**: Since it's just impossible for NEAL to have built-in support for every language out there, it has to be highly composable. In order to achieve this level of composition, language support is handled by components in NEAL, and this components are called _AST providers_ (or *providers* for short).
6+
**Composability**: Since it's just impossible for NEAL to have built-in support for every language out there, it has to be highly composable. In order to achieve this level of composition, language support is handled by components in NEAL, and this components are called *AST providers* (or *providers* for short).
67

78
**Flexibility**: On the other hand, at the same time that it'd be great to be effortless to add a new language, this should compromise NEAL's analysis capabilities. In order to achieve this level of flexibility, the complexity of the analysis one can perform using NEAL should only be bound by the *provider* it targets, and not the platform itself.
89

@@ -17,4 +18,5 @@ In order to keep the whole system highly composable, it's broken into four types
1718

1819
Here's a small diagram illustrating how all of the components interact with each other:
1920

20-
![Diagram of the interactions between all of NEAL's components](imgs/neal_diagram.png)
21+
.. image:: imgs/neal_diagram.png
22+
:alt: Diagram of the interactions between all of NEAL's components
File renamed without changes.

docs/components/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ Writing your own components
33

44
.. toctree::
55
:hidden:
6-
:maxdepth: 0
76
:titlesonly:
87

98
Introduction <self>

docs/components/providers.md

Lines changed: 0 additions & 93 deletions
This file was deleted.

docs/components/providers.rst

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
Writing a custom AST Provider
2+
=============================
3+
4+
AST Providers in NEAL are responsible for adding support for a new language. They must conform to a small interface, and have complete ownership over the analysis to be done.
5+
6+
They can either do take care of parsing internally, e.g. using a parser written in OCaml (like the `Swift provider`_) or call out to an external parser (like the `Python provider`_).
7+
8+
Either way, they must conform to the following interface:
9+
10+
.. code-block:: ocaml
11+
12+
module type PROVIDER = sig val name: string
13+
val extensions: string list
14+
val parse: filename -> source -> Absyn.absyn
15+
val exports : (function_name * exported_function) list
16+
end
17+
18+
With the following type aliases:
19+
20+
.. code-block:: ocaml
21+
22+
type exported_function = Ctx.ctx -> Rule.literal list -> Rule.literal
23+
type filename = string
24+
type source = string
25+
type function_name = string
26+
27+
Using a custom provider
28+
-----------------------
29+
30+
* Custom providers must be compiled to a ``.cmxs`` file, which is OCaml's dynamic library format (as described `here <../components#plugins>`_);
31+
* They must have ``.provider`` suffix before the ``.cmxs`` extension, e.g. ``swift.provider.cmxs``;
32+
* You must tell NEAL the path to your provider (using the ``-p``/``--provider`` `configuration flag <../configuration.html#flags>`_).
33+
34+
After that NEAL should already be able to parse files using your new provider and evaluate rules that target it.
35+
36+
## Examples
37+
38+
Here we'll use the two providers currently available with NEAL to illustrate the two use cases:
39+
40+
`Swift provider`_
41+
+++++++++++++++++
42+
43+
Here's the current implementation (we'll discuss it below):
44+
45+
.. code-block:: ocaml
46+
47+
Provider.register(module struct
48+
let name = "Swift"
49+
let extensions = [".swift"]
50+
let parse filename source = Parser.parse filename source
51+
let exports = [
52+
("inheritsFrom", inherits_from)
53+
]
54+
end)
55+
56+
What this provider is saying is:
57+
* Its name is `Swift`, i.e. the provider name you'll use in a `rule <../rules.html>`_ to reference to this provider is `Swift`.
58+
* It can parse files that have the `.swift` extension. (It should always include the `.`)
59+
* Parsing is delegate to `Parser.parse`, which in this case is a Swift parser implemented in OCaml.
60+
* It exports a function called `inheritsFrom`, and its implementation is the OCaml function `inherits_from`. (Which should have the `exported_function` type from above.)
61+
62+
`Python provider`_
63+
+++++++++++++++++++
64+
65+
The actual Python provider module looks very similar to the Swift one:
66+
67+
.. code-block:: ocaml
68+
69+
let () = Provider.register(module struct
70+
let name = "Python"
71+
let extensions = [".py"]
72+
let parse = parse
73+
let exports = []
74+
end)
75+
76+
The main different is the ``parse`` function. Here, instead of actually parsing the file and generating the AST all in OCaml, it calls out to a script which uses the parser built into the python interpreter to generate the AST and dumps it as JSON.
77+
78+
.. code-block:: ocaml
79+
80+
let exec_name = Neal.Utils.relative_path "providers/helpers/dump_python_ast.py"
81+
82+
let parse filename _ =
83+
let cmd = Printf.sprintf "%s %s" exec_name filename in
84+
let stdout = Unix.open_process_in cmd in
85+
let json = Yojson.Safe.from_channel stdout in
86+
let _ = Unix.close_process_in stdout in
87+
absyn_of_json json
88+
89+
The implementation of ``absyn_of_json`` simply takes the JSON parsed using yojson_ and converts it to NEAL's AST type. You can check the `source code <Python provider>`_, but here will ignore it as an implementation detail.
90+
91+
.. _`Swift provider`: https://github.com/uber/NEAL/blob/master/src/providers/swift/swift_provider.ml
92+
.. _`Python provider`: https://github.com/uber/NEAL/blob/master/src/providers/python/python.ml
93+
.. _yojson: https://github.com/mjambon/yojson

0 commit comments

Comments
 (0)