Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Instructions
- class Refer extends Instructions
- constructor : (@variable, @next) ->
- class Close extends Instructions
- constructor : (@parameter, @body, @next) ->
- class Frame extends Instructions
- constructor : (@x, @next) ->
- class Constant extends Instructions
- constructor : (@value, @next) ->
- class Assign extends Instructions
- constructor : (@symbol, @next) ->
- class Return extends Instructions
- class Argument extends Instructions
- constructor : (@argument) ->
- class Apply extends Instructions
- class Halt extends Instructions
- Array::cons = (a) ->
- b = this.concat([])
- b.unshift(a)
- b
- p = (a) ->
- alert a
- a
- compile = (x, next) ->
- if typeof x is 'string' and x[0] isnt '"'
- new Refer x, next
- else if x instanceof Array
- if x[0] is 'lambda'
- new Close x[1], (compile x[2], new Return()), next
- else if x[0] is 'define'
- compile x[2], new Assign x[1], next
- else
- recur = (a, c) ->
- if !a
- if next[0] is 'return' then c
- else new Frame c, next
- else
- recur null, (compile a, new Argument c)
- recur x[1], (compile x[0], new Apply)
- else
- new Constant x, next
- extend = (env, vari, val) ->
- (env.cons [vari, val])
- lookup = (q, e) ->
- if not e
- alert 'lookup failed'
- else if e[0][0] is q
- e[0][1]
- else
- lookup q, e[1..]
- closure = (body, e, vars) ->
- [body, e, vars]
- callframe = (x, e, r, s) ->
- [x, e, r, s]
- VM = (a, x, e, r, s) ->
- if x instanceof Halt then a
- else if x instanceof Refer then VM (lookup x.variable, e), x.next, e, r, s
- else if x instanceof Constant then VM x.value, x.next, e, r, s
- else if x instanceof Close then VM (closure x.body, e, x.parameter), x.next, e, r, s
- else if x instanceof Assign then VM a, x.next, (extend e, x.symbol, a), r, s
- else if x instanceof Frame then VM a, x.x, e, [], (callframe x.next, e, r, s)
- else if x instanceof Argument then VM a, x.argument, e, r.cons(a), s
- else if x instanceof Apply then VM a, a[0], (extend a[1], a[2], r[0]), [], s
- else if x instanceof Return then VM a, s[0], s[1], s[2], s[3]
- else alert 'undefined instruction'
- #evaluate = (x) -> VM [], (compile x, new Halt()), [], [], []
- evaluate = (block...) ->
- recur = (rest) ->
- if !rest[1] then (compile rest[0], new Halt())
- else (compile rest[0], (recur rest[1..]))
- VM [], (recur block), [], [], []
- #evaluate [['lambda', 'a', 'a'], [['lambda', 'b', 'b'], 2]]
- parse = (src) ->
- tokens = src.split(' ')
- recur = (arr) ->
- switch arr[0]
- when '/'
- body = recur arr[2..]
- result : ['lambda', arr[1], body.result],
- rest : body.rest
- when '$'
- fn = recur arr[1..]
- arg = recur fn.rest
- result : [fn.result, arg.result],
- rest : arg.rest
- when '='
- body = recur arr[2..]
- result : ['define', arr[1], body.result],
- rest : body.rest
- else
- x = if arr[0].match(/^[0-9]+$/) then Number(arr[0]) else arr[0]
- result : x,
- rest : arr[1..] or null
- (recur tokens).result
- alert evaluate(
- (parse '= cons / x / y / z $ $ z x y'),
- (parse '= car / z $ z / x / y x'),
- (parse '= cdr / z $ z / x / y y'),
- (parse '= true / x / y x'),
- (parse '= false / x / y y'),
- (parse '= if / p / t / e $ $ p t e'),
- (parse '$ $ $ if true $ car $ $ cons "true" "or" "false"')
- )
Add Comment
Please, Sign In to add comment