diff --git a/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodClosure.wiki b/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodClosure.wiki index 7d2e32e..3ec719a 100644 --- a/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodClosure.wiki +++ b/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodClosure.wiki @@ -22,3 +22,74 @@ Test | check | evaluate | (funcall my-counter :dec) | 2 | | check | evaluate | (funcall my-counter :dec) | 1 | | check | evaluate | (funcall my-counter :dec) | 0 | + + +| script | lisp interpreter fixture | +| # | dlambda | +| show | evaluate |!- + +(defun map (fn ls) + (if (null ls) + () + (cons (funcall fn (first ls)) + (map fn (rest ls)) + ) + ) +) + +(define-macro dlambda (&rest methods) + (cons + (quote lambda) + (cons + (quote (&rest arguments)) + (list + (cons + (quote case) + (cons + (quote (first arguments)) + (map + (lambda (method) + (cons + (first method) + (list + (cons + (quote apply) + (cons + (cons + (quote lambda) + (rest method) + ) + (list (quote (rest arguments))) + ) + ) + ) + ) + ) + methods + ) + ) + ) + ) + ) + ) +) + +(defun apple-counter () + (let ((apple-count 0)) + (eval + (dlambda + (:inc () (setf apple-count (+ apple-count 1))) + (:dec () (setf apple-count (- apple-count 1))) + ) + ) + ) +) + -!| +| show | evaluate | (setf a (apple-counter)) | +| check | evaluate | (funcall a :inc) | 1 | +| check | evaluate | (funcall a :inc) | 2 | +| check | evaluate | (funcall a :inc) | 3 | +| check | evaluate | (funcall a :dec) | 2 | +| check | evaluate | (funcall a :dec) | 1 | +| check | evaluate | (funcall a :dec) | 0 | +| show | evaluate | (funcall a :inc 1) | diff --git a/fitnesse/FitNesseRoot/RecentChanges.wiki b/fitnesse/FitNesseRoot/RecentChanges.wiki index 4c3733e..d3421b5 100644 --- a/fitnesse/FitNesseRoot/RecentChanges.wiki +++ b/fitnesse/FitNesseRoot/RecentChanges.wiki @@ -1,4 +1,4 @@ -|LispInterpreter.MultipleMethodClosure||11:04:53 Wed, Mar 01, 2017| +|LispInterpreter.MultipleMethodClosure||16:02:22 Wed, Mar 01, 2017| |LispInterpreter.SetUp||11:04:36 Wed, Mar 01, 2017| |LispInterpreter.LexicalClosures||12:10:13 Mon, Feb 27, 2017| |LispInterpreter.TestClosure||11:24:27 Mon, Feb 27, 2017| diff --git a/lisp/dlambda.lisp b/lisp/dlambda.lisp new file mode 100644 index 0000000..76331c6 --- /dev/null +++ b/lisp/dlambda.lisp @@ -0,0 +1,46 @@ +(defun map (fn ls) + (if (null ls) + () + (cons (funcall fn (first ls)) + (map fn (rest ls)) + ) + ) +) + +(define-macro dlambda (&rest methods) + (cons + (quote lambda) + (cons + (quote (&rest arguments)) + (list + (cons + (quote case) + (cons + (quote (first arguments)) + (map + (lambda (method) + (cons + (first method) + (list + (cons + (quote apply) + (cons + (cons + (quote lambda) + (rest method) + ) + (list (quote (rest arguments))) + ) + ) + ) + ) + ) + methods + ) + ) + ) + ) + ) + ) +) + diff --git a/test/function/builtin/special/CASETester.java b/test/function/builtin/special/CASETester.java index 7a055a0..8ddc54e 100644 --- a/test/function/builtin/special/CASETester.java +++ b/test/function/builtin/special/CASETester.java @@ -116,6 +116,20 @@ public class CASETester { assertSExpressionsMatch(parseString("orange"), evaluateString(input)); } + @Test + public void caseWithEmptyList() { + String input = "(case () ((()) 'orange))"; + + assertSExpressionsMatch(parseString("orange"), evaluateString(input)); + } + + @Test + public void caseWithList() { + String input = "(case '(5 4 3) (((1 2) (5 4 3)) 'orange))"; + + assertSExpressionsMatch(parseString("orange"), evaluateString(input)); + } + @Test public void caseWithDefaultClause() { String input = "(case nil (() 'banana) (t 'orange))"; @@ -185,8 +199,13 @@ public class CASETester { } @Test(expected = BadArgumentTypeException.class) - public void caseWithNilClause() { + public void caseWithEmptyClause() { evaluateString("(case :a ())"); } + @Test(expected = BadArgumentTypeException.class) + public void caseWithNilClause() { + evaluateString("(case :a nil)"); + } + } diff --git a/test/function/builtin/special/CONDTester.java b/test/function/builtin/special/CONDTester.java index 468bcf6..3e1ea94 100644 --- a/test/function/builtin/special/CONDTester.java +++ b/test/function/builtin/special/CONDTester.java @@ -72,10 +72,15 @@ public class CONDTester { } @Test(expected = BadArgumentTypeException.class) - public void condWithNilArgument_ThrowsException() { + public void condWithEmptyListArgument_ThrowsException() { evaluateString("(cond ())"); } + @Test(expected = BadArgumentTypeException.class) + public void condWithNilArgument_ThrowsException() { + evaluateString("(cond nil)"); + } + @Test(expected = BadArgumentTypeException.class) public void condWithNonListArgument_ThrowsException() { evaluateString("(cond o)");