// clang -masm=intel -nostdlib -Ltarget/release -lrt -lSystem -Wl,-e,_start -g example.s -o target/example .data ZERO: .zero 8 SUCC: .zero 8 ADD: .zero 8 MUL: .zero 8 DEBUG: .zero 8 .text .global _start _start: // Align the stack sub rsp, 64 and spl, 0xF0 lea rdi, [rip + zero] mov rsi, 2 mov rdx, 0 call _ivy_make_lam mov [rip + ZERO], rax mov rdi, rax call _ivy_incref lea rdi, [rip + succ] mov rsi, 3 mov rdx, 0 call _ivy_make_lam mov [rip + SUCC], rax mov rdi, rax call _ivy_incref lea rdi, [rip + add] mov rsi, 4 mov rdx, 0 call _ivy_make_lam mov [rip + ADD], rax mov rdi, rax call _ivy_incref lea rdi, [rip + mul] mov rsi, 4 mov rdx, 0 call _ivy_make_lam mov [rip + MUL], rax mov rdi, rax call _ivy_incref lea rdi, [rip + debug] mov rsi, 1 mov rdx, 0 call _ivy_make_lam mov [rip + DEBUG], rax mov rdi, rax call _ivy_incref main: mov rdi, [rip + SUCC] mov rsi, [rip + ZERO] call _ivy_app // succ zero mov rdi, [rip + SUCC] mov rsi, rax call _ivy_app // succ (succ zero) // RAX contains Church #2 mov [rsp], rax // 2 := succ (succ zero) mov rdi, [rip + ADD] mov rsi, rax call _ivy_app // add 2 mov rdi, rax mov rsi, [rsp] call _ivy_app // add 2 2 mov [rsp], rax // RAX contains Church #4 mov rdi, [rip + MUL] mov rsi, rax call _ivy_app // mul (add 2 2) mov rdi, rax mov rsi, [rsp] call _ivy_app // 16 := mul (add 2 2) (add 2 2) mov rdi, [rip + MUL] mov rsi, rax call _ivy_app // mul (add 2 2) mov rdi, rax mov rsi, [rsp] call _ivy_app // 64 := mul (add 2 2) 16 // RAX contains Church #16 mov rdi, rax mov rsi, [rip + DEBUG] call _ivy_app // 64 debug mov rdi, rax mov rsi, [rip + ZERO] call _ivy_app // 64 debug zero // This should print out "DBUG <0-addr>" 16 times. I hope. mov rdi, 0 call _exit /* let zero = lam (f x) => x; succ = lam (n f x) => f (n f x); add = lam (m n f x) => m f (n f x); mul = lam (m n f x) => m (n f) x; debug = some magic nonsense in let two = succ (succ zero); four = add two two; _64 = mul (mul four four) four in _64 debug zero */ // \fx.x zero: mov rax, [rdi + (0x18 + 8)] ret // \nfx.f(nfx) succ: push rbx mov rbx, rdi mov rdi, [rbx + 0x18] mov rsi, [rbx + (0x18 + 8)] call _ivy_app // nf mov rdi, rax mov rsi, [rbx + (0x18 + 16) call _ivy_app // nfx mov rdi, [rbx + (0x18 + 8)] mov rsi, rax call _ivy_app // f(nfx) pop rbx ret // \mnfx.mf(nfx) add: push rbx sub rsp, 16 mov rbx, rdi mov rdi, [rbx + 0x18] mov rsi, [rbx + (0x18 + 16)] call _ivy_app // mf mov [rsp], rax mov rdi, [rbx + (0x18 + 8)] mov rsi, [rbx + (0x18 + 16)] call _ivy_app // nf mov rdi, rax mov rsi, [rbx + (0x18 + 24)] call _ivy_app // nfx mov rdi, [rsp] mov rsi, rax call _ivy_app // mf(nfx) add rsp, 16 pop rbx ret // \mnfx.m(nf)x mul: push rbx mov rbx, rdi mov rdi, [rbx + (0x18 + 8)] mov rsi, [rbx + (0x18 + 16)] call _ivy_app // nf mov rdi, [rbx + 0x18] mov rsi, rax call _ivy_app // m(nf) mov rdi, rax mov rsi, [rbx + (0x18 + 24)] call _ivy_app // m(nf)x pop rbx ret // \x.debug x debug: push rbx mov rdi, [rdi + 0x18] call _ivy_debug pop rbx ret