Refactored some code and added unit tests
This commit is contained in:
		
							parent
							
								
									b700b714f3
								
							
						
					
					
						commit
						ea8acd423f
					
				@ -13,7 +13,8 @@ public class Environment {
 | 
				
			|||||||
    private InputStream input;
 | 
					    private InputStream input;
 | 
				
			||||||
    private PrintStream output;
 | 
					    private PrintStream output;
 | 
				
			||||||
    private PrintStream errorOutput;
 | 
					    private PrintStream errorOutput;
 | 
				
			||||||
    private Runnable terminate;
 | 
					    private Runnable terminationFunction;
 | 
				
			||||||
 | 
					    private Runnable errorTerminationFunction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Environment() {}
 | 
					    private Environment() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -29,8 +30,12 @@ public class Environment {
 | 
				
			|||||||
        this.errorOutput = errorOutput;
 | 
					        this.errorOutput = errorOutput;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void setTerminate(Runnable terminate) {
 | 
					    public void setTerminationFunction(Runnable terminationFunction) {
 | 
				
			||||||
        this.terminate = terminate;
 | 
					        this.terminationFunction = terminationFunction;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setErrorTerminationFunction(Runnable errorTerminationFunction) {
 | 
				
			||||||
 | 
					        this.errorTerminationFunction = errorTerminationFunction;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public InputStream getInput() {
 | 
					    public InputStream getInput() {
 | 
				
			||||||
@ -49,8 +54,12 @@ public class Environment {
 | 
				
			|||||||
        return errorOutput;
 | 
					        return errorOutput;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void terminate() {
 | 
					    public void terminateSuccessfully() {
 | 
				
			||||||
        terminate.run();
 | 
					        terminationFunction.run();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    public void terminateExceptionally() {
 | 
				
			||||||
 | 
					        errorTerminationFunction.run();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ public class ErrorManager {
 | 
				
			|||||||
        printError(lispException);
 | 
					        printError(lispException);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (isCritical(lispException))
 | 
					        if (isCritical(lispException))
 | 
				
			||||||
            environment.terminate();
 | 
					            environment.terminateExceptionally();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void printError(LispException lispException) {
 | 
					    private void printError(LispException lispException) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,22 +1,25 @@
 | 
				
			|||||||
package function.builtin;
 | 
					package function.builtin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import environment.Environment;
 | 
				
			||||||
import function.*;
 | 
					import function.*;
 | 
				
			||||||
import sexpression.*;
 | 
					import sexpression.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class EXIT extends LispFunction {
 | 
					public class EXIT extends LispFunction {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private ArgumentValidator argumentValidator;
 | 
					    private ArgumentValidator argumentValidator;
 | 
				
			||||||
 | 
					    private Environment environment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public EXIT() {
 | 
					    public EXIT() {
 | 
				
			||||||
        this.argumentValidator = new ArgumentValidator("EXIT");
 | 
					        this.argumentValidator = new ArgumentValidator("EXIT");
 | 
				
			||||||
        this.argumentValidator.setMaximumNumberOfArguments(0);
 | 
					        this.argumentValidator.setMaximumNumberOfArguments(0);
 | 
				
			||||||
 | 
					        this.environment = Environment.getInstance();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
        System.exit(0);
 | 
					        environment.terminateSuccessfully();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return null;
 | 
					        return Nil.getInstance();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,8 +15,9 @@ public class PRINT extends LispFunction {
 | 
				
			|||||||
        this.environment = Environment.getInstance();
 | 
					        this.environment = Environment.getInstance();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public SExpression call(Cons argList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        SExpression argument = argList.getCar();
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					        SExpression argument = argumentList.getCar();
 | 
				
			||||||
        environment.getOutput().println(argument);
 | 
					        environment.getOutput().println(argument);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return argument;
 | 
					        return argument;
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,9 @@ public interface LispInterpreterBuilder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void setErrorOutput(PrintStream errorOutputStream);
 | 
					    void setErrorOutput(PrintStream errorOutputStream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void setTerminate(Runnable terminationFunction);
 | 
					    void setTerminationFunction(Runnable terminationFunction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setErrorTerminationFunction(Runnable errorTerminationFunction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void useFile(String fileName);
 | 
					    void useFile(String fileName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -33,10 +33,16 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void setTerminate(Runnable terminationFunction) {
 | 
					    public void setTerminationFunction(Runnable terminationFunction) {
 | 
				
			||||||
        this.environment.setTerminate(terminationFunction);
 | 
					        this.environment.setTerminationFunction(terminationFunction);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void setErrorTerminationFunction(Runnable errorTerminationFunction) {
 | 
				
			||||||
 | 
					        this.environment.setErrorTerminationFunction(errorTerminationFunction);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void useFile(String fileName) {
 | 
					    public void useFile(String fileName) {
 | 
				
			||||||
        this.fileName = fileName;
 | 
					        this.fileName = fileName;
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,8 @@ public class LispMain {
 | 
				
			|||||||
        builder.setInput(System.in);
 | 
					        builder.setInput(System.in);
 | 
				
			||||||
        builder.setOutput(System.out);
 | 
					        builder.setOutput(System.out);
 | 
				
			||||||
        builder.setErrorOutput(System.err);
 | 
					        builder.setErrorOutput(System.err);
 | 
				
			||||||
        builder.setTerminate(() -> System.exit(1));
 | 
					        builder.setTerminationFunction(() -> System.exit(0));
 | 
				
			||||||
 | 
					        builder.setErrorTerminationFunction(() -> System.exit(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (args.length > 0)
 | 
					        if (args.length > 0)
 | 
				
			||||||
            builder.useFile(args[0]);
 | 
					            builder.useFile(args[0]);
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ public class ErrorManagerTester {
 | 
				
			|||||||
    private ByteArrayOutputStream outputStream;
 | 
					    private ByteArrayOutputStream outputStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private ErrorManager createErrorManagerWithIndicators() {
 | 
					    private ErrorManager createErrorManagerWithIndicators() {
 | 
				
			||||||
        Environment.getInstance().setTerminate(() -> indicatorSet.add(TERMINATED));
 | 
					        Environment.getInstance().setErrorTerminationFunction(() -> indicatorSet.add(TERMINATED));
 | 
				
			||||||
        Environment.getInstance().setErrorOutput(new PrintStream(outputStream));
 | 
					        Environment.getInstance().setErrorOutput(new PrintStream(outputStream));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new ErrorManager();
 | 
					        return new ErrorManager();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										54
									
								
								test/function/builtin/PRINTTester.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								test/function/builtin/PRINTTester.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					package function.builtin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.junit.Assert.assertEquals;
 | 
				
			||||||
 | 
					import static testutil.TestUtilities.evaluateString;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.*;
 | 
				
			||||||
 | 
					import java.text.MessageFormat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import environment.Environment;
 | 
				
			||||||
 | 
					import function.ArgumentValidator.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class PRINTTester {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private ByteArrayOutputStream outputStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void assertPrinted(String expected) {
 | 
				
			||||||
 | 
					        assertEquals(expected, outputStream.toString());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Before
 | 
				
			||||||
 | 
					    public void setUp() {
 | 
				
			||||||
 | 
					        this.outputStream = new ByteArrayOutputStream();
 | 
				
			||||||
 | 
					        Environment.getInstance().setOutput(new PrintStream(outputStream));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void printStringWorks() {
 | 
				
			||||||
 | 
					        String output = "\"Hello, world!\"";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        evaluateString(MessageFormat.format("(print {0})", output));
 | 
				
			||||||
 | 
					        assertPrinted(MessageFormat.format("{0}\n", output));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void printSymbolWorks() {
 | 
				
			||||||
 | 
					        String output = "A";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        evaluateString(MessageFormat.format("(print ''{0})", output));
 | 
				
			||||||
 | 
					        assertPrinted(MessageFormat.format("{0}\n", output));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = TooManyArgumentsException.class)
 | 
				
			||||||
 | 
					    public void testPrintWithTooManyArguments() {
 | 
				
			||||||
 | 
					        evaluateString("(print '1 '2)");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = TooFewArgumentsException.class)
 | 
				
			||||||
 | 
					    public void testPrintWithTooFewArguments() {
 | 
				
			||||||
 | 
					        evaluateString("(print)");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -106,12 +106,12 @@ public class SExpressionTester {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testCarOfNilIsNil() {
 | 
					    public void testCarOfNilIsNil() {
 | 
				
			||||||
        assertEquals(Nil.getInstance().getCar(), Nil.getInstance());
 | 
					        assertEquals(Nil.getInstance(), Nil.getInstance().getCar());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testCdrOfNilIsNil() {
 | 
					    public void testCdrOfNilIsNil() {
 | 
				
			||||||
        assertEquals(Nil.getInstance().getCdr(), Nil.getInstance());
 | 
					        assertEquals(Nil.getInstance(), Nil.getInstance().getCdr());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
@ -119,7 +119,7 @@ public class SExpressionTester {
 | 
				
			|||||||
        Cons nil = Nil.getInstance();
 | 
					        Cons nil = Nil.getInstance();
 | 
				
			||||||
        nil.setCar(new LispNumber("2"));
 | 
					        nil.setCar(new LispNumber("2"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertEquals(nil.getCar(), Nil.getInstance());
 | 
					        assertEquals(Nil.getInstance(), nil.getCar());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
@ -127,7 +127,7 @@ public class SExpressionTester {
 | 
				
			|||||||
        Cons nil = Nil.getInstance();
 | 
					        Cons nil = Nil.getInstance();
 | 
				
			||||||
        nil.setCdr(new LispNumber("2"));
 | 
					        nil.setCdr(new LispNumber("2"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertEquals(nil.getCdr(), Nil.getInstance());
 | 
					        assertEquals(Nil.getInstance(), nil.getCdr());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
@ -135,7 +135,7 @@ public class SExpressionTester {
 | 
				
			|||||||
        BigInteger value = new BigInteger("12");
 | 
					        BigInteger value = new BigInteger("12");
 | 
				
			||||||
        LispNumber number = new LispNumber(value.toString());
 | 
					        LispNumber number = new LispNumber(value.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertEquals(number.getValue(), value);
 | 
					        assertEquals(value, number.getValue());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test(expected = InvalidNumberException.class)
 | 
					    @Test(expected = InvalidNumberException.class)
 | 
				
			||||||
@ -166,8 +166,8 @@ public class SExpressionTester {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testLispNumberConstants() {
 | 
					    public void testLispNumberConstants() {
 | 
				
			||||||
        assertEquals(LispNumber.ZERO.getValue(), new BigInteger("0"));
 | 
					        assertEquals(BigInteger.ZERO, LispNumber.ZERO.getValue());
 | 
				
			||||||
        assertEquals(LispNumber.ONE.getValue(), new BigInteger("1"));
 | 
					        assertEquals(BigInteger.ONE, LispNumber.ONE.getValue());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -29,21 +29,21 @@ public class SymbolTableTester {
 | 
				
			|||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void retrieveSymbolValue() {
 | 
					    public void retrieveSymbolValue() {
 | 
				
			||||||
        symbolTable.put("symbol", Symbol.T);
 | 
					        symbolTable.put("symbol", Symbol.T);
 | 
				
			||||||
        assertEquals(symbolTable.get("symbol"), Symbol.T);
 | 
					        assertEquals(Symbol.T, symbolTable.get("symbol"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void redefineSymbolValue() {
 | 
					    public void redefineSymbolValue() {
 | 
				
			||||||
        symbolTable.put("symbol", Symbol.T);
 | 
					        symbolTable.put("symbol", Symbol.T);
 | 
				
			||||||
        symbolTable.put("symbol", Nil.getInstance());
 | 
					        symbolTable.put("symbol", Nil.getInstance());
 | 
				
			||||||
        assertEquals(symbolTable.get("symbol"), Nil.getInstance());
 | 
					        assertEquals(Nil.getInstance(), symbolTable.get("symbol"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void checkParentTableIsCorrect() {
 | 
					    public void checkParentTableIsCorrect() {
 | 
				
			||||||
        SymbolTable childTable = new SymbolTable(symbolTable);
 | 
					        SymbolTable childTable = new SymbolTable(symbolTable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertEquals(childTable.getParent(), symbolTable);
 | 
					        assertEquals(symbolTable, childTable.getParent());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
@ -52,7 +52,7 @@ public class SymbolTableTester {
 | 
				
			|||||||
        SymbolTable childTable = new SymbolTable(symbolTable);
 | 
					        SymbolTable childTable = new SymbolTable(symbolTable);
 | 
				
			||||||
        SymbolTable parentTable = childTable.getParent();
 | 
					        SymbolTable parentTable = childTable.getParent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertEquals(parentTable.get("symbol"), Symbol.T);
 | 
					        assertEquals(Symbol.T, parentTable.get("symbol"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ public final class SExpressionTypeAssertions {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static void assertNil(SExpression sExpression) {
 | 
					    public static void assertNil(SExpression sExpression) {
 | 
				
			||||||
        assertEquals(sExpression, Nil.getInstance());
 | 
					        assertEquals(Nil.getInstance(), sExpression);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertTrue(sExpression.atomp());
 | 
					        assertTrue(sExpression.atomp());
 | 
				
			||||||
        assertFalse(sExpression.consp());
 | 
					        assertFalse(sExpression.consp());
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user