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:
Elf M. Sternberg 2015-05-20 15:43:34 -07:00
parent 75a22f87ea
commit d9345c513a
3 changed files with 26 additions and 5 deletions

1
.gitignore vendored
View File

@ -15,4 +15,5 @@ bin/coffee
bin/escodegen
bin/esgenerate
bin/mocha
*.js

View File

@ -41,13 +41,13 @@ listToVector = (l, v = []) ->
listToVector (cdr l), v
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) ->
inner = (l, s) ->
return nil if nilp l
return l if s.length == 0
inner ((if s.pop() == 'a' then car else cdr)(l)), s
inner(l, seq)
return l if (nilp l) or (nilp s)
inner ops[(car s)](l), (cdr s)
inner l, seq
module.exports =
cons: cons

20
src/print.coffee Normal file
View File

@ -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