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) {
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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) {
 | 
			
		||||
 | 
			
		||||
@ -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 ())");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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));
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user