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.

66 lines
1.4 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
  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. else
  19. return x, stack, sp
  20. end
  21. end
  22. local function repr(x)
  23. if type(x) == 'table' then
  24. if x[1] == A then
  25. return repr(x[2]) .. '(' .. repr(x[3])
  26. elseif x[1] == F then
  27. return x[4]
  28. elseif x[1] == I then
  29. return '&' .. repr(x[2])
  30. end
  31. return '<bad node>'
  32. else
  33. return tostring(x)
  34. end
  35. end
  36. local function eval(node)
  37. local stack, sp = { node }, 1
  38. return (unwind(stack, sp))
  39. end
  40. local function getchar(stack, sp)
  41. local k = stack[sp - 1][3]; sp = sp - 1
  42. local knil = stack[sp - 1][3]; sp = sp - 1
  43. local ch = io.read(1)
  44. if ch then
  45. stack[sp] = { A, k, ch:byte() }
  46. else
  47. stack[sp] = { A, knil, 0 }
  48. end
  49. return unwind(stack, sp)
  50. end
  51. local getchar_combinator = { F, getchar, 2 }
  52. local function putchar()
  53. local ch = stack[sp - 1][3];
  54. local k = stack[sp - 2][3]; sp = sp - 1
  55. io.write(string.char(ch))
  56. stack[sp] = { A, k, ch }
  57. return unwind(stack, sp)
  58. end
  59. local putchar_combinator = { F, putchar, 2 }