Refactored the interpreter and updated the build file
This commit is contained in:
parent
064f905045
commit
5f2c3dc469
18
build.xml
18
build.xml
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue