{}
run-icon
main.c
#include <stdio.h> #include <stdarg.h> typedef struct LAMBDA { struct LAMBDA *(*fn)(struct LAMBDA *, ...); } *lambda_t; // -------- True/False --------- lambda_t l_true_fn(lambda_t x, ...) { return x; } static const lambda_t L_TRUE = &(struct LAMBDA) { .fn = l_true_fn }; lambda_t l_false_fn(lambda_t x, ...) { va_list argp; va_start(argp, x); lambda_t y = va_arg(argp, lambda_t); va_end(argp); return y; } static const lambda_t L_FALSE = &(struct LAMBDA) { .fn = l_false_fn }; // -------- Boolean Algebra -------- lambda_t l_not_fn(lambda_t b, ...) { return b->fn(L_FALSE, L_TRUE); } static const lambda_t L_NOT = &(struct LAMBDA) { .fn = l_not_fn }; lambda_t l_and_fn(lambda_t b1, ...) { va_list argp; va_start(argp, b1); lambda_t b2 = va_arg(argp, lambda_t); va_end(argp); return b1->fn(b2, L_FALSE); } static const lambda_t L_AND = &(struct LAMBDA) { .fn = l_and_fn }; lambda_t l_or_fn(lambda_t b1, ...) { va_list argp; va_start(argp, b1); lambda_t b2 = va_arg(argp, lambda_t); va_end(argp); return b1->fn(L_TRUE, b2); } static const lambda_t L_OR = &(struct LAMBDA) { .fn = l_or_fn }; // -------- Church Numerals -------- static const lambda_t L_ZERO = &(struct LAMBDA) { .fn = l_false_fn }; lambda_t l_succ_fn(lambda_t n, ...) { va_list argp; va_start(argp, n); lambda_t f = va_arg(argp, lambda_t); lambda_t x = va_arg(argp, lambda_t); va_end(argp); return f->fn(n->fn(f, x)); } // Initialize SUC lambda_t L_SUCC = &(struct LAMBDA) { .fn = l_succ_fn }; int main() { // Test bools printf("TRUE = %p, FALSE = %p\n", L_TRUE, L_FALSE); const lambda_t not_true = L_NOT->fn(L_TRUE); const lambda_t not_false = L_NOT->fn(L_FALSE); printf("!TRUE = %p, !FALSE = %p\n", not_true, not_false); const lambda_t false_a_false = L_AND->fn(L_FALSE, L_FALSE); const lambda_t false_a_true = L_AND->fn(L_FALSE, L_TRUE); const lambda_t true_a_false = L_AND->fn(L_TRUE, L_FALSE); const lambda_t true_a_true = L_AND->fn(L_TRUE, L_TRUE); printf( "FALSE & FALSE = %p\nFALSE & TRUE = %p\nTRUE & FALSE = %p\nTRUE & TRUE = %p\n", false_a_false, false_a_true, true_a_false, true_a_true ); const lambda_t false_o_false = L_OR->fn(L_FALSE, L_FALSE); const lambda_t false_o_true = L_OR->fn(L_FALSE, L_TRUE); const lambda_t true_o_false = L_OR->fn(L_TRUE, L_FALSE); const lambda_t true_o_true = L_OR->fn(L_TRUE, L_TRUE); printf( "FALSE | FALSE = %p\nFALSE | TRUE = %p\nTRUE | FALSE = %p\nTRUE | TRUE = %p\n", false_o_false, false_o_true, true_o_false, true_o_true ); // Test numerals printf("0 = %p, s(x) = %p\n", L_ZERO, L_SUCC); const lambda_t one = L_SUCC->fn(L_ZERO, L_TRUE); printf("1 = %p\n", one); const lambda_t two = L_SUCC->fn(one, L_TRUE); return 0; }
Output