Last active
March 13, 2017 23:58
-
-
Save paniq/627a408adee7142bd9ef743f2034f70f to your computer and use it in GitHub Desktop.
Cheney on the MTA in C++11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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