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="classes.dir" value="${build.dir}/classes" />
|
||||
<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="main-class" value="main.LispInterpreter" />
|
||||
<property name="main-class" value="main.LispMain" />
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${build.dir}" />
|
||||
<delete dir="${doc.dir}" />
|
||||
<delete dir="${jar.dir}" />
|
||||
</target>
|
||||
|
||||
|
@ -31,18 +28,5 @@
|
|||
</jar>
|
||||
</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" />
|
||||
</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