Refactored the interpreter and updated the build file

This commit is contained in:
Mike Cifelli 2016-12-17 10:19:18 -05:00
parent 064f905045
commit 5f2c3dc469
5 changed files with 177 additions and 143 deletions

View File

@ -5,14 +5,11 @@
<property name="build.dir" value="build" /> <property name="build.dir" value="build" />
<property name="classes.dir" value="${build.dir}/classes" /> <property name="classes.dir" value="${build.dir}/classes" />
<property name="jar.dir" value="jar" /> <property name="jar.dir" value="jar" />
<property name="doc.dir" value="doc" />
<property name="test.dir" value="test" />
<property name="jar-file" value="${jar.dir}/LispInterpreter.jar" /> <property name="jar-file" value="${jar.dir}/LispInterpreter.jar" />
<property name="main-class" value="main.LispInterpreter" /> <property name="main-class" value="main.LispMain" />
<target name="clean"> <target name="clean">
<delete dir="${build.dir}" /> <delete dir="${build.dir}" />
<delete dir="${doc.dir}" />
<delete dir="${jar.dir}" /> <delete dir="${jar.dir}" />
</target> </target>
@ -31,18 +28,5 @@
</jar> </jar>
</target> </target>
<target name="javadoc">
<mkdir dir="${doc.dir}" />
<javadoc destdir="${doc.dir}">
<fileset dir="${src.dir}"
includes="scanner/*.java,
parser/*.java,
eval/*.java,
error/*.java,
main/*.java" />
<tag name="postcondition" description="Postcondition:" />
</javadoc>
</target>
<target name="clean-jar" depends="clean, jar" /> <target name="clean-jar" depends="clean, jar" />
</project> </project>

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}
}

58
src/main/LispMain.java Normal file
View File

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