run dune b
to build, this project requires menhirLib
and ppx_sexp_conv
and sexplib
.
the product will be a single executable in _build/default/install/bin
, it should named spml
.
run it with -help
to see help message.
note that this program transpile a m-lisp based language to COMMON LISP as its IR, if you want to execute a file, use sbcl
.
dune exec spml <filename.sp> | sbcl --script
See examples in testcases.
Use
`name
to include a file with name
.
As in ml let xxx = yyy in zzz
, let bindings in this syntax should be xxx := yyy => zzz
,
with type annotation in ml let xxx: ttt = yyy in zzz
, in this syntax it should be xxx: ttt = yyy => zzz
As in toplevel ml let val xxx: ttt in zzz
, type annotations in this syntax should be xxx: ttt => zzz
, also in top level.
This also declared the name, for recursive definitions like functions, this is necessary.
As in Commom Lisp (cond (p1 e1) (p2 e2) ... ('t en))
, in this syntax it should be p1 -> e1 | p2 -> e2 | ... | _ -> en
, where wildcard must be the last predicate.
As in Common Lisp (lambda (p1 p2 ... pn) e)
, in this syntax it should be (p1:t1, p2:t2, ..., pn:tn) -> e
, where t1, t2, ..., tn
are type annotation.
Given function named f
, called with arguments a
, b
, c
, should be f[a,b,c]
.
In top-level, there can be multiple programs(expressions) sharing the same env, so xxx := yyy => zzz
and xxx : ttt => zzz
can just be xxx := yyy
and xxx: ttt
, making zzz
the next expression. However, abbr. xxx : ttt = yyy
is not allowed.
Few basic types are provided, like int
and float
. Functions like add[a, b]
where a, b
are int
should typed [int, int] -> int
. Note there is a unit
type like in ML.
You can put any type expressions together forming a list:
{1, 2, {3, 4}, "yes"}
This is legal, is a backdoor to common lisp.
This Language does not have a stdlib, so it needs to 'borrow' functions from other languages as primitives.
Example: Addi: "add_i_i" [int, int] -> int
to import function add_i_i
as Addi
. This can also be used to import symbols.
To export a local symbol to abi, useless currently cuz I haven't done binary generation.
Example: "fbnc_i":= fbnc
ensures to export name fbnc to elf symbol 'fbnc_i'.