From 54da8c6b655678cca96e4b49476fc13a696c54e8 Mon Sep 17 00:00:00 2001 From: "Elf M. Sternberg" Date: Mon, 22 Jun 2015 17:03:21 -0700 Subject: [PATCH] Changed the list structure to not respect cons(nil, nil) == nil. I think this is a mistake, but at the moment I'm not clever enough to figure out how to properly acknowledge an end-of-list without a special sentinel, which I'm trying to avoid. TODO: Revisit this. Modified Makefile to produce JUnit-compatible error messages. Style (coffee-lint cleanup) --- .gitignore | 1 + Makefile | 6 +++++- src/lists.coffee | 2 +- src/reduce.coffee | 51 +++++++++++++++++----------------------------- test/lists.coffee | 26 +++++++++++------------ test/reduce.coffee | 15 +++++++------- 6 files changed, 47 insertions(+), 54 deletions(-) diff --git a/.gitignore b/.gitignore index cd88911..15c0519 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ bin/escodegen bin/esgenerate bin/mocha *.js +test-reports.xml diff --git a/Makefile b/Makefile index ac60f45..785a274 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,11 @@ node_modules: package.json mkdir -p node_modules npm install -test: node_modules +test: clean node_modules + @JUNIT_REPORT_PATH=test-reports.xml JUNIT_REPORT_STACK=1 ./node_modules/.bin/mocha \ + --reporter mocha-jenkins-reporter --compilers coffee:coffee-script/register || true + +ltest: node_modules @node_modules/.bin/mocha --compilers coffee:coffee-script/register clean: diff --git a/src/lists.coffee b/src/lists.coffee index b6d42cc..ad63567 100644 --- a/src/lists.coffee +++ b/src/lists.coffee @@ -13,7 +13,7 @@ nilp = (a) -> cellp(a) and a.length == 0 nil = (-> l = []; l.__list = true; l)() cons = (a, b = nil) -> - l = if not (a?) then [] else if (nilp a) then b else [a, b] + l = if (not (a?)) then b else [a, b] l.__list = true l diff --git a/src/reduce.coffee b/src/reduce.coffee index 4c53cf6..4050d9a 100644 --- a/src/reduce.coffee +++ b/src/reduce.coffee @@ -1,7 +1,9 @@ -{car, cdr, cons, listp, pairp, nilp, nil, list, listToString} = require './lists' +{car, cdr, cons, listp, pairp, nilp, + nil, list, listToString} = require './lists' reduce = (lst, iteratee, memo, context) -> count = 0 + console.log lst return memo if nilp lst memo = iteratee.call(context, memo, (car lst), count) lst = cdr lst @@ -13,43 +15,28 @@ reduce = (lst, iteratee, memo, context) -> null memo -map = (lst, iteratee, context) -> + +map = (lst, iteratee, context, count = 0) -> return nil if nilp lst - root = cons() + product = iteratee.call(context, (car lst), count, lst) + rest = if (nilp cdr lst) then nil else + map((cdr lst), iteratee, context, count + 1) + cons product, rest - reducer = (memo, item, count) -> - next = cons(iteratee.call(context, item, count, lst)) - memo[1] = next - next - - reduce(lst, reducer, root, context) - (cdr root) - -rmap = (lst, iteratee, context) -> +rmap = (lst, iteratee, context, count = 0) -> return nil if nilp lst - root = cons() - - reducer = (memo, item, count) -> - cons(iteratee.call(context, item, count, lst), memo) - - reduce(lst, reducer, root, context) + product = (if (nilp cdr lst) then nil else + map((cdr lst), iteratee, context, count + 1)) + cons product, iteratee.call(context, (car lst), count, lst) filter = (lst, iteratee, context) -> return nil if nilp lst - root = cons() + if iteratee.call(context, (car lst), lst) + cons (car lst), filter (cdr lst) + else + filter (cdr list) - reducer = (memo, item, count) -> - if iteratee.call(context, item, count, lst) - next = cons(item) - memo[1] = next - next - else - memo - - reduce(lst, reducer, root, context) - if (pairp root) then (cdr root) else root - -reverse = (lst) -> reduce(lst, ((memo, value) -> cons(value, memo)), cons()) +reverse = (lst) -> rmap lst, (i) -> i module.exports = reduce: reduce @@ -57,4 +44,4 @@ module.exports = rmap: rmap filter: filter reverse: reverse - + diff --git a/test/lists.coffee b/test/lists.coffee index 75616b9..589d1fa 100644 --- a/test/lists.coffee +++ b/test/lists.coffee @@ -1,20 +1,16 @@ chai = require 'chai' chai.should() -expect = chai.expect +expect = chai.expect {listToVector, vectorToList, cons, list, nil, metacadr} = require '../src/lists' describe "Basic list building", -> for [t, v] in [ [cons(), cons()] - [cons(nil), cons()] - [cons(), cons(nil)] [cons('a'), cons('a')] [cons('a', cons('b', cons('c'))), cons('a', cons('b', cons('c')))] [cons('a', cons('b', cons('c'))), cons('a', cons('b', cons('c', nil)))] - [cons('a', cons('b', cons('c', nil))), cons('a', cons('b', cons('c')))] - [cons(nil, cons('a')), cons('a')] # Test for identity; consing nil to anything results in anything - [cons(nil, cons(nil, cons(nil))), nil]] + [cons('a', cons('b', cons('c', nil))), cons('a', cons('b', cons('c')))]] do (t, v) -> it "should match #{t}", -> expect(t).to.deep.equal(v) @@ -28,20 +24,20 @@ describe 'Round trip equivalence', -> do (t, v) -> it "should successfully round-trip #{t}", -> expect(listToVector vectorToList t).to.deep.equal(v) - + describe 'List Building', -> for [t, v] in [ [cons(), []] - [cons(nil), []] + [cons(nil), [nil]] [cons('a'), ['a']] [cons('a', cons('b')), ['a', 'b']] [cons('a', cons('b', cons('c'))), ['a', 'b', 'c']] [cons('a', cons('b', cons('c'), nil)), ['a', 'b', 'c']]] do (t, v) -> it "should cons a list into #{v}", -> - expect(listToVector t).to.deep.equal(v) + expect(listToVector t).to.deep.equal(v) -describe 'Dynamic list constructor', -> +describe 'Dynamic list constructor', -> for [t, v] in [ [list(), []] [list('a'), ['a']] @@ -53,7 +49,7 @@ describe 'Dynamic list constructor', -> mcsimple = cons('a', cons('b', cons('c'))) -describe 'Metacadr Simple', -> +describe 'Metacadr Simple', -> for [t, v, r] in [ ['car', 'a'] ['cadr', 'b'] @@ -62,9 +58,13 @@ describe 'Metacadr Simple', -> it "The #{t} should read #{v}", -> expect(metacadr(t)(mcsimple)).to.equal(v) -mccomplex = vectorToList([['a', 'b', 'c'], ['1', '2', '3'], ['X', 'Y', 'Z'], ['f', 'g', 'h']]) +mccomplex = vectorToList([ + ['a', 'b', 'c'], + ['1', '2', '3'], + ['X', 'Y', 'Z'], + ['f', 'g', 'h']]) -describe 'Metacadr Complex', -> +describe 'Metacadr Complex', -> for [t, v, r] in [ ['cadar', 'b'] ['caadddr', 'f'] diff --git a/test/reduce.coffee b/test/reduce.coffee index 1d1d323..ff5dcad 100644 --- a/test/reduce.coffee +++ b/test/reduce.coffee @@ -1,12 +1,13 @@ chai = require 'chai' chai.should() -expect = chai.expect +expect = chai.expect -{listToVector, vectorToList, listToString, cons, list, nil} = require '../src/lists' +{listToVector, vectorToList, + listToString, cons, list, nil} = require '../src/lists' {map, reduce, filter, reverse} = require '../src/reduce' id = (item) -> item - + describe 'Map Identity Testing', -> samples = [ @@ -16,12 +17,12 @@ describe 'Map Identity Testing', -> cons('a', cons('b')) cons('a', cons('b', cons('c'))), cons('a', cons('b', cons('c'), nil))] - + for t in samples do (t) -> it "should produce the same thing as #{t}", -> product = map(t, id) - expect(product).to.deep.equal(t) + expect(product).to.deep.equal(t) describe 'Filter Testing Testing', -> @@ -33,12 +34,12 @@ describe 'Filter Testing Testing', -> [vectorToList([1, 2, 3 ,4]), cons(2, cons(4))]] truth = (item) -> item % 2 == 0 - + for [t, v] in samples do (t, v) -> it "should produce the same thing as #{v}", -> product = filter(t, truth) - expect(product).to.deep.equal(v) + expect(product).to.deep.equal(v) describe 'Reverse', ->