Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Quramy/pico-ml
A toy programming language which is a subset of OCaml.
https://github.com/Quramy/pico-ml
compiler language ml wasm
Last synced: 3 months ago
JSON representation
A toy programming language which is a subset of OCaml.
- Host: GitHub
- URL: https://github.com/Quramy/pico-ml
- Owner: Quramy
- License: mit
- Created: 2021-04-02T15:26:21.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-05-28T07:14:25.000Z (5 months ago)
- Last Synced: 2024-05-28T14:34:42.322Z (5 months ago)
- Topics: compiler, language, ml, wasm
- Language: TypeScript
- Homepage: https://quramy.github.io/pico-ml/
- Size: 8.11 MB
- Stars: 49
- Watchers: 3
- Forks: 1
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# PicoML
[![github actions](https://github.com/Quramy/pico-ml/workflows/build/badge.svg)](https://github.com/Quramy/pico-ml/actions)
[![npm version](https://badge.fury.io/js/pico-ml.svg)](https://badge.fury.io/js/pico-ml)
[![codecov](https://codecov.io/gh/Quramy/pico-ml/graph/badge.svg?token=ZZN2OX50UX)](https://codecov.io/gh/Quramy/pico-ml)A toy programming language which is a subset of OCaml.
```ocaml
let rec fact n = if n < 2 then 1 else n * fact(n - 1) in
let rec range s e = if s >= e then [] else s::(range (s + 1) e) in
let rec map f list = match list with [] -> [] | x::y -> (f x)::(map f y) in
map fact (range 1 7) (* ==> int list: [ 1, 2, 6, 24, 120, 720 ] *)
```## Features
- Interpreter
- Type inference
- Compile to WASM## Web Playground
[![Playground](https://raw.githubusercontent.com/Quramy/pico-ml/main/playground_capture.png)](https://quramy.github.io/pico-ml/)
[You can try PicoML here.](https://quramy.github.io/pico-ml/)
## How to use
### Install
```sh
$ npm i -g pico-ml
```### REPL
You can REPL with `ipml` command.
```sh
$ ipml# Input ML expression to evaluate
> let add = fun a -> fun b -> a + b in add 1 2;;
```The REPL allows multiple line input. Enter `;;` to evaluate the input expression.
### Compiler
```ocaml
(* example.ml *)let add = fun a -> fun b -> a + b in add 1 2
```To compile Web Assembly module, use `pmlc` command.
```sh
$ pmlc example.ml
```The generated module exports `main` function to evaluate the input expression.
```js
// Execute in browserconst instance = await WebAssembly.instatiateStreaming(fetch("example.wasm"), {});
const result = instance.exports["main"]();
console.log(result);
``````js
// Execute in Node.jsconst fs = require("fs/promises");
(async () => {
const source = await fs.readFile("example.wasm");
const { instance } = await WebAssembly.instantiate(source, {});
const result = instance.exports["main"]();
console.log(result);
})();
```And `pmlc` can also outputs WAT file with `-t` option.
```sh
$ pmlc example.ml -t
```## Language
### BNF
```
expr ::= id |
int |
decimal |
bool |
"[]" |
expr expr |
unop expr |
expr binop expr |
expr "::" expr |
"if" expr "then" expr "else" expr |
"match" expr "with" clause |
"fun" id "->" expr |
"let" id id* "=" expr "in" expr |
"let" "rec" id "=" "fun" id "->" expr "in" expr |
"let" "rec" id id+ "=" expr "in" exprclause ::= pat "->" expr | pat "->" expr "|" clause
pat ::= id | "[]" | "_" | pat "::" pat
id ::= (letter | "_"){ letter | digit | "_" | "'" }
unop ::= "-" | "-."
binop ::= "+" | "-" | "*" | "/" | +." | "-." | "*." |"/." | "<" | ">" | "<=" | ">=" | "=" | "<>" | "==" | "!=" | "&&" | "||"
bool ::= "true" | "false"
int ::= (digit)+
decimal ::= digit+"."digit*
letter ::= "a" | ... | "z" | "A" | ... | "Z"
digit ::= "0" | ... | "9"
```## License
MIT