johnwhitington / ocamli

OCaml interpreter
BSD 3-Clause "New" or "Revised" License
99 stars 0 forks source link

OCamli

OCamli is a proof-of-concept step-by-step interpreter for OCaml programs intended for teaching purposes and, eventually, as a debugger. It works by reading an OCaml program into an abstract syntax tree, then interpreting the AST one reduction at a time, optionally displaying each reduction and underlining the reducible expression. For example:

showall

With just -show instead:

show

Running the classic factorial program, using a set of options to elide parts of the output (there are too many options, and the interface will be improved):

factorial

Mutable code

Some of ocamli's output is a little low-level for now, but it's important to emulate what OCaml itself does by making the actual calls to primitives like %setfield0:

mutable

Input/Output

Sometimes the approach of printing everything gets far too much. We will need methods for hiding this internal detail by default:

printint

Standard Library Functions

You should be able to use some or most of the Standard Library functions. Presently Printf and Scanf are not loaded due to bugs.

listmap

Searching

"I want to see the last few steps before factorial (4 - 1)":

search

Examples

The directory examples contains a number of little programs written for development.

The directory OCaml from the Very Beginning contains all the examples and exercises from the beginner's OCaml textbook.

Paper

The eventual use of ocamli as a debugger is sketched in the position paper "Visualizing the Evaluation of Functional Programs for Debugging", given at SLATE'17 in June.

Selected command line options

eval <filename | -e program> [-- arg1 arg2 ...]

Loading and runnning programs:

Multiple files and -e options may be given, and will be treated as zero or more modules followed by one main program.

Searching:

Interaction:

Elision:

Configuration:

Implementation

The ocamli interpreter requires no patches to the OCaml compiler; it is implemented entirely using compiler-libs.

The OCaml program is lexed and parsed by compiler-libs, typechecked, then the parse tree is converted to a simpler, more direct datatype, called Tinyocaml.

The Tinyocaml representation is then interpreted step-by-step, optionally printing each stage out. We use a custom prettyprinter, but hope to eventually contribute back to the standard one.

Keeping ocamli in sync with OCaml will involve updating it to reflect any changes in the compiler-libs API and adding any new features added to the OCaml languages. So, we will have ocamli 4.05 for OCaml 4.05 and so on.

The ocamli facilities for conversing with C code (such as OCaml %external declarations) are based on reading and writing OCaml heap values. The interpreter and the interpreted program and the compiled parts live in the same process with the same OCaml runtime.

Use at runtime

The interpreter can be used at runtime, and the resulting value bought back into the caller:

# let x : int list * int list =
  Tinyocaml.to_ocaml_value
    (Runeval.eval_string "List.split [(1, 2); (3, 4)]");;
val x : int list * int list = ([1; 3], [2; 4])

Support for this is very rudimentary at the moment.

PPX_eval

Writing

let compiler_command = [%compiletimestr "Sys.argv.(0)"])

in a normal compiled OCaml program with PPX_eval generates

let compiler_command = "ocamlopt"

Status

The ocamli interpreter is a proof-of-concept. Do not expect it to run your larger programs!

It supports just enough of the language to load (and run the module initialisation of) most of the OCaml Standard Library. This is quite a large number of constructs, though, including functors, first class modules and so on.

The ocamli interpreter can run almost all the programs in the OCaml from the Very Beginning textbook. The examples are included in the download.

The ocamli interpreter currently makes no guarantee of computational complexity, even when the steps of evaluation are not shown. The extent to which such a guarantee can be given is an open research question.

Future

In short, make it more than a proof-of-concept:

Building

Make sure to download from tag "OCaml17". Should work on all platforms with OCaml 4.05. To build, run the build script. You will need ocamlfind and ppx_tools installed, both of which are available on OPAM.