diff --git a/build.xml b/build.xml
index d8fde68..39aa7fc 100644
--- a/build.xml
+++ b/build.xml
@@ -5,14 +5,11 @@
-
-
-
+
-
@@ -31,18 +28,5 @@
-
-
-
-
-
-
-
-
diff --git a/src/interpreter/InteractiveLispInterpreter.java b/src/interpreter/InteractiveLispInterpreter.java
new file mode 100644
index 0000000..4f2f2d9
--- /dev/null
+++ b/src/interpreter/InteractiveLispInterpreter.java
@@ -0,0 +1,36 @@
+package interpreter;
+
+import java.io.*;
+
+import error.ErrorManager;
+
+public class InteractiveLispInterpreter extends LispInterpreter {
+
+ private static final String GREETING = "SUNY Potsdam Lisp Interpreter - Version 4.4.3";
+ private static final String PROMPT = "~ ";
+
+ public InteractiveLispInterpreter(InputStream inputStream, ErrorManager errorManager, PrintStream outputStream) {
+ super(inputStream, errorManager, outputStream);
+ }
+
+ protected void printGreeting() {
+ outputStream.println(GREETING);
+ outputStream.println();
+ }
+
+ protected void displayPrompt() {
+ outputStream.print(PROMPT);
+ }
+
+ protected void erasePrompt() {
+ for (int i = 0; i < PROMPT.length(); i++) {
+ outputStream.print("\b");
+ }
+ }
+
+ protected void printFarewell() {
+ outputStream.println();
+ outputStream.println();
+ }
+
+}
diff --git a/src/interpreter/LispInterpreter.java b/src/interpreter/LispInterpreter.java
new file mode 100644
index 0000000..edef39f
--- /dev/null
+++ b/src/interpreter/LispInterpreter.java
@@ -0,0 +1,82 @@
+package interpreter;
+
+import java.io.*;
+import java.text.MessageFormat;
+
+import error.*;
+import eval.EVAL;
+import parser.LispParser;
+import sexpression.SExpression;
+
+public class LispInterpreter {
+
+ public static final String ANSI_RESET = "\u001B[0m";
+ public static final String ANSI_GREEN = "\u001B[32m";
+
+ private LispParser parser;
+ private ErrorManager errorManager;
+ protected PrintStream outputStream;
+
+ public LispInterpreter(InputStream inputStream, ErrorManager errorManager, PrintStream outputStream) {
+ this.errorManager = errorManager;
+ this.parser = new LispParser(inputStream, inputStream.toString());
+ this.outputStream = outputStream;
+ }
+
+ public void interpret() {
+ printGreeting();
+
+ for (displayPrompt(); !parser.isEof(); displayPrompt())
+ printValueOfNextSExpression();
+
+ printFarewell();
+ }
+
+ protected void printGreeting() {}
+
+ protected void displayPrompt() {}
+
+ private void printValueOfNextSExpression() {
+ try {
+ printValueOfNextSExpressionWithException();
+ } catch (LispException e) {
+ erasePrompt();
+ errorManager.generateError(e);
+ } catch (RuntimeException e) {
+ erasePrompt();
+ errorManager.generateError(convertToLispException(e));
+ }
+ }
+
+ private void printValueOfNextSExpressionWithException() {
+ SExpression sExpression = parser.getNextSExpression();
+ String result = MessageFormat.format("{0}{1}{2}", ANSI_GREEN, EVAL.eval(sExpression), ANSI_RESET);
+
+ erasePrompt();
+ outputStream.println(result);
+ }
+
+ protected void erasePrompt() {}
+
+ private LispException convertToLispException(RuntimeException e) {
+ return new LispException() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public int getSeverity() {
+ return 0;
+ }
+
+ @Override
+ public String getMessage() {
+ return e.getMessage();
+ }
+ };
+ }
+
+ protected void printFarewell() {
+ outputStream.println();
+ }
+
+}
diff --git a/src/main/LispInterpreter.java b/src/main/LispInterpreter.java
deleted file mode 100644
index e35df95..0000000
--- a/src/main/LispInterpreter.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package main;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.text.MessageFormat;
-
-import error.ErrorManager;
-import error.LispException;
-import eval.EVAL;
-import parser.LispParser;
-import sexpression.SExpression;
-
-/**
- * This is an interpreter for the Lisp programming language. It takes the name of a file as a
- * command-line argument, evaluates the s-expressions found in the file and then prints the results
- * to the console. If no file name is provided at the command-line, this program will read from
- * standard input.
- */
-public class LispInterpreter {
-
- private static final String GREETING = "SUNY Potsdam Lisp Interpreter - Version 4.4.3";
- private static final String PROMPT = "~ ";
-
- public static final String ANSI_RESET = "\u001B[0m";
- public static final String ANSI_GREEN = "\u001B[32m";
-
- /**
- * Evaluate the s-expressions found in the file given as a command-line argument and print the
- * results to the console. If no file name was given, retrieve the s-expressions from standard
- * input.
- */
- public static void main(String[] args) {
- LispParser parser = null;
- ErrorManager errorManager = new ErrorManager(new TerminateInterpreter(), System.out::print);
- boolean interactive = false;
-
- if (args.length > 0) {
- // a file name was given at the command-line, attempt to create a
- // 'LispParser' on it
- try {
- parser = new LispParser(new FileInputStream(args[0]), args[0]);
- } catch (FileNotFoundException e) {
- errorManager.generateError(new LispException() {
-
- private static final long serialVersionUID = 1L;
-
- @Override
- public int getSeverity() {
- return ErrorManager.CRITICAL_LEVEL;
- }
-
- @Override
- public String getMessage() {
- return e.getMessage();
- }
- });
- }
- } else {
- // no file name was given, create a 'LispParser' on standard input
- parser = new LispParser(System.in, "System.in");
- interactive = true;
-
- System.out.println(GREETING);
- System.out.println();
- System.out.print(PROMPT);
- }
-
- while (!parser.isEof()) {
- try {
- SExpression sexpr = parser.getNextSExpression();
- String result = MessageFormat.format("{0}{1}{2}", ANSI_GREEN, EVAL.eval(sexpr), ANSI_RESET);
-
- LispInterpreter.erasePrompt(interactive);
- System.out.println(result);
- } catch (LispException e) {
- LispInterpreter.erasePrompt(interactive);
- errorManager.generateError(e);
- } catch (RuntimeException e) {
- LispInterpreter.erasePrompt(interactive);
- errorManager.generateError(new LispException() {
-
- private static final long serialVersionUID = 1L;
-
- @Override
- public int getSeverity() {
- return 0;
- }
-
- @Override
- public String getMessage() {
- return e.getMessage();
- }
- });
- }
-
- if (interactive) {
- System.out.print(PROMPT);
- }
- }
-
- System.out.println();
- }
-
- private static void erasePrompt(boolean interactive) {
- if (interactive) {
- for (int i = 0; i < PROMPT.length(); i++) {
- System.out.print("\b");
- }
- }
- }
-
- private static class TerminateInterpreter implements Runnable {
-
- @Override
- public void run() {
- System.exit(1);
- }
- }
-
-}
diff --git a/src/main/LispMain.java b/src/main/LispMain.java
new file mode 100644
index 0000000..3f998c9
--- /dev/null
+++ b/src/main/LispMain.java
@@ -0,0 +1,58 @@
+package main;
+
+import java.io.*;
+
+import error.*;
+import interpreter.*;
+
+public class LispMain {
+
+ private LispMain() {}
+
+ public static void main(String[] args) {
+ LispInterpreter interpreter = null;
+ ErrorManager errorManager = new ErrorManager(new TerminateInterpreter(), System.err::print);
+
+ if (args.length > 0) {
+ String fileName = args[0];
+
+ try {
+ interpreter = new LispInterpreter(new FileInputStream(fileName), errorManager, System.out);
+ } catch (FileNotFoundException e) {
+ errorManager.generateError(new LispFileNotFoundException(e));
+ }
+ } else
+ interpreter = new InteractiveLispInterpreter(System.in, errorManager, System.out);
+
+ interpreter.interpret();
+ }
+
+ private static class TerminateInterpreter implements Runnable {
+
+ @Override
+ public void run() {
+ System.exit(1);
+ }
+ }
+
+ public static class LispFileNotFoundException extends LispException {
+
+ private static final long serialVersionUID = 1L;
+ private String message;
+
+ public LispFileNotFoundException(FileNotFoundException e) {
+ this.message = e.getMessage();
+ }
+
+ @Override
+ public int getSeverity() {
+ return ErrorManager.CRITICAL_LEVEL;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+ }
+
+}