Guest User

Untitled

a guest
Sep 24th, 2018
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.26 KB | None | 0 0
  1. class Instructions
  2. class Refer extends Instructions
  3. constructor : (@variable, @next) ->
  4. class Close extends Instructions
  5. constructor : (@parameter, @body, @next) ->
  6. class Frame extends Instructions
  7. constructor : (@x, @next) ->
  8. class Constant extends Instructions
  9. constructor : (@value, @next) ->
  10. class Assign extends Instructions
  11. constructor : (@symbol, @next) ->
  12. class Return extends Instructions
  13. class Argument extends Instructions
  14. constructor : (@argument) ->
  15. class Apply extends Instructions
  16. class Halt extends Instructions
  17. Array::cons = (a) ->
  18. b = this.concat([])
  19. b.unshift(a)
  20. b
  21.  
  22.  
  23. p = (a) ->
  24. alert a
  25. a
  26.  
  27. compile = (x, next) ->
  28. if typeof x is 'string' and x[0] isnt '"'
  29. new Refer x, next
  30. else if x instanceof Array
  31. if x[0] is 'lambda'
  32. new Close x[1], (compile x[2], new Return()), next
  33. else if x[0] is 'define'
  34. compile x[2], new Assign x[1], next
  35. else
  36. recur = (a, c) ->
  37. if !a
  38. if next[0] is 'return' then c
  39. else new Frame c, next
  40. else
  41. recur null, (compile a, new Argument c)
  42. recur x[1], (compile x[0], new Apply)
  43. else
  44. new Constant x, next
  45.  
  46. extend = (env, vari, val) ->
  47. (env.cons [vari, val])
  48.  
  49. lookup = (q, e) ->
  50. if not e
  51. alert 'lookup failed'
  52. else if e[0][0] is q
  53. e[0][1]
  54. else
  55. lookup q, e[1..]
  56.  
  57. closure = (body, e, vars) ->
  58. [body, e, vars]
  59.  
  60. callframe = (x, e, r, s) ->
  61. [x, e, r, s]
  62.  
  63. VM = (a, x, e, r, s) ->
  64. if x instanceof Halt then a
  65. else if x instanceof Refer then VM (lookup x.variable, e), x.next, e, r, s
  66. else if x instanceof Constant then VM x.value, x.next, e, r, s
  67. else if x instanceof Close then VM (closure x.body, e, x.parameter), x.next, e, r, s
  68. else if x instanceof Assign then VM a, x.next, (extend e, x.symbol, a), r, s
  69. else if x instanceof Frame then VM a, x.x, e, [], (callframe x.next, e, r, s)
  70. else if x instanceof Argument then VM a, x.argument, e, r.cons(a), s
  71. else if x instanceof Apply then VM a, a[0], (extend a[1], a[2], r[0]), [], s
  72. else if x instanceof Return then VM a, s[0], s[1], s[2], s[3]
  73. else alert 'undefined instruction'
  74.  
  75. #evaluate = (x) -> VM [], (compile x, new Halt()), [], [], []
  76. evaluate = (block...) ->
  77. recur = (rest) ->
  78. if !rest[1] then (compile rest[0], new Halt())
  79. else (compile rest[0], (recur rest[1..]))
  80. VM [], (recur block), [], [], []
  81.  
  82. #evaluate [['lambda', 'a', 'a'], [['lambda', 'b', 'b'], 2]]
  83.  
  84. parse = (src) ->
  85. tokens = src.split(' ')
  86. recur = (arr) ->
  87. switch arr[0]
  88. when '/'
  89. body = recur arr[2..]
  90. result : ['lambda', arr[1], body.result],
  91. rest : body.rest
  92. when '$'
  93. fn = recur arr[1..]
  94. arg = recur fn.rest
  95. result : [fn.result, arg.result],
  96. rest : arg.rest
  97. when '='
  98. body = recur arr[2..]
  99. result : ['define', arr[1], body.result],
  100. rest : body.rest
  101. else
  102. x = if arr[0].match(/^[0-9]+$/) then Number(arr[0]) else arr[0]
  103. result : x,
  104. rest : arr[1..] or null
  105. (recur tokens).result
  106.  
  107. alert evaluate(
  108. (parse '= cons / x / y / z $ $ z x y'),
  109. (parse '= car / z $ z / x / y x'),
  110. (parse '= cdr / z $ z / x / y y'),
  111. (parse '= true / x / y x'),
  112. (parse '= false / x / y y'),
  113. (parse '= if / p / t / e $ $ p t e'),
  114. (parse '$ $ $ if true $ car $ $ cons "true" "or" "false"')
  115. )
Add Comment
Please, Sign In to add comment