You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
1.4 KiB

4 years ago
  1. local A, F, I = {}, {}, {}
  2. local stack = {}
  3. local sp = 1
  4. local function repr(x)
  5. if type(x) == 'table' then
  6. if x[1] == F then
  7. return x[4]
  8. elseif x[1] == A then
  9. return repr(x[2]) .. '(' .. repr(x[3]) .. ')'
  10. elseif x[1] == I then
  11. return '&' .. repr(x[2])
  12. end
  13. else
  14. return tostring(x)
  15. end
  16. end
  17. local function unwind()
  18. local x = stack[sp]
  19. if type(x) == 'table' then
  20. if x[1] == A then
  21. stack[sp + 1] = x[2]; sp = sp + 1
  22. return unwind()
  23. elseif x[1] == I then
  24. stack[sp] = x[2]
  25. return unwind()
  26. elseif x[1] == F then
  27. if sp - 1 >= x[3] then
  28. return x[2]()
  29. else
  30. print("insufficient arguments for supercombinator " .. x[4])
  31. print 'stack dump:'
  32. for k, v in pairs(stack) do
  33. print(sp - k, repr(v))
  34. end
  35. error()
  36. end
  37. end
  38. else
  39. os.exit(x)
  40. end
  41. end
  42. local function getchar()
  43. local k = stack[sp - 1][3]; sp = sp - 1
  44. local knil = stack[sp - 1][3]; sp = sp - 1
  45. local ch = io.read(1)
  46. if ch then
  47. stack[sp] = { A, k, ch:byte() }
  48. else
  49. stack[sp] = { A, knil, 0 }
  50. end
  51. return unwind()
  52. end
  53. local getchar_combinator = { F, getchar, 2 }
  54. local function putchar()
  55. local ch = stack[sp - 1][3];
  56. local k = stack[sp - 2][3]; sp = sp - 1
  57. io.write(string.char(ch))
  58. stack[sp] = { A, k, ch }
  59. return unwind()
  60. end
  61. local putchar_combinator = { F, putchar, 2 }