From 42191ec69d00a5b37666b74b1f5d2ac4d9f396da Mon Sep 17 00:00:00 2001 From: Mike Cifelli Date: Tue, 28 Feb 2017 16:16:43 -0500 Subject: [PATCH] Parts of CASE and COND were refactored Updated the terminology used in the code Added test cases Changed the format of error/warning messages --- src/error/ErrorManager.java | 2 +- src/function/builtin/special/CASE.java | 12 +++---- src/function/builtin/special/COND.java | 12 +++---- test/function/builtin/special/CASETester.java | 33 +++++++++++++++++-- test/function/builtin/special/CONDTester.java | 12 +++---- 5 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/error/ErrorManager.java b/src/error/ErrorManager.java index 4788665..7a78685 100644 --- a/src/error/ErrorManager.java +++ b/src/error/ErrorManager.java @@ -40,7 +40,7 @@ public class ErrorManager { private String formatMessage(LispException lispException) { Severity severity = lispException.getSeverity(); String prefix = severity.toDisplayString(); - String message = MessageFormat.format("{0}: {1}", prefix, lispException.getMessage()); + String message = MessageFormat.format("[{0}] {1}", prefix, lispException.getMessage()); return severity.decorate(message, environment); } diff --git a/src/function/builtin/special/CASE.java b/src/function/builtin/special/CASE.java index e387140..60da96b 100644 --- a/src/function/builtin/special/CASE.java +++ b/src/function/builtin/special/CASE.java @@ -34,7 +34,7 @@ public class CASE extends LispSpecialFunction { SExpression keyList = clause.getFirst(); if (isMatch(key, keyList)) - return evaluateResult(clause); + return evaluateConsequents(clause.getRest()); return callTailRecursive(key, remainingClauses); } @@ -68,13 +68,13 @@ public class CASE extends LispSpecialFunction { return ((Cons) knownCons).getFirst(); } - private SExpression evaluateResult(Cons clause) { - SExpression lastResultValue = Nil.getInstance(); + private SExpression evaluateConsequents(SExpression consequentList) { + SExpression lastConsequentValue = Nil.getInstance(); - for (SExpression result = clause.getRest(); result.isCons(); result = advanceCons(result)) - lastResultValue = eval(getFirst(result)); + for (; consequentList.isCons(); consequentList = advanceCons(consequentList)) + lastConsequentValue = eval(getFirst(consequentList)); - return lastResultValue; + return lastConsequentValue; } } diff --git a/src/function/builtin/special/COND.java b/src/function/builtin/special/COND.java index c8a33b8..8429453 100644 --- a/src/function/builtin/special/COND.java +++ b/src/function/builtin/special/COND.java @@ -31,7 +31,7 @@ public class COND extends LispSpecialFunction { SExpression test = eval(clause.getFirst()); if (isTestSuccessful(test)) - return evaluateResult(clause, test); + return evaluateConsequents(clause.getRest(), test); return callTailRecursive(remainingClauses); } @@ -40,13 +40,13 @@ public class COND extends LispSpecialFunction { return test != Nil.getInstance(); } - private SExpression evaluateResult(Cons clause, SExpression test) { - SExpression lastResultValue = test; + private SExpression evaluateConsequents(SExpression consequentList, SExpression test) { + SExpression lastConsequentValue = test; - for (SExpression result = clause.getRest(); result.isCons(); result = advanceCons(result)) - lastResultValue = eval(getFirst(result)); + for (; consequentList.isCons(); consequentList = advanceCons(consequentList)) + lastConsequentValue = eval(getFirst(consequentList)); - return lastResultValue; + return lastConsequentValue; } private SExpression advanceCons(SExpression knownCons) { diff --git a/test/function/builtin/special/CASETester.java b/test/function/builtin/special/CASETester.java index 1abb3bb..7a055a0 100644 --- a/test/function/builtin/special/CASETester.java +++ b/test/function/builtin/special/CASETester.java @@ -26,7 +26,7 @@ public class CASETester { } @Test - public void caseWithOnlySwitchExpression() { + public void caseWithKeyOnly() { String input = "(case t)"; assertSExpressionsMatch(parseString("nil"), evaluateString(input)); @@ -95,6 +95,13 @@ public class CASETester { assertSExpressionsMatch(parseString("nil"), evaluateString(input)); } + @Test + public void caseDoesNotEvaluateKeyList() { + String input = "(case 'x ((x) t))"; + + assertSExpressionsMatch(parseString("t"), evaluateString(input)); + } + @Test public void caseWithEmptyKeyList() { String input = "(case nil (() 'orange))"; @@ -138,7 +145,24 @@ public class CASETester { } @Test - public void caseOnlyEvaluatesFirstMatchingClause() { + public void caseEvaluatesMultipleConsequents() { + String input = "(case 2 (1 1) (2 (setf x 'x) (setf y 'y)) (3 3)))"; + + evaluateString(input); + + assertSExpressionsMatch(parseString("x"), evaluateString("x")); + assertSExpressionsMatch(parseString("y"), evaluateString("y")); + } + + @Test + public void caseReturnsValueOfLastConsequent() { + String input = "(case 2 (1 1) (2 3 4 5) (3 3))"; + + assertSExpressionsMatch(parseString("5"), evaluateString(input)); + } + + @Test + public void caseOnlyEvaluatesConsequentInFirstMatchingClause() { String input = "(case 2 ((0) (setf zero 0)) ((1) (setf one 1)) ((2) (setf two '2)) ((2) (setf two 'two)))"; evaluateString("(setf zero nil)"); @@ -160,4 +184,9 @@ public class CASETester { evaluateString("(case :a t)"); } + @Test(expected = BadArgumentTypeException.class) + public void caseWithNilClause() { + evaluateString("(case :a ())"); + } + } diff --git a/test/function/builtin/special/CONDTester.java b/test/function/builtin/special/CONDTester.java index 5a63e06..468bcf6 100644 --- a/test/function/builtin/special/CONDTester.java +++ b/test/function/builtin/special/CONDTester.java @@ -30,42 +30,42 @@ public class CONDTester { } @Test - public void condWithSingleExpression() { + public void condWithSingleClause() { String input = "(cond (T \"true\"))"; assertSExpressionsMatch(parseString("\"true\""), evaluateString(input)); } @Test - public void condWithMultipleExpressions() { + public void condWithMultipleClauses() { String input = "(cond ((= 1 2) 2) ((= 1 2) 2) ((= 1 1) 3))"; assertSExpressionsMatch(parseString("3"), evaluateString(input)); } @Test - public void condWithMultipleConditionsMatching_ReturnFirstOne() { + public void condWithMultipleTrueTests_ReturnsFirstOne() { String input = "(cond ((= 1 1) 2) ((= 1 1) 3))"; assertSExpressionsMatch(parseString("2"), evaluateString(input)); } @Test - public void condWithMultipleConditionsMatching_OnlyEvaluatesFirstOne() { + public void condWithMultipleTrueTests_OnlyEvaluatesFirstOne() { String input = "(cond ((= 1 1) 2) ((= 1 1) x))"; assertSExpressionsMatch(parseString("2"), evaluateString(input)); } @Test - public void condWithMultipleResultValues_OnlyReturnsLast() { + public void condWithMultipleValuesInConsequent_OnlyReturnsLast() { String input = "(cond ((= 1 1) 2 3 4))"; assertSExpressionsMatch(parseString("4"), evaluateString(input)); } @Test - public void condWithNoConditionMatching_ReturnsNil() { + public void condWithNoTrueTest_ReturnsNil() { String input = "(cond ((= 1 2) T) ((= 1 3) T))"; assertSExpressionsMatch(parseString("nil"), evaluateString(input));