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.

72 lines
1.5 KiB

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