Guest User

Untitled

a guest
Nov 17th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.86 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <inttypes.h>
  4. #include <string.h>
  5. #include <sys/mman.h>
  6.  
  7. typedef void *(*f)(void *);
  8.  
  9. f make_function_with_state(f code, size_t code_len, void *state, size_t state_len) {
  10. f mem = mmap(NULL, code_len + state_len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  11. memcpy(mem, code, code_len);
  12. memcpy(mem + code_len, state, state_len);
  13. mprotect(mem, code_len + state_len, PROT_READ|PROT_EXEC);
  14. return mem;
  15. }
  16.  
  17. extern void *single_var_helper(void *);
  18. extern const size_t single_var_helper_len;
  19.  
  20. __asm__(
  21. "single_var_helper:\n"
  22. "mov %rdi,%rsi\n"
  23. "mov single_var_helper_len(%rip), %rdi\n"
  24. "jmp *single_var_helper_len+8(%rip)\n"
  25. "single_var_helper_len:\n"
  26. ".8byte .-single_var_helper"
  27. );
  28.  
  29. extern void *double_var_helper(void *);
  30. extern const size_t double_var_helper_len;
  31.  
  32. __asm__(
  33. "double_var_helper:\n"
  34. "mov %rdi,%rdx\n"
  35. "mov double_var_helper_len(%rip), %rdi\n"
  36. "mov double_var_helper_len+8(%rip), %rsi\n"
  37. "jmp *double_var_helper_len+16(%rip)\n"
  38. "double_var_helper_len:\n"
  39. ".8byte .-double_var_helper"
  40. );
  41.  
  42. void *B_inner(void *x, void *y, void *z) {
  43. void *yz = ((f)y)(z);
  44. return ((f)x)(yz);
  45. }
  46.  
  47. void *B_middle(void *x, void *y) {
  48. void *state[] = {x, y, B_inner};
  49. return make_function_with_state(double_var_helper, double_var_helper_len, state, sizeof(state));
  50. }
  51.  
  52. void *B(void *x) {
  53. void *state[] = {x, B_middle};
  54. return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
  55. }
  56.  
  57. void *C_inner(void *x, void *y, void *z) {
  58. void *xz = ((f)x)(z);
  59. return ((f)xz)(y);
  60. }
  61.  
  62. void *C_middle(void *x, void *y) {
  63. void *state[] = {x, y, C_inner};
  64. return make_function_with_state(double_var_helper, double_var_helper_len, state, sizeof(state));
  65. }
  66.  
  67. void *C(void *x) {
  68. void *state[] = {x, C_middle};
  69. return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
  70. }
  71.  
  72. void *K_inner(void *x, void *y) {
  73. return x;
  74. }
  75.  
  76. void *K(void *x) {
  77. void *state[] = {x, K_inner};
  78. return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
  79. }
  80.  
  81. void *I(void *x) {
  82. return x;
  83. }
  84.  
  85. void *S_inner(void *x, void *y, void *z) {
  86. void *xz = ((f)x)(z);
  87. void *yz = ((f)y)(z);
  88. return ((f)xz)(yz);
  89. }
  90.  
  91. void *S_middle(void *x, void *y) {
  92. void *state[] = {x, y, S_inner};
  93. return make_function_with_state(double_var_helper, double_var_helper_len, state, sizeof(state));
  94. }
  95.  
  96. void *S(void *x) {
  97. void *state[] = {x, S_middle};
  98. return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
  99. }
  100.  
  101. void *W_inner(void *x, void *y) {
  102. f xy = ((f)x)(y);
  103. return xy(y);
  104. }
  105.  
  106. void *W(void *x) {
  107. void *state[] = {x, W_inner};
  108. return make_function_with_state(single_var_helper, single_var_helper_len, state, sizeof(state));
  109. }
  110.  
  111. void *inc(void *x) {
  112. return (void *)(1 + (uintptr_t)x);
  113. }
  114.  
  115. uintptr_t church_to_int(f church) {
  116. f church_inc = church(inc);
  117. return (uintptr_t)church_inc(0);
  118. }
  119.  
  120. static f zero, succ;
  121.  
  122. f int_to_church(uintptr_t i) {
  123. f n = zero;
  124. while(i--) {
  125. n = succ(n);
  126. }
  127. return n;
  128. }
  129.  
  130. int main(void) {
  131. f BS = B(S);
  132. f BB = B(B);
  133. f plus = BS(BB);
  134. f BW = B(W);
  135. f BBC = BB(C);
  136. f B_BW = B(BW);
  137. f S_alt = B_BW(BBC);
  138. f BS_alt = B(S_alt);
  139. f plus_alt = BS_alt(BB);
  140. f mult = B;
  141. f exp = C(I);
  142. zero = K(I);
  143. f one = I;
  144. succ = plus(one);
  145. f two = succ(one);
  146. f three = succ(two);
  147. f four = int_to_church(4);
  148. f add_three = plus(three);
  149. f three_plus_four = add_three(four);
  150. f add_three_alt = plus_alt(three);
  151. f three_plus_four_alt = add_three_alt(four);
  152. f three_of = mult(three);
  153. f three_times_four = three_of(four);
  154. f three_to = exp(three);
  155. f three_fourth = three_to(four);
  156. printf("3+4 is %" PRIuPTR "\n", church_to_int(three_plus_four));
  157. printf("3+4 a different way is %" PRIuPTR "\n", church_to_int(three_plus_four_alt));
  158. printf("3*4 is %" PRIuPTR "\n", church_to_int(three_times_four));
  159. printf("3^4 is %" PRIuPTR "\n", church_to_int(three_fourth));
  160. return 0;
  161. }
Add Comment
Please, Sign In to add comment