MetaLang compiles ML-like source language to C++ meta template code, which allows you to easily utilize the compile-time computation capability of C++ compilers.
You need SMLNJ with ml-lpt-lib preinstalled to build this compiler, since the
lexical analyzer and parser is built with ml-ulex and ml-antlr. Once all
dependencies were resolved, you can run the script ./build.sh
to build the
compiler.
Let’s compile a simple metalang program for a shakedown run: simple
is a
metalang source file, it defined a factorial function and calculated the factorial
of 0, 1, … 5. The factorial function looks a bit weird since it is written in
Y-combinator form, a better version of factorial function can be found in
/samples/partial
.
First let’s compile it:
./metac simple
If the compilation succeeded, you can see compiled C++ code printed to the
terminal. Now let’s wrap these compiled code with a main function (please refer to
try.cc
for details).
template <int _>
struct dump {};
int main(int argc, char *argv[])
{
dump<fac0> _0;
dump<fac1> _1;
dump<fac2> _2;
dump<fac3> _3;
dump<fac4> _4;
dump<fac5> _5;
return 0;
}
Actually, the template parameter passed to dump
does not match with its
definition (aka, facK are not ints), however we deliberately wrote these illegal
code for dumping computed values in compile error messages, you can find values of
facK hidden inside a bunch of error messages generated by g++ try.cc
:
try.cc: In function ‘int main(int, char**)’:
try.cc:59:18: error: type/value mismatch at argument 1 in template parameter list for ‘template<int _> struct dump’
try.cc:59:18: error: expected a constant of type ‘int’, got ‘fac0 {aka meta_integer<1>}’
try.cc:59:22: error: invalid type in declaration before ‘;’ token
try.cc:60:18: error: type/value mismatch at argument 1 in template parameter list for ‘template<int _> struct dump’
try.cc:60:18: error: expected a constant of type ‘int’, got ‘fac1 {aka meta_integer<1>}’
try.cc:60:22: error: invalid type in declaration before ‘;’ token
try.cc:61:18: error: type/value mismatch at argument 1 in template parameter list for ‘template<int _> struct dump’
try.cc:61:18: error: expected a constant of type ‘int’, got ‘fac2 {aka meta_integer<2>}’
try.cc:61:22: error: invalid type in declaration before ‘;’ token
try.cc:62:18: error: type/value mismatch at argument 1 in template parameter list for ‘template<int _> struct dump’
try.cc:62:18: error: expected a constant of type ‘int’, got ‘fac3 {aka meta_integer<6>}’
try.cc:62:22: error: invalid type in declaration before ‘;’ token
try.cc:63:18: error: type/value mismatch at argument 1 in template parameter list for ‘template<int _> struct dump’
try.cc:63:18: error: expected a constant of type ‘int’, got ‘fac4 {aka meta_integer<24>}’
try.cc:63:22: error: invalid type in declaration before ‘;’ token
try.cc:64:18: error: type/value mismatch at argument 1 in template parameter list for ‘template<int _> struct dump’
try.cc:64:18: error: expected a constant of type ‘int’, got ‘fac5 {aka meta_integer<120>}’
try.cc:64:22: error: invalid type in declaration before ‘;’ token
… can be found in /samples/
, there are several interesting examples involving
currying, higher-order functions, compound datatypes and Y-combinators. you can
get a first impression about what the syntax looks like and what you can do with
metalang.