Metacadr was broken. You won't believe why!
Lists are mutable, even by-reference. When I was popping off the values, I was destroying the list; metacadr only worked once. That was terrible functional programming. I should learn to trust myself; by using a cons-list for my operations index and a lookup table (anti-if!) for my operations, the code was simplified incredibly. Also, added a very (!) primitive pretty printer. It'll get better over time, but for now it's sufficient for debugging.
This commit is contained in:
parent
75a22f87ea
commit
d9345c513a
|
@ -15,4 +15,5 @@ bin/coffee
|
||||||
bin/escodegen
|
bin/escodegen
|
||||||
bin/esgenerate
|
bin/esgenerate
|
||||||
bin/mocha
|
bin/mocha
|
||||||
|
*.js
|
||||||
|
|
||||||
|
|
|
@ -41,13 +41,13 @@ listToVector = (l, v = []) ->
|
||||||
listToVector (cdr l), v
|
listToVector (cdr l), v
|
||||||
|
|
||||||
metacadr = (m) ->
|
metacadr = (m) ->
|
||||||
seq = m.match(/c([ad]+)r/)[1].split('')
|
ops = {'a': car, 'd': cdr}
|
||||||
|
seq = vectorToList m.match(/c([ad]+)r/)[1].split('').reverse()
|
||||||
return (l) ->
|
return (l) ->
|
||||||
inner = (l, s) ->
|
inner = (l, s) ->
|
||||||
return nil if nilp l
|
return l if (nilp l) or (nilp s)
|
||||||
return l if s.length == 0
|
inner ops[(car s)](l), (cdr s)
|
||||||
inner ((if s.pop() == 'a' then car else cdr)(l)), s
|
inner l, seq
|
||||||
inner(l, seq)
|
|
||||||
|
|
||||||
module.exports =
|
module.exports =
|
||||||
cons: cons
|
cons: cons
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
{listToString, listToVector, pairp, cons, car, cdr, caar, cddr, cdar, cadr, caadr, cadar, caddr, nilp, nil, setcdr, metacadr} = require "cons-lists/lists"
|
||||||
|
|
||||||
|
evlis = (exps, d) ->
|
||||||
|
if (pairp exps) then evaluate((car exps), d) + " " + evlis((cdr exps), d) else evaluate(exps, d)
|
||||||
|
|
||||||
|
indent = (d) ->
|
||||||
|
([0..d].map () -> " ").join('')
|
||||||
|
|
||||||
|
evaluate = (e, d = 0) ->
|
||||||
|
t = typeof e
|
||||||
|
if (pairp e) then "\n" + indent(d) + "(" + evlis(e, d + 2) + ")"
|
||||||
|
else if (nilp e) then "()"
|
||||||
|
else if t is "boolean" then (if e then "#t" else "#f")
|
||||||
|
else if t is "string"
|
||||||
|
if e.length > 0 and e[0] == '"' then '"' + e + '"' else e
|
||||||
|
else if t is "number" then e
|
||||||
|
else if t is "function" then e.toString()
|
||||||
|
else e.toString()
|
||||||
|
|
||||||
|
module.exports = (c) -> evaluate c, 0
|
Loading…
Reference in New Issue