https://github.com/maxm33/minicaml-interpreter
An interpreter written in Java that understands a subset of OCaml instructions.
https://github.com/maxm33/minicaml-interpreter
interpreter ocaml
Last synced: 4 months ago
JSON representation
An interpreter written in Java that understands a subset of OCaml instructions.
- Host: GitHub
- URL: https://github.com/maxm33/minicaml-interpreter
- Owner: maxm33
- License: mit
- Created: 2024-03-11T16:35:48.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-14T17:02:01.000Z (5 months ago)
- Last Synced: 2025-02-14T17:39:55.538Z (5 months ago)
- Topics: interpreter, ocaml
- Language: Java
- Homepage:
- Size: 13.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# MiniCaml Interpreter
This is an interpreter that understands a simplified version of OCaml (**MiniCaml**).
Since it is implemented in Java, every construct, type or structure (**every expression**, better said) in MiniCaml is modeled as an object.
OCaml offers constructs for OOP and imperative programming, which is not _(yet)_ the case in MiniCaml.
However, MiniCaml offers constructs for control-flow, declaration of variables, functions and recursive functions.
## Grammar
Every program must start with an expression `e ;;` from which can derive as follows:
- **e** := **val** | **ide** | **ListOp** | (**e**) | (**e** **bop** **e**) | **uop** **e** | **e** ;; **e** | (**ide** **e1 ... e16**) | if **e** then **e** else **e** | let _rec_ **ide** _**ide1 ... ide16**_ = **e** _in **e**_ | function **ide1 ... ide16** -> **e**
- **ListOp** := List.hd **e** | List.tl **e** | List.rev **e** | List.isEmpty **e** | List.length **e** | List.cons **e** **e** | List.append **e** **e** | List.map **e** **e** | List.filter **e** **e** | List.exists **e** **e** | List.forAll **e** **e** | List.fold **e** **e** **e**
- **val** := Int | Bool | Closure | RecursiveClosure | [**e0 ... en-1**]
- **uop** := !
- **bop** := **+** | **-** | \* | **/** | **&** | **|** | **>** | < | **>=** | <= | **%** | **^** | **==** | **!=**
- **ide** := Identifiers
> [!TIP]
> You can refer to OCaml documentation for any doubt, since it should be almost equivalent to this lexic, syntax and semantics.
As in OCaml, functions in MiniCaml are treated as values, so they can be passed as arguments to or returned from other functions, or stored in variables/lists.
> [!NOTE]
>
> - '( )' can surround any expression (just one), but they are also necessary to define operations and functional applications, so use them wisely.
> - 'in', 'rec' and 'ide1 ... ide16' are optional in 'let' declaration, thus they are formatted in _italic_. This was done to reduce several rules to just one, lightening the grammar representation.
## Usage
- Compile
```
javac Main.java
```- Run
```
java Main
```
> [!TIP]
> Some test programs are available in `test` folder.
## Example
The compilation of the available test, through the command `java Main test/test.ml`, returns the following:
```
((1 + 3) * (2 - (16 / 8))) ;;-: Int = 0
((2 > 1) & !(( !true != (4 < 6)) == (false | true))) ;;
-: Bool = false
[[(99)]] ;;
-: Lis = [[99]]
[ ] ;;
-: Lis = []
!(List.isEmpty [88]) ;;
-: Bool = true
let x = 5 ;;
-: Int = 5
[x,1,2] ;;
-: Lis = [5,1,2]
let var = (1 - 2) in (var * 6) ;;
-: Int = -6
let mul = function f y -> (f * y) in (mul 10 2) ;;
-: Int = 20
let y = 2 in
let x = (y + 13) in
let y = (x * y) in
y ;;-: Int = 30
let rec fact n =
if (n < 2) then 1
else (n * (fact (n - 1))) ;;-: RecursiveClosure =
(fact 4) ;;
-: Int = 24
let f y = (x + y) ;;
-: Closure =
(f 6) ;;
-: Int = 11
let list0 = [] ;;
-: Lis = []
let list1 = [11,5,21,5,1,2] ;;
-: Lis = [11,5,21,5,1,2]
let list2 = [ 3 2 ] ;;
-: Lis = [3,2]
let pred_even = function x -> ((x % 2) == 0) ;;
-: Closure =
let doubler x = (x * 2) ;;
-: Closure =
let rec search elem lis count =
if (List.isEmpty lis) then -1
else let head = (List.hd lis) in
if (head == elem) then count
else (search elem List.tl lis (count + 1)) ;;-: RecursiveClosure =
let sum_list = function lst ->
let f = function x acc -> (acc + x) in
List.fold f 0 lst ;;-: Closure =
(sum_list list1) ;;
-: Int = 45
let sub_list lst =
let f x acc = (acc - x) in
List.fold f 0 lst in
(sub_list list1) ;;-: Int = -45
List.hd list0 ;;
-: null
List.tl list0 ;;
-: null
List.rev list0 ;;
-: Lis = []
List.length list0 ;;
-: Int = 0
List.isEmpty list0 ;;
-: Bool = true
List.hd list1 ;;
-: Int = 11
List.tl list1 ;;
-: Lis = [5,21,5,1,2]
List.rev list1 ;;
-: Lis = [2,1,5,21,5,11]
List.length list1 ;;
-: Int = 6
List.isEmpty list1 ;;
-: Bool = false
let list0 = List.cons 5 list0 ;;
-: Lis = [5]
let list0 = List.cons 6 list0 ;;
-: Lis = [6,5]
List.map doubler list1 ;;
-: Lis = [22,10,42,10,2,4]
List.filter pred_even list1 ;;
-: Lis = [2]
(List.append list1 list2) ;;
-: Lis = [11,5,21,5,1,2,3,2]
List.forAll pred_even list1 ;;
-: Bool = false
List.exists pred_even list2 ;;
-: Bool = true
(search 21 list1 0) ;;
-: Int = 2
```