Parts of CASE and COND were refactored
Updated the terminology used in the code Added test cases Changed the format of error/warning messages
This commit is contained in:
parent
4253145383
commit
42191ec69d
|
@ -40,7 +40,7 @@ public class ErrorManager {
|
||||||
private String formatMessage(LispException lispException) {
|
private String formatMessage(LispException lispException) {
|
||||||
Severity severity = lispException.getSeverity();
|
Severity severity = lispException.getSeverity();
|
||||||
String prefix = severity.toDisplayString();
|
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);
|
return severity.decorate(message, environment);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class CASE extends LispSpecialFunction {
|
||||||
SExpression keyList = clause.getFirst();
|
SExpression keyList = clause.getFirst();
|
||||||
|
|
||||||
if (isMatch(key, keyList))
|
if (isMatch(key, keyList))
|
||||||
return evaluateResult(clause);
|
return evaluateConsequents(clause.getRest());
|
||||||
|
|
||||||
return callTailRecursive(key, remainingClauses);
|
return callTailRecursive(key, remainingClauses);
|
||||||
}
|
}
|
||||||
|
@ -68,13 +68,13 @@ public class CASE extends LispSpecialFunction {
|
||||||
return ((Cons) knownCons).getFirst();
|
return ((Cons) knownCons).getFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression evaluateResult(Cons clause) {
|
private SExpression evaluateConsequents(SExpression consequentList) {
|
||||||
SExpression lastResultValue = Nil.getInstance();
|
SExpression lastConsequentValue = Nil.getInstance();
|
||||||
|
|
||||||
for (SExpression result = clause.getRest(); result.isCons(); result = advanceCons(result))
|
for (; consequentList.isCons(); consequentList = advanceCons(consequentList))
|
||||||
lastResultValue = eval(getFirst(result));
|
lastConsequentValue = eval(getFirst(consequentList));
|
||||||
|
|
||||||
return lastResultValue;
|
return lastConsequentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ public class COND extends LispSpecialFunction {
|
||||||
SExpression test = eval(clause.getFirst());
|
SExpression test = eval(clause.getFirst());
|
||||||
|
|
||||||
if (isTestSuccessful(test))
|
if (isTestSuccessful(test))
|
||||||
return evaluateResult(clause, test);
|
return evaluateConsequents(clause.getRest(), test);
|
||||||
|
|
||||||
return callTailRecursive(remainingClauses);
|
return callTailRecursive(remainingClauses);
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,13 @@ public class COND extends LispSpecialFunction {
|
||||||
return test != Nil.getInstance();
|
return test != Nil.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression evaluateResult(Cons clause, SExpression test) {
|
private SExpression evaluateConsequents(SExpression consequentList, SExpression test) {
|
||||||
SExpression lastResultValue = test;
|
SExpression lastConsequentValue = test;
|
||||||
|
|
||||||
for (SExpression result = clause.getRest(); result.isCons(); result = advanceCons(result))
|
for (; consequentList.isCons(); consequentList = advanceCons(consequentList))
|
||||||
lastResultValue = eval(getFirst(result));
|
lastConsequentValue = eval(getFirst(consequentList));
|
||||||
|
|
||||||
return lastResultValue;
|
return lastConsequentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression advanceCons(SExpression knownCons) {
|
private SExpression advanceCons(SExpression knownCons) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class CASETester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void caseWithOnlySwitchExpression() {
|
public void caseWithKeyOnly() {
|
||||||
String input = "(case t)";
|
String input = "(case t)";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
|
@ -95,6 +95,13 @@ public class CASETester {
|
||||||
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseDoesNotEvaluateKeyList() {
|
||||||
|
String input = "(case 'x ((x) t))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("t"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void caseWithEmptyKeyList() {
|
public void caseWithEmptyKeyList() {
|
||||||
String input = "(case nil (() 'orange))";
|
String input = "(case nil (() 'orange))";
|
||||||
|
@ -138,7 +145,24 @@ public class CASETester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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)))";
|
String input = "(case 2 ((0) (setf zero 0)) ((1) (setf one 1)) ((2) (setf two '2)) ((2) (setf two 'two)))";
|
||||||
|
|
||||||
evaluateString("(setf zero nil)");
|
evaluateString("(setf zero nil)");
|
||||||
|
@ -160,4 +184,9 @@ public class CASETester {
|
||||||
evaluateString("(case :a t)");
|
evaluateString("(case :a t)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
|
public void caseWithNilClause() {
|
||||||
|
evaluateString("(case :a ())");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,42 +30,42 @@ public class CONDTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void condWithSingleExpression() {
|
public void condWithSingleClause() {
|
||||||
String input = "(cond (T \"true\"))";
|
String input = "(cond (T \"true\"))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("\"true\""), evaluateString(input));
|
assertSExpressionsMatch(parseString("\"true\""), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void condWithMultipleExpressions() {
|
public void condWithMultipleClauses() {
|
||||||
String input = "(cond ((= 1 2) 2) ((= 1 2) 2) ((= 1 1) 3))";
|
String input = "(cond ((= 1 2) 2) ((= 1 2) 2) ((= 1 1) 3))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("3"), evaluateString(input));
|
assertSExpressionsMatch(parseString("3"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void condWithMultipleConditionsMatching_ReturnFirstOne() {
|
public void condWithMultipleTrueTests_ReturnsFirstOne() {
|
||||||
String input = "(cond ((= 1 1) 2) ((= 1 1) 3))";
|
String input = "(cond ((= 1 1) 2) ((= 1 1) 3))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("2"), evaluateString(input));
|
assertSExpressionsMatch(parseString("2"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void condWithMultipleConditionsMatching_OnlyEvaluatesFirstOne() {
|
public void condWithMultipleTrueTests_OnlyEvaluatesFirstOne() {
|
||||||
String input = "(cond ((= 1 1) 2) ((= 1 1) x))";
|
String input = "(cond ((= 1 1) 2) ((= 1 1) x))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("2"), evaluateString(input));
|
assertSExpressionsMatch(parseString("2"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void condWithMultipleResultValues_OnlyReturnsLast() {
|
public void condWithMultipleValuesInConsequent_OnlyReturnsLast() {
|
||||||
String input = "(cond ((= 1 1) 2 3 4))";
|
String input = "(cond ((= 1 1) 2 3 4))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("4"), evaluateString(input));
|
assertSExpressionsMatch(parseString("4"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void condWithNoConditionMatching_ReturnsNil() {
|
public void condWithNoTrueTest_ReturnsNil() {
|
||||||
String input = "(cond ((= 1 2) T) ((= 1 3) T))";
|
String input = "(cond ((= 1 2) T) ((= 1 3) T))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
|
|
Loading…
Reference in New Issue