local A, F, I = {}, {}, {} local stack = {} local sp = 1 local function repr(x) if type(x) == 'table' then if x[1] == F then return x[4] elseif x[1] == A then return repr(x[2]) .. '(' .. repr(x[3]) .. ')' elseif x[1] == I then return '&' .. repr(x[2]) end else return tostring(x) end end local function unwind() local x = stack[sp] if type(x) == 'table' then if x[1] == A then stack[sp + 1] = x[2]; sp = sp + 1 return unwind() elseif x[1] == I then stack[sp] = x[2] return unwind() elseif x[1] == F then if sp - 1 >= x[3] then return x[2]() else print("insufficient arguments for supercombinator " .. x[4]) print 'stack dump:' for k, v in pairs(stack) do print(sp - k, repr(v)) end error() end end else os.exit(x) end end local function getchar() local k = stack[sp - 1][3]; sp = sp - 1 local knil = stack[sp - 1][3]; sp = sp - 1 local ch = io.read(1) if ch then stack[sp] = { A, k, ch:byte() } else stack[sp] = { A, knil, 0 } end return unwind() end local getchar_combinator = { F, getchar, 2 } local function putchar() local ch = stack[sp - 1][3]; local k = stack[sp - 2][3]; sp = sp - 1 io.write(string.char(ch)) stack[sp] = { A, k, ch } return unwind() end local putchar_combinator = { F, putchar, 2 }