Skip to content

Instantly share code, notes, and snippets.

@paniq
Last active March 13, 2017 23:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save paniq/627a408adee7142bd9ef743f2034f70f to your computer and use it in GitHub Desktop.
Save paniq/627a408adee7142bd9ef743f2034f70f to your computer and use it in GitHub Desktop.
Cheney on the MTA in C++11
// Syntax demo for writing Cheney on the MTA style code in C++11
// (see http://home.pipeline.com/~hbaker1/CheneyMTA.html for more info)
//
// Using variadic macros, I managed to design a syntax that is good enough
// to write in, as opposed to the automated code generation that COTMTA
// originally envisioned.
//
// key reasons why I intend to use this:
// * Writing a Scheme interpreter that keeps the C stack compact
// is annoying and hard. Continuing down the stack is easy.
// * Nested anonymous continuations are easier to write than
// split up toplevel functions.
// * All heap allocation turn into garbage collected stack allocations.
// That means alloca replaces malloc completely.
// * The GC compacts data regularly and linearizes dependencies
// over time, which improves access times.
// * Stack depth no longer matters as much for recursive algorithms.
// * Runtime-generated code profits from this infrastructure as well.
//
// The example computes pow(2,16) and is equivalent
// to this pseudocode:
//
// fn pow (x n cont)
// if (n == 0)
// cont 1
// else if ((n % 2) == 0)
// pow x (n / 2)
// fn (x2)
// cont (x2 * x2)
// else
// pow x (n - 1)
// fn (x2)
// cont (x * x2)
// fn cmain ()
// pow 2 16
// fn (x)
// print x
//
// lots of ugly preceding macros that you don't want to look at ;-)
...
FN(pow, (x, n, cont), (),
if (n.i32 == 0) {
RET(cont.closure, 1);
} else if ((n.i32 % 2) == 0) {
CC(pow, x, n.i32 / 2,
FN((x2), (cont),
RET(cont.closure, x2.i32 * x2.i32);
));
} else {
CC(pow, x, n.i32 - 1,
FN((x2), (x, cont),
RET(cont.closure, x.i32 * x2.i32);
));
}
)
FN(cmain, (), (),
CC(pow, 2, 16,
FN((x), (),
printf("%i\n", x.i32);
exit(0);
));
)
int main(int argc, char ** argv) {
char c = 0; g_stack_limit = &c - 0x200000;
cmain::run(nullptr, 0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment