#include #include #include #include #include #include void rt_3addiii(int *res, int a, int b) { *res = a + b; } void rt_3subiii(int *res, int a, int b) { *res = a - b; } void rt_2eqbii(bool *res, int a, int b) { *res = a == b; } void rt_2if(bool test, ...) { va_list args; va_start(args, test); if (!test) { int num_skip = va_arg(args, int); for (int i = 0; i < num_skip; i++) { (void) va_arg(args, ffi_type*); (void) va_arg(args, void*); } va_arg(args, void(*)()); } int num_args = va_arg(args, int); ffi_cif cif; ffi_arg ret; ffi_type **types = alloca(sizeof(ffi_type*) * num_args); void **values = alloca(sizeof(void(*)()) * num_args); for (int i = 0; i < num_args; i++) { types[i] = va_arg(args, ffi_type*); values[i] = va_arg(args, void*); } void (*fun)() = va_arg(args, void*); ffi_status result = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, num_args, &ffi_type_void, types); assert(result == FFI_OK); ffi_call(&cif, fun, &ret, values); } int zero = 0; int one = 1; void ack(int *res, int m, int n); void ack_ret2(int *res, int m) { int temp; rt_3subiii(&temp, m, one); ack(res, temp, one); } void ack_rest2(int *res, int m, int n) { int temp1, temp2, temp3; rt_3subiii(&temp1, n, one); ack(&temp2, m, temp1); rt_3subiii(&temp3, m, one); ack(res, temp3, temp2); } void ack_ret1(int *res, int n) { rt_3addiii(res, n, one); } void ack_rest1(int *res, int m, int n) { bool temp; rt_2eqbii(&temp, n, zero); rt_2if(temp, 2, &ffi_type_pointer, &res, &ffi_type_sint32, &m, &ack_ret2, 3, &ffi_type_pointer, &res, &ffi_type_sint32, &m, &ffi_type_sint32, &n, &ack_rest2 ); } void ack(int *res, int m, int n) { bool temp; rt_2eqbii(&temp, m, zero); rt_2if(temp, 2, &ffi_type_pointer, &res, &ffi_type_sint32, &n, &ack_ret1, 3, &ffi_type_pointer, &res, &ffi_type_sint32, &m, &ffi_type_sint32, &n, &ack_rest1 ); } int wrap_ack(int m, int n) { int res; ack(&res, m, n); return res; } int main(int argc, const char *argv[]) { for (int i = 0; i < 10; ++i) { printf("ack(3, 7) = %i\n", wrap_ack(3, 7)); } }