#include "stdio.h" #include "stdlib.h" typedef struct { void* apply_func; // pointer to function apply this closure w/ correct number of args and free-vars void* func; // pointer to lifted function that implements this closure int num_freevars; // number of bound variables (for GC use) char* str; // string representation of this function void* forwarded; // forward pointer (for GC use) void* args[]; // bound variables } clos; // halt function void halt_func(clos* halt, clos* val) { printf("%s\n", val->str); exit(0); } // halt continuation clos halt_impl = {&halt_func, // just use the apply function NULL, 2, "halt func", NULL, NULL}; // no bound args static clos* halt = &halt_impl; /* function pointer typedefs */ typedef void (*fp_typedef2032)(clos*, clos*); typedef void (*fp_typedef2028)(clos*, clos*, clos*, clos*); typedef void (*fp_typedef2025)(clos*, clos*, clos*); /* apply function definitions */ // apply_funcs do not allocate any important stack variables, // so we can use a return and save some memory // there is one apply function for each used combination of (num-args, num-free-vars) // note functions only take one argument in vanilla lambda calculus void apply_func22052(clos* cls, clos* arg2051) { // use a return here, we don't have to worry about blowing important stack variables return ((fp_typedef2032)(cls->func))(arg2051,((clos*)(cls->args[0]))); } void apply_func22038(clos* cls, clos* arg2036,clos* arg2037) { return ((fp_typedef2032)(cls->func))(arg2036,arg2037); } void apply_func32035(clos* cls, clos* arg2033,clos* arg2034) { return ((fp_typedef2025)(cls->func))(arg2033,arg2034,((clos*)(cls->args[0]))); } void apply_func42031(clos* cls, clos* arg2029,clos* arg2030) { return ((fp_typedef2028)(cls->func))(arg2029,arg2030,((clos*)(cls->args[0])),((clos*)(cls->args[1]))); } void apply_func32027(clos* cls, clos* arg2026) { return ((fp_typedef2025)(cls->func))(arg2026,((clos*)(cls->args[0])),((clos*)(cls->args[1]))); } /* forward declarations */ void func2049(clos*, clos*); void func2047(clos*, clos*); void func2045(clos*, clos*); void func2043(clos*, clos*); void func2041(clos*, clos*, clos*); void func2039(clos*, clos*); void func2023(clos*, clos*, clos*); void func2021(clos*, clos*, clos*, clos*); void func2019(clos*, clos*, clos*); void func2017(clos*, clos*); /* lifted function definitions */ // allocate all values (just closures) on the stack // never return from a lifted lambda function // so all stack pointers remain valid (until overflow, of course) void func2043(clos* rv2009, clos* halt) { clos* clos2046 = alloca(sizeof(clos)+(sizeof(clos*)*0)+(sizeof(char)*16)); clos2046->num_args = 0; clos2046->func = &func2045; clos2046->apply_func = &apply_func22038; clos2046->str = "(LAMBDA (B3) B3)"; clos* clos2048 = alloca(sizeof(clos)+(sizeof(clos*)*1)+(sizeof(char)*0)); clos2048->num_args = 1; clos2048->func = &func2047; clos2048->apply_func = &apply_func22052; clos2048->str = NULL; clos2048->args[0] = (void*)halt; ((fp_typedef2025)(rv2009->apply_func))(rv2009,clos2046,clos2048); } void func2047(clos* rv2007, clos* halt) { clos* clos2050 = alloca(sizeof(clos)+(sizeof(clos*)*0)+(sizeof(char)*16)); clos2050->num_args = 0; clos2050->func = &func2049; clos2050->apply_func = &apply_func22038; clos2050->str = "(LAMBDA (C2) C2)"; ((fp_typedef2025)(rv2007->apply_func))(rv2007,clos2050,halt); } void func2049(clos* C2, clos* k2008) { ((fp_typedef2032)(k2008->apply_func))(k2008,C2); } void func2045(clos* B3, clos* k2010) { ((fp_typedef2032)(k2010->apply_func))(k2010,B3); } void func2039(clos* B2, clos* k2015) { clos* clos2042 = alloca(sizeof(clos)+(sizeof(clos*)*1)+(sizeof(char)*16)); clos2042->num_args = 1; clos2042->func = &func2041; clos2042->apply_func = &apply_func32035; clos2042->str = "(LAMBDA (C3) B2)"; clos2042->args[0] = (void*)B2; ((fp_typedef2032)(k2015->apply_func))(k2015,clos2042); } void func2041(clos* C3, clos* k2016, clos* B2) { ((fp_typedef2032)(k2016->apply_func))(k2016,B2); } void func2017(clos* A, clos* k2011) { clos* clos2020 = alloca(sizeof(clos)+(sizeof(clos*)*1)+(sizeof(char)*35)); clos2020->num_args = 1; clos2020->func = &func2019; clos2020->apply_func = &apply_func32035; clos2020->str = "(LAMBDA (B) (LAMBDA (C) ((A B) C)))"; clos2020->args[0] = (void*)A; ((fp_typedef2032)(k2011->apply_func))(k2011,clos2020); } void func2019(clos* B, clos* k2012, clos* A) { clos* clos2022 = alloca(sizeof(clos)+(sizeof(clos*)*2)+(sizeof(char)*22)); clos2022->num_args = 2; clos2022->func = &func2021; clos2022->apply_func = &apply_func42031; clos2022->str = "(LAMBDA (C) ((A B) C))"; clos2022->args[0] = (void*)A; clos2022->args[1] = (void*)B; ((fp_typedef2032)(k2012->apply_func))(k2012,clos2022); } void func2021(clos* C, clos* k2013, clos* A, clos* B) { clos* clos2024 = alloca(sizeof(clos)+(sizeof(clos*)*2)+(sizeof(char)*0)); clos2024->num_args = 2; clos2024->func = &func2023; clos2024->apply_func = &apply_func32027; clos2024->str = NULL; clos2024->args[0] = (void*)k2013; clos2024->args[1] = (void*)C; ((fp_typedef2025)(A->apply_func))(A,B,clos2024); } void func2023(clos* rv2014, clos* k2013, clos* C) { ((fp_typedef2025)(rv2014->apply_func))(rv2014,C,k2013); } int main() { clos* clos2040 = alloca(sizeof(clos)+(sizeof(clos*)*0)+(sizeof(char)*30)); clos2040->num_args = 0; clos2040->func = &func2039; clos2040->apply_func = &apply_func22038; clos2040->str = "(LAMBDA (B2) (LAMBDA (C3) B2))"; clos* clos2044 = alloca(sizeof(clos)+(sizeof(clos*)*1)+(sizeof(char)*0)); clos2044->num_args = 1; clos2044->func = &func2043; clos2044->apply_func = &apply_func22052; clos2044->str = NULL; clos2044->args[0] = (void*)halt; clos* clos2018 = alloca(sizeof(clos)+(sizeof(clos*)*0)+(sizeof(char)*48)); clos2018->num_args = 0; clos2018->func = &func2017; clos2018->apply_func = &apply_func22038; clos2018->str = "(LAMBDA (A) (LAMBDA (B) (LAMBDA (C) ((A B) C))))"; ((fp_typedef2025)(clos2018->apply_func))(clos2018,clos2040,clos2044); return 0; }