diff --git a/src/environment/Environment.java b/src/environment/RuntimeEnvironment.java similarity index 86% rename from src/environment/Environment.java rename to src/environment/RuntimeEnvironment.java index 50b019b..83b9b21 100644 --- a/src/environment/Environment.java +++ b/src/environment/RuntimeEnvironment.java @@ -2,11 +2,11 @@ package environment; import java.io.*; -public class Environment { +public class RuntimeEnvironment { - private static Environment uniqueInstance = new Environment(); + private static RuntimeEnvironment uniqueInstance = new RuntimeEnvironment(); - public static Environment getInstance() { + public static RuntimeEnvironment getInstance() { return uniqueInstance; } @@ -16,7 +16,7 @@ public class Environment { private Runnable terminationFunction; private Runnable errorTerminationFunction; - private Environment() {} + private RuntimeEnvironment() {} public void setInput(InputStream input) { this.input = input; diff --git a/src/error/ErrorManager.java b/src/error/ErrorManager.java index d1841d2..da713e4 100644 --- a/src/error/ErrorManager.java +++ b/src/error/ErrorManager.java @@ -2,7 +2,7 @@ package error; import java.text.MessageFormat; -import environment.Environment; +import environment.RuntimeEnvironment; /** * Prints error messages and potentially terminates the application. @@ -15,10 +15,10 @@ public class ErrorManager { private static final String ANSI_RED = "\u001B[31m"; private static final String ANSI_PURPLE = "\u001B[35m"; - private Environment environment; + private RuntimeEnvironment environment; public ErrorManager() { - this.environment = Environment.getInstance(); + this.environment = RuntimeEnvironment.getInstance(); } public void generateError(LispException lispException) { diff --git a/src/function/builtin/EXIT.java b/src/function/builtin/EXIT.java index 942c6f0..8b225ab 100644 --- a/src/function/builtin/EXIT.java +++ b/src/function/builtin/EXIT.java @@ -1,18 +1,18 @@ package function.builtin; -import environment.Environment; +import environment.RuntimeEnvironment; import function.*; import sexpression.*; public class EXIT extends LispFunction { private ArgumentValidator argumentValidator; - private Environment environment; + private RuntimeEnvironment environment; public EXIT() { this.argumentValidator = new ArgumentValidator("EXIT"); this.argumentValidator.setMaximumNumberOfArguments(0); - this.environment = Environment.getInstance(); + this.environment = RuntimeEnvironment.getInstance(); } public SExpression call(Cons argumentList) { diff --git a/src/function/builtin/LOAD.java b/src/function/builtin/LOAD.java index 29d9c50..205a8bb 100644 --- a/src/function/builtin/LOAD.java +++ b/src/function/builtin/LOAD.java @@ -3,7 +3,7 @@ package function.builtin; import java.io.*; import java.text.MessageFormat; -import environment.Environment; +import environment.RuntimeEnvironment; import function.*; import parser.LispParser; import sexpression.*; @@ -11,13 +11,13 @@ import sexpression.*; public class LOAD extends LispFunction { private ArgumentValidator argumentValidator; - private Environment environment; + private RuntimeEnvironment environment; public LOAD() { this.argumentValidator = new ArgumentValidator("LOAD"); this.argumentValidator.setExactNumberOfArguments(1); this.argumentValidator.setEveryArgumentExpectedType(LispString.class); - this.environment = Environment.getInstance(); + this.environment = RuntimeEnvironment.getInstance(); } public SExpression call(Cons argumentList) { diff --git a/src/function/builtin/PRINT.java b/src/function/builtin/PRINT.java index 920a8fa..2ae1262 100644 --- a/src/function/builtin/PRINT.java +++ b/src/function/builtin/PRINT.java @@ -1,18 +1,18 @@ package function.builtin; -import environment.Environment; +import environment.RuntimeEnvironment; import function.*; import sexpression.*; public class PRINT extends LispFunction { private ArgumentValidator argumentValidator; - private Environment environment; + private RuntimeEnvironment environment; public PRINT() { this.argumentValidator = new ArgumentValidator("PRINT"); this.argumentValidator.setExactNumberOfArguments(1); - this.environment = Environment.getInstance(); + this.environment = RuntimeEnvironment.getInstance(); } public SExpression call(Cons argumentList) { diff --git a/src/function/builtin/special/DEFUN.java b/src/function/builtin/special/DEFUN.java index 23b0b2f..1fa85fa 100644 --- a/src/function/builtin/special/DEFUN.java +++ b/src/function/builtin/special/DEFUN.java @@ -2,7 +2,7 @@ package function.builtin.special; import java.text.MessageFormat; -import environment.Environment; +import environment.RuntimeEnvironment; import function.*; import function.builtin.cons.LIST; import sexpression.*; @@ -13,7 +13,7 @@ public class DEFUN extends LispFunction { private ArgumentValidator argumentValidator; private ArgumentValidator lambdaListIsListValidator; private ArgumentValidator lambdaListValidator; - private Environment environment; + private RuntimeEnvironment environment; public DEFUN() { this.argumentValidator = new ArgumentValidator("DEFUN"); @@ -26,7 +26,7 @@ public class DEFUN extends LispFunction { this.lambdaListValidator = new ArgumentValidator("DEFUN|parameter|"); this.lambdaListValidator.setEveryArgumentExpectedType(Symbol.class); - this.environment = Environment.getInstance(); + this.environment = RuntimeEnvironment.getInstance(); } public SExpression call(Cons argumentList) { diff --git a/src/interpreter/LispInterpreter.java b/src/interpreter/LispInterpreter.java index 5833a2f..8a7de2d 100644 --- a/src/interpreter/LispInterpreter.java +++ b/src/interpreter/LispInterpreter.java @@ -3,7 +3,7 @@ package interpreter; import java.io.*; import java.text.MessageFormat; -import environment.Environment; +import environment.RuntimeEnvironment; import error.*; import function.builtin.EVAL; import parser.LispParser; @@ -16,16 +16,16 @@ public class LispInterpreter { private LispParser parser; private ErrorManager errorManager; - protected Environment environment; + protected RuntimeEnvironment environment; public LispInterpreter() { - this.environment = Environment.getInstance(); + this.environment = RuntimeEnvironment.getInstance(); this.errorManager = new ErrorManager(); this.parser = new LispParser(this.environment.getInput(), this.environment.getInputName()); } public LispInterpreter(String fileName) { - this.environment = Environment.getInstance(); + this.environment = RuntimeEnvironment.getInstance(); this.errorManager = new ErrorManager(); try { diff --git a/src/interpreter/LispInterpreterBuilderImpl.java b/src/interpreter/LispInterpreterBuilderImpl.java index 89c05fe..bc8eb46 100644 --- a/src/interpreter/LispInterpreterBuilderImpl.java +++ b/src/interpreter/LispInterpreterBuilderImpl.java @@ -2,47 +2,60 @@ package interpreter; import java.io.*; -import environment.Environment; +import environment.RuntimeEnvironment; +import error.*; public class LispInterpreterBuilderImpl implements LispInterpreterBuilder { + + private static LispInterpreterBuilder uniqueInstance = new LispInterpreterBuilderImpl(); + + public static LispInterpreterBuilder getInstance() { + return uniqueInstance; + } - private Environment environment; + private InputStream inputStream; + private PrintStream outputStream; + private PrintStream errorOutputStream; + private Runnable terminationFunction; + private Runnable errorTerminationFunction; + private RuntimeEnvironment environment; private String fileName; private boolean isInteractive; + private boolean isBuilt; - public LispInterpreterBuilderImpl() { - this.environment = Environment.getInstance(); + private LispInterpreterBuilderImpl() { + this.environment = RuntimeEnvironment.getInstance(); this.fileName = ""; this.isInteractive = true; + this.isBuilt = false; } @Override public void setInput(InputStream inputStream) { - this.environment.setInput(inputStream); + this.inputStream = inputStream; } @Override public void setOutput(PrintStream outputStream) { - this.environment.setOutput(outputStream); + this.outputStream = outputStream; } @Override public void setErrorOutput(PrintStream errorOutputStream) { - this.environment.setErrorOutput(errorOutputStream); + this.errorOutputStream = errorOutputStream; } @Override public void setTerminationFunction(Runnable terminationFunction) { - this.environment.setTerminationFunction(terminationFunction); + this.terminationFunction = terminationFunction; } @Override public void setErrorTerminationFunction(Runnable errorTerminationFunction) { - this.environment.setErrorTerminationFunction(errorTerminationFunction); + this.errorTerminationFunction = errorTerminationFunction; } - @Override public void useFile(String fileName) { this.fileName = fileName; @@ -51,10 +64,40 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder { @Override public LispInterpreter build() { - if (isInteractive) - return new InteractiveLispInterpreter(); + if (!isBuilt) + return buildInterpreter(); else - return new LispInterpreter(fileName); + throw new InterpreterAlreadyBuiltException(); + } + + private LispInterpreter buildInterpreter() { + environment.setInput(inputStream); + environment.setOutput(outputStream); + environment.setErrorOutput(errorOutputStream); + environment.setTerminationFunction(terminationFunction); + environment.setErrorTerminationFunction(errorTerminationFunction); + + LispInterpreter lispInterpreter = isInteractive ? new InteractiveLispInterpreter() + : new LispInterpreter(fileName); + + isBuilt = true; + + return lispInterpreter; + } + + public class InterpreterAlreadyBuiltException extends LispException { + + private static final long serialVersionUID = 1L; + + @Override + public int getSeverity() { + return ErrorManager.CRITICAL_LEVEL; + } + + @Override + public String getMessage() { + return "Refusing to build more than one interpreter."; + } } } diff --git a/src/main/LispMain.java b/src/main/LispMain.java index c6f123b..fa930bf 100644 --- a/src/main/LispMain.java +++ b/src/main/LispMain.java @@ -12,7 +12,7 @@ public class LispMain { } private static LispInterpreter buildInterpreter(String[] args) { - LispInterpreterBuilder builder = new LispInterpreterBuilderImpl(); + LispInterpreterBuilder builder = LispInterpreterBuilderImpl.getInstance(); builder.setInput(System.in); builder.setOutput(System.out); builder.setErrorOutput(System.err); diff --git a/test/error/ErrorManagerTester.java b/test/error/ErrorManagerTester.java index 3f6f5b3..a28e294 100644 --- a/test/error/ErrorManagerTester.java +++ b/test/error/ErrorManagerTester.java @@ -7,7 +7,7 @@ import java.util.*; import org.junit.*; -import environment.Environment; +import environment.RuntimeEnvironment; public class ErrorManagerTester { @@ -18,8 +18,8 @@ public class ErrorManagerTester { private ByteArrayOutputStream outputStream; private ErrorManager createErrorManagerWithIndicators() { - Environment.getInstance().setErrorTerminationFunction(() -> indicatorSet.add(TERMINATED)); - Environment.getInstance().setErrorOutput(new PrintStream(outputStream)); + RuntimeEnvironment.getInstance().setErrorTerminationFunction(() -> indicatorSet.add(TERMINATED)); + RuntimeEnvironment.getInstance().setErrorOutput(new PrintStream(outputStream)); return new ErrorManager(); } diff --git a/test/function/builtin/EXITTester.java b/test/function/builtin/EXITTester.java index f0e8d0a..4964402 100644 --- a/test/function/builtin/EXITTester.java +++ b/test/function/builtin/EXITTester.java @@ -7,7 +7,7 @@ import java.util.*; import org.junit.*; -import environment.Environment; +import environment.RuntimeEnvironment; import function.ArgumentValidator.TooManyArgumentsException; public class EXITTester { @@ -26,7 +26,7 @@ public class EXITTester { @Before public void setUp() { indicatorSet = new HashSet<>(); - Environment.getInstance().setTerminationFunction(() -> indicatorSet.add(TERMINATED)); + RuntimeEnvironment.getInstance().setTerminationFunction(() -> indicatorSet.add(TERMINATED)); } @Test diff --git a/test/function/builtin/LOADTester.java b/test/function/builtin/LOADTester.java index beee965..8ed723c 100644 --- a/test/function/builtin/LOADTester.java +++ b/test/function/builtin/LOADTester.java @@ -7,7 +7,7 @@ import java.io.*; import org.junit.*; -import environment.Environment; +import environment.RuntimeEnvironment; import function.ArgumentValidator.*; import sexpression.*; @@ -26,7 +26,7 @@ public class LOADTester { @Before public void setUp() { this.outputStream = new ByteArrayOutputStream(); - Environment.getInstance().setErrorOutput(new PrintStream(outputStream)); + RuntimeEnvironment.getInstance().setErrorOutput(new PrintStream(outputStream)); } @Test diff --git a/test/function/builtin/PRINTTester.java b/test/function/builtin/PRINTTester.java index fb44ee5..dc7baea 100644 --- a/test/function/builtin/PRINTTester.java +++ b/test/function/builtin/PRINTTester.java @@ -8,7 +8,7 @@ import java.text.MessageFormat; import org.junit.*; -import environment.Environment; +import environment.RuntimeEnvironment; import function.ArgumentValidator.*; public class PRINTTester { @@ -22,7 +22,7 @@ public class PRINTTester { @Before public void setUp() { this.outputStream = new ByteArrayOutputStream(); - Environment.getInstance().setOutput(new PrintStream(outputStream)); + RuntimeEnvironment.getInstance().setOutput(new PrintStream(outputStream)); } @Test diff --git a/test/function/builtin/special/DEFUNTester.java b/test/function/builtin/special/DEFUNTester.java index d23f6a3..21ab446 100644 --- a/test/function/builtin/special/DEFUNTester.java +++ b/test/function/builtin/special/DEFUNTester.java @@ -7,7 +7,7 @@ import java.io.*; import org.junit.*; -import environment.Environment; +import environment.RuntimeEnvironment; import function.ArgumentValidator.*; import table.FunctionTable; @@ -22,7 +22,7 @@ public class DEFUNTester { @Before public void setUp() { this.outputStream = new ByteArrayOutputStream(); - Environment.getInstance().setOutput(new PrintStream(outputStream)); + RuntimeEnvironment.getInstance().setOutput(new PrintStream(outputStream)); FunctionTable.reset(); }