LunarML
A Standard ML compiler that produces Lua/JavaScript.
Building
You need a recent version of MLton to build the executable, and Lua 5.3+ or recent Node.js to run the compiled script.
$ make
$ make test
$ make test-lua-continuations
$ make test-luajit
$ make test-nodejs
$ make test-nodejs-cps
$ bin/lunarml compile example/hello.sml
$ lua example/hello.lua
Hello world!
Usage
lunarml [subcommand] [options] input.(sml|mlb)
Subcommand:
-
compile
: Compile a program. -
help
: Show help. -
version
: Show version information.
Targets:
- Lua
-
--lua
(default): Targets Lua 5.3+. -
--lua-continuations
: Targets Lua 5.3+. Supports one-shot delimited continuations. Also, supports deeply nestedhandle
. -
--luajit
: Targets LuaJIT.
-
- JavaScript (ES2020+)
-
--js
: Produces a JavaScript program. -
--js-cps
: Produces a JavaScript program (CPS mode; supports delimited continuations).
-
Output type:
-
--exe
(default): Produces Lua/JavaScript program. -
--lib
: Produces a Lua module.
Features
- Most of SML '97 language, including signatures and functors
- A subset of SML Basis Library
- Interface to Lua
- Interface to JavaScript
- Delimited continuations (experimental)
- ML Basis system like MLton
Successor ML features:
- Monomorphic non-exhaustive bindings
-
Simplified recursive value bindings
- SML '97-compatible ordering for type variables is also supported:
val <tyvarseq> rec <valbind>
- SML '97-compatible ordering for type variables is also supported:
- Abstype as derived form
- Fixed manifest type specifications
- Abolish sequenced type realizations
- Line comments
-
Extended literal syntax
-
Underscores (e.g.
3.1415_9265
,0xffff_ffff
) -
Binary notation (
0b
,0wb
) -
Eight hex digits in text (
\Uxxxxxxxx
)
-
Underscores (e.g.
- Record punning
- Record extension
- Record update
- Conjunctive patterns
- Disjunctive patterns
- Nested matches
- Pattern guards
- Optional bars and semicolons
- Optional else branch
- Do declarations
- Withtype in signatures
Other extensions planned:
- Vector expressions and patterns
- Packaged modules (like in Alice ML or HaMLet S)
-
Hexadecimal floating-point constants (e.g.
0x1p1024
,0x1.ffff_ffff_ffff_f
) -
Variably-encoded Unicode escape sequence in string literals (e.g.
\u{3042}
) - Unicode identifiers
The syntax of hexadecimal floating-point constants is:
<hexadecimal-integer-constant> ::= '~'? '0' 'w'? 'x' <hexadecimal-digit-sequence>
<hexadecimal-floating-point-constant> ::= '~'? '0x' <hexadecimal-digit-sequence> (<binary-exponent-part> | '.' <hexadecimal-digit-sequence> <binary-exponent-part>?)
<hexadecimal-digit-sequence> ::= <hexadecimal-digit> ('_'* <hexadecimal-digit>)*
<binary-exponent-part> ::= [pP] '~'? <digit> ('_'* <digit>)?
In short: the (binary) exponent part is optional and use tilde (~
) for the negation symbol.
The \u{}
escape sequence allows you to embed a Unicode scalar value in a string literal.
The compiler encodes the character in UTF-(8|16|32), depending on the string type.