blob: 48675a585f2f5d0fdd7205192741cfc46385f311 [file] [view] [edit]
# Wasm SpecTec
Defines and implements a domain specific language (DSL) for the formal specification of Wasm.
The goal is to have a unified source that is simple to
* _read_, _write_, and code-review (simpler than Latex anyway),
* _check_ for first-level consistency,
* _process_ to generate other formats from.
Because this DSL can transport sufficient domain knowledge, various artefacts could be generated through dedicated backends:
* the _Latex_ for the formal specification for the spec document,
* the _prose_ specification pseudo-algorithms for the spec document,
* the _Coq_ and _Isabelle_ definitions for mechanisation,
* a reference _interpreter_, or parts thereof,
* a _test suite_ exercising individual rules.
Every such backend may need occasional extra guidance, so the language also includes generic syntax for uninterpreted hint annotations that each backend can hook into.
## Structure
The language consists of few generic concepts:
* _Syntax definitions_, describing the grammar of the input language or auxiliary constructs.
These are essentially type definitions for the object language.
For example:
```
syntax valtype = | I32 | I64 | F32 | F64
syntax functype = valtype* -> valtype*
syntax instr = | NOP | BLOCK instr* | LOOP instr* | IF instr* ELSE instr*
syntax context = { FUNC functype*, LABEL (valtype*)* }
syntax config = state; instr*
```
* _Variable declarations_, ascribing the syntactic class (i.e., type) that meta variables used in rules range over.
For example:
```
var t : valtype
var ft : functype
var `C : context
```
(Also, every type name is implicitly usable as a variable of the respective type.)
* _Relation declarations_, defining the shape of judgement forms, such as typing or reduction relations. These are essentially type declarations for the meta language. For example:
```
relation Instr_ok: context |- instr : functype
relation Step: config ~> config
```
* _Rule definitions_, expressing the individual rules defining relations. For example:
```
rule Instr_ok/nop:
`C |- NOP : epsilon -> epsilon
rule Instr_ok/if:
`C |- IF instr_1* ELSE instr_2* : t_1* -> t_2
-- InstrSeq_ok: `C, LABEL t_2* |- instr_1* : t_1* -> t_2*
-- InstrSeq_ok: `C, LABEL t_2* |- instr_2* : t_1* -> t_2*
rule Step/nop:
z; NOP ~> z; epsilon
rule Step/if-true:
z; (I32.CONST c) (IF instr_1* ELSE instr_2*) ~> z; (BLOCK instr_1*)
-- if c =/= 0
rule Step/if-false:
z; (I32.CONST c) (IF instr_1* ELSE instr_2*) ~> z; (BLOCK instr_2*)
-- if c = 0
```
Every rule is named, so that it can be referenced.
Each premise is introduced by a dash and includes the name of the relation it is referencing, easing checking and processing.
* _Auxiliary Functions_, allowing to abstract complex conditions into separate definitions.
For example:
```
def $size(numtype) : nat
def $size(I32) = 32
def $size(I64) = 64
def $size(F32) = 32
def $size(F64) = 64
```
Larger examples can be found in the [`spec`](spec) subdirectory.
## Documentation
Documentation can be found in the [`doc`](doc) subdirectory.
## Building
### Prerequisites
You will need `ocaml` installed with `dune`, `menhir`, `mdx`, and the `zarith` library using `opam`.
* Install `opam` version 2.0.5 or higher.
```
$ apt-get install opam
$ opam init
```
* Set `ocaml` as version 5.0.0 or higher.
```
$ opam switch create 5.0.0
```
* Install `dune` version 3.11.0, `menhir` version 20230608, `mdx` version 2.3.1, and `zarith` version 1.13, via `opam` (default versions)
```
$ opam install dune menhir mdx zarith
```
### Building the Project
* Invoke `make` to build the `spectec` executable.
* In the same place, invoke `make test` to run it on the demo files from the `spec` directory.
### Prerequisites for Latex and Sphinx Backends
To generate a specification document in Latex or Sphinx (to be built into pdf or html), you will also need `pdflatex` and `sphinx-build`.
* Have `python3` version 3.7 or higher with `pip3` installed.
* Install `sphinx` version 8.1.3 or higher and `six` version 1.16.0 via `pip3` (default versions).
```
$ pip3 install sphinx six
```
* Install `texlive-full` via your package manager.
```
$ apt-get install texlive-full
```
### Building the Spec
The core spec document in this repo is build using SpecTec by default. To build:
```
$ cd ../document/core
$ make main
```
### Example
A smaller, self-contained example for a SpecTec specification, a small document with splices, and a suitable Makefile can be found in the [example](doc/example/) directory.
### Running Interpreter Backend
To run a wast file,
```
spectec spec/* --interpreter test-interpreter/sample.wast
```