An interpreter and interactive REPL for MicroCaml, a small functional programming language based on a subset of OCaml.
This project implements the core components of a small functional language interpreter:
- Lexical analysis (tokenizing source code)
- Parsing into an Abstract Syntax Tree (AST)
- Environment-based evaluation with closures
- Interpreter integrated with an interactive REPL (Mutop)
The interpreter was developed as part of CMSC330: Organization of Programming Languages at the University of Maryland.
The project was implemented according to the CMSC330 Project 4 specification:
Example interaction with the MicroCaml Mutop REPL demonstrating variable definitions and expression evaluation.
The project includes an interactive REPL (Mutop) built on top of the MicroCaml interpreter.
The execution flow is:
User Input
↓
bin/mutop.ml (interactive REPL / CLI loop)
↓
src/lexer.ml (tokenization)
↓
src/parser.ml (parsing)
↓
src/eval.ml (evaluation with environment)
↓
Result
Core components:
| File | Purpose |
|---|---|
src/lexer.ml |
Converts source text into tokens |
src/parser.ml |
Parses MicroCaml expressions and Mutop commands |
src/eval.ml |
Evaluates expressions and Mutop statements |
src/microCamlTypes.ml |
Defines AST and runtime types |
bin/mutop.ml |
Provided REPL that interfaces with the interpreter |
mutop.ml reads user input until ;;, invokes the lexer/parser/evaluator pipeline, prints results, and preserves the environment across commands such as def x = 5;;.
The evaluator implements environment-based evaluation with closures, supporting higher-order functions and recursion.
The formal operational semantics used to guide the evaluator implementation are included in:
docs/microcaml-opsem.pdf
The project includes Mutop, a provided interactive REPL used to execute MicroCaml programs.
Mutop supports two kinds of inputs.
mutop # 3 + 4;;
- : val: Int 7The def command stores variables in the REPL environment.
mutop # def x = 5;;
val x = Int 5The variable can then be used in future expressions:
mutop # x + 2;;
- : val: Int 7MicroCaml supports a subset of OCaml-style functional programming.
int
bool
+ - * /
Example:
mutop # 1 + 2;;
- : val: Int 3&& || not
= <> < <= > >=
if <expr> then <expr> else <expr>Example:
mutop # if true then 1 else 2;;
- : val: Int 1let x = 6 in x + 4;;Anonymous functions:
fun x -> x + 1Function application:
mutop # (fun x -> x + 1) 5;;
- : val: Int 6Functions capture their surrounding environment.
mutop # let x = 5 in
let f = fun y -> x + y in
f 3;;
- : val: Int 8Recursive functions are supported using let rec.
mutop # let rec fact = fun n ->
if n = 0 then 1
else n * fact (n - 1)
in fact 5;;
- : val: Int 120MicroCaml
│
├── src/ interpreter implementation
├── bin/ REPL entry point (mutop)
├── test/ unit and property tests
├── docs/ language semantics documentation
│
├── dune-project
├── dune-workspace
├── mutop.sh
└── README.md
The project uses the OCaml ecosystem with opam and the Dune build system.
Install dependencies:
opam install dune utop ounit ounit2 qcheckFrom the repository root:
dune buildYou may see deprecation warnings from the testing libraries (for example QCheck.small_int).
These originate from the provided test suite and do not affect interpreter functionality.
Start the interactive REPL:
dune exec bin/mutop.bcAlternatively, run the helper script:
./mutop.shRun the test suite with:
dune runtestThe tests include both unit tests and property-based tests.
This project builds on starter infrastructure provided in CMSC330, while the interpreter logic (lexing, parsing, and evaluation) was implemented as part of the assignment.
