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; + } + } + +}