Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdint.h>
- #include <inttypes.h>
- #include <string.h>
- #include <sys/mman.h>
- typedef void *(*f)(void *);
- f make_function_with_state(f code, size_t code_len, void *state, size_t state_len) {
- f mem = mmap(NULL, code_len + state_len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- memcpy(mem, code, code_len);
- memcpy(mem + code_len, state, state_len);
- mprotect(mem, code_len + state_len, PROT_READ|PROT_EXEC);
- return mem;
- }
- extern void *single_var_helper(void *);
- extern const size_t single_var_helper_len;
- __asm__(
- "single_var_helper:\n"
- "mov %rdi,%rsi\n"
- "mov single_var_helper_len(%rip), %rdi\n"
- "jmp *single_var_helper_len+8(%rip)\n"
- "single_var_helper_len:\n"
- ".8byte .-single_var_helper"
- );
- extern void *double_var_helper(void *);
- extern const size_t double_var_helper_len;
- __asm__(
- "double_var_helper:\n"
- "mov %rdi,%rdx\n"
- "mov double_var_helper_len(%rip), %rdi\n"
- "mov double_var_helper_len+8(%rip), %rsi\n"
- "jmp *double_var_helper_len+16(%rip)\n"
- "double_var_helper_len:\n"
- ".8byte .-double_var_helper"
- );
- void *B_inner(void *x, void *y, void *z) {
- void *yz = ((f)y)(z);
- return ((f)x)(yz);
- }
- void *B_middle(void *x, void *y) {
- void *state[] = {x, y, B_inner};
- return make_function_with_state(double_var_helper, double_var_helper_len, state, sizeof(state));
- }
- void *B(void *x) {
- void *state[] = {x, B_middle};
- return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
- }
- void *C_inner(void *x, void *y, void *z) {
- void *xz = ((f)x)(z);
- return ((f)xz)(y);
- }
- void *C_middle(void *x, void *y) {
- void *state[] = {x, y, C_inner};
- return make_function_with_state(double_var_helper, double_var_helper_len, state, sizeof(state));
- }
- void *C(void *x) {
- void *state[] = {x, C_middle};
- return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
- }
- void *K_inner(void *x, void *y) {
- return x;
- }
- void *K(void *x) {
- void *state[] = {x, K_inner};
- return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
- }
- void *I(void *x) {
- return x;
- }
- void *S_inner(void *x, void *y, void *z) {
- void *xz = ((f)x)(z);
- void *yz = ((f)y)(z);
- return ((f)xz)(yz);
- }
- void *S_middle(void *x, void *y) {
- void *state[] = {x, y, S_inner};
- return make_function_with_state(double_var_helper, double_var_helper_len, state, sizeof(state));
- }
- void *S(void *x) {
- void *state[] = {x, S_middle};
- return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
- }
- void *W_inner(void *x, void *y) {
- f xy = ((f)x)(y);
- return xy(y);
- }
- void *W(void *x) {
- void *state[] = {x, W_inner};
- return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
- }
- void *inc(void *x) {
- return (void *)(1 + (uintptr_t)x);
- }
- uintptr_t church_to_int(f church) {
- f church_inc = church(inc);
- return (uintptr_t)church_inc(0);
- }
- static f zero, succ;
- f int_to_church(uintptr_t i) {
- f n = zero;
- while(i--) {
- n = succ(n);
- }
- return n;
- }
- int main(void) {
- f BS = B(S);
- f BB = B(B);
- f plus = BS(BB);
- f BW = B(W);
- f BBC = BB(C);
- f B_BW = B(BW);
- f S_alt = B_BW(BBC);
- f BS_alt = B(S_alt);
- f plus_alt = BS_alt(BB);
- f mult = B;
- f exp = C(I);
- zero = K(I);
- f one = I;
- succ = plus(one);
- f two = succ(one);
- f three = succ(two);
- f four = int_to_church(4);
- f add_three = plus(three);
- f three_plus_four = add_three(four);
- f add_three_alt = plus_alt(three);
- f three_plus_four_alt = add_three_alt(four);
- f three_of = mult(three);
- f three_times_four = three_of(four);
- f three_to = exp(three);
- f three_fourth = three_to(four);
- printf("3+4 is %" PRIuPTR "\n", church_to_int(three_plus_four));
- printf("3+4 a different way is %" PRIuPTR "\n", church_to_int(three_plus_four_alt));
- printf("3*4 is %" PRIuPTR "\n", church_to_int(three_times_four));
- printf("3^4 is %" PRIuPTR "\n", church_to_int(three_fourth));
- return 0;
- }
Add Comment
Please, Sign In to add comment