diff --git a/.classpath b/.classpath
index 1938c4d..b52a479 100644
--- a/.classpath
+++ b/.classpath
@@ -1,10 +1,12 @@
+
+
diff --git a/.project b/.project
index d1cb933..883a7f1 100644
--- a/.project
+++ b/.project
@@ -15,6 +15,19 @@
+
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/Ant_Builder.launch
+
+
+ incclean
+ true
+
+
+
org.eclipse.wst.common.project.facet.core.nature
diff --git a/build.xml b/build.xml
index 5756cd6..a28a61a 100644
--- a/build.xml
+++ b/build.xml
@@ -1,11 +1,12 @@
-
+
+
@@ -16,11 +17,8 @@
-
+ includeantruntime="false" />
diff --git a/error/ErrorManager.java b/error/ErrorManager.java
deleted file mode 100644
index 255c61d..0000000
--- a/error/ErrorManager.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter Phase 1 - Lexical Analysis
- */
-
-package error;
-
-import java.text.MessageFormat;
-
-/**
- * ErrorManager
is an error handling class for a Lisp interpreter.
- */
-public class ErrorManager {
-
- /**
- * The lowest "criticality" level of an error that will cause the currently
- * running program to terminate.
- */
- public static final int CRITICAL_LEVEL = 3;
-
- public static final String ANSI_RESET = "\u001B[0m";
- public static final String ANSI_RED = "\u001B[31m";
- public static final String ANSI_YELLOW = "\u001B[33m";
- public static final String ANSI_PURPLE = "\u001B[35m";
-
- /**
- * Prints out the specified error message to the console and decides
- * whether or not to terminate the currently running program.
- *
- * @param message
- * the error message
- * @param level
- * the "criticality" level of the error
- * @postcondition
- * If level >= CRITICAL_LEVEL
the currently running
- * program has been terminated.
- */
- public static void generateError(String message, int level) {
- String color = (level >= CRITICAL_LEVEL) ? ANSI_PURPLE : ANSI_RED;
- String formattedMessage = MessageFormat.format("{0}error: {1}{2}", color, message, ANSI_RESET);
-
- System.out.println(formattedMessage);
-
- if (level >= CRITICAL_LEVEL) {
- System.exit(1);
- }
- }
-
-}
diff --git a/error/package.html b/error/package.html
deleted file mode 100644
index b8e7489..0000000
--- a/error/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Provides a class for managing errors in the Lisp Interpreter.
-
diff --git a/eval/APPLY.java b/eval/APPLY.java
deleted file mode 100644
index f7fa819..0000000
--- a/eval/APPLY.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * APPLY
represents the APPLY function in Lisp.
- */
-public class APPLY extends LispFunction {
-
- /**
- * Call APPLY with the specified argument list.
- *
- * @param argList
- * the list of arguments to be sent to APPLY (MUST BE A PROPER LIST)
- * @return
- * the result of evaluating APPLY on argList
- */
- public static SExpression apply(Cons argList) {
- return new APPLY().call(argList);
- }
-
- // The number of arguments that APPLY takes.
- private static final int NUM_ARGS = 2;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to APPLY
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("APPLY"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to APPLY: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression car = argList.getCar(); // function name
- Cons cdr = (Cons) argList.getCdr();
- SExpression cadr = cdr.getCar(); // argument list
-
- // make sure the second argument is a list
- if (cadr.listp()) {
- LispFunction function = EVAL.lookupFunction(car.toString());
-
- if (function == null) {
- // check if the car of the list is a lambda expression
- if (car.functionp()) {
- function = ((LambdaExpression) car).getFunction();
- } else if (LAMBDA.isLambdaExpression(car)) {
- Cons lexpr = (Cons) car;
-
- function = LAMBDA.createFunction(lexpr);
- } else {
- throw new RuntimeException("undefined function " + car);
- }
- }
-
- // apply the given function to the given argument list
- return function.call((Cons) cadr);
- }
-
- // the second argument is not a list
- throw new RuntimeException("APPLY: " + cadr + " is not a list");
- }
-
-}
diff --git a/eval/ATOM.java b/eval/ATOM.java
deleted file mode 100644
index fbee068..0000000
--- a/eval/ATOM.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * ATOM
represents the ATOM function in Lisp.
- */
-public class ATOM extends LispFunction {
-
- // The number of arguments that ATOM takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to ATOM
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("ATOM"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to ATOM: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression arg = argList.getCar();
-
- return (arg.atomp() ? Symbol.T : Nil.getUniqueInstance());
- }
-
-}
diff --git a/eval/CAR.java b/eval/CAR.java
deleted file mode 100644
index 3b75078..0000000
--- a/eval/CAR.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * CAR
represents the CAR function in Lisp.
- */
-public class CAR extends LispFunction {
-
- // The number of arguments that CAR takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to CAR
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("CAR"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to CAR: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression argCar = argList.getCar();
-
- // make sure that the argument is a list
- if (argCar.listp()) {
- Cons arg = (Cons) argCar;
-
- return arg.getCar();
- }
-
- // the argument is not a list
- throw new RuntimeException("CAR: " + argCar + " is not a list");
- }
-
-}
diff --git a/eval/CDR.java b/eval/CDR.java
deleted file mode 100644
index 0cc281e..0000000
--- a/eval/CDR.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * CDR
represents the CDR function in Lisp.
- */
-public class CDR extends LispFunction {
-
- // The number of arguments that CDR takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to CDR
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("CDR"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to CDR: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression argCar = argList.getCar();
-
- // make sure that the argument is a list
- if (argCar.listp()) {
- Cons arg = (Cons) argCar;
-
- return arg.getCdr();
- }
-
- // the argument is not a list
- throw new RuntimeException("CDR: " + argCar + " is not a list");
- }
-
-}
diff --git a/eval/COND.java b/eval/COND.java
deleted file mode 100644
index 9bd4e79..0000000
--- a/eval/COND.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * COND
represents the COND form in Lisp.
- */
-public class COND extends LispFunction {
-
- public SExpression call(Cons argList) {
- if (argList.nullp()) {
- // return NIL if there are were no arguments passed to COND
- return Nil.getUniqueInstance();
- }
-
- SExpression argCar = argList.getCar(); // first clause
- Cons argCdr = (Cons) argList.getCdr(); // list of remaining clauses
-
- // make sure the first clause is a list and is not NIL
- if (argCar.consp()) {
- Cons clause = (Cons) argCar;
- SExpression test = EVAL.eval(clause.getCar());
-
- if (test != Nil.getUniqueInstance()) {
- // the car of this clause is true, so we evaluate its cdr
-
- SExpression cdr = clause.getCdr();
- SExpression retval = test;
-
- // evaluate all the S-expressions in the cdr of the clause
- while (cdr.consp()) {
- retval = EVAL.eval(((Cons) cdr).getCar());
- cdr = ((Cons) cdr).getCdr();
- }
-
- // return the value of the last S-expression evaluated
- return retval;
- }
-
- // the car of this clause is false, so we test any remaining
- // clauses
-
- // check if the list of remaining clauses is a list and is not NIL
- if (argCdr.consp()) {
- return call(argCdr);
- }
-
- // there are no remaining clauses, so we return NIL
- return Nil.getUniqueInstance();
- }
-
- throw new RuntimeException("COND: clause " + argCar +
- " should be a list");
- }
-
- /**
- * Determine if the arguments passed to this Lisp function should be
- * evaluated.
- *
- * @return
- * false
- */
- public boolean evaluateArguments() {
- return false;
- }
-
-}
diff --git a/eval/CONS.java b/eval/CONS.java
deleted file mode 100644
index db967a7..0000000
--- a/eval/CONS.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * CONS
represents the CONS function in Lisp.
- */
-public class CONS extends LispFunction {
-
- // The number of arguments that CONS takes.
- private static final int NUM_ARGS = 2;
-
- public Cons call(Cons argList) {
- // retrieve the number of arguments passed to CONS
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("CONS"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to CONS: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- // the car of the CONS cell we are going to create
- SExpression argOne = argList.getCar();
-
- Cons cdr = (Cons) argList.getCdr();
-
- // the cdr of the CONS cell we are going to create
- SExpression argTwo = cdr.getCar();
-
- return new Cons(argOne, argTwo);
- }
-
-}
diff --git a/eval/DEFUN.java b/eval/DEFUN.java
deleted file mode 100644
index c435737..0000000
--- a/eval/DEFUN.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-import java.util.HashMap;
-
-/**
- * DEFUN
represents the DEFUN form in Lisp.
- */
-public class DEFUN extends LispFunction {
-
- // The minimum number of arguments that DEFUN takes.
- private static final int MIN_ARGS = 3;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to DEFUN
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength < MIN_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("DEFUN"), argList);
- String errMsg = "too few arguments given to DEFUN: " +
- originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression name = argList.getCar(); // name of the function
-
- // make sure the function name is a symbol
- if (! name.symbolp()) {
- throw new RuntimeException("DEFUN: " + name + " is not a symbol");
- }
-
- Cons cdr = (Cons) argList.getCdr();
- SExpression cadr = cdr.getCar();
-
- // make sure the list of arguments (lambda list) is a proper list
- if (! cadr.listp()) {
- throw new RuntimeException("DEFUN: " + cadr + " is not a list");
- } else if (EVAL.isDotted((Cons) cadr)) {
- throw new RuntimeException("DEFUN: " + cadr +
- " is not a proper list");
- }
-
- Cons lambdaList = (Cons) cadr; // lambda list of the function
-
- // list of S-expressions making up the body of the function
- Cons body = (Cons) cdr.getCdr();
-
- HashMap functionTable = EVAL.getFunctionTable();
-
- // give a warning if this function has already been defined
- if (functionTable.containsKey(name.toString())) {
- System.out.println("WARNING: redefining function " +
- name.toString());
- }
-
- // place the function in the function table
- functionTable.put(name.toString(),
- new UDFunction(name.toString(), lambdaList, body));
-
- return name;
- }
-
- /**
- * Determine if the arguments passed to this Lisp function should be
- * evaluated.
- *
- * @return
- * false
- */
- public boolean evaluateArguments() {
- return false;
- }
-
-}
diff --git a/eval/DIVIDE.java b/eval/DIVIDE.java
deleted file mode 100644
index 0794f57..0000000
--- a/eval/DIVIDE.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * DIVIDE
represents the '/' function in Lisp.
- */
-public class DIVIDE extends LispFunction {
-
- public SExpression call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- Cons originalSExpr = new Cons(new Symbol("/"), argList);
-
- throw new RuntimeException("too few arguments given to /: " +
- originalSExpr);
- }
-
- SExpression argFirst = argList.getCar();
- Cons argRest = (Cons) argList.getCdr();
-
- // make sure that the first argument is a number
- if (argFirst.numberp()) {
- LispNumber num1 = (LispNumber) argFirst;
-
- if (argRest.nullp()) {
- // there is only one argument, so return the multiplicative
- // inverse of the number
- return new LispNumber(1 / num1.getValue());
- }
-
- SExpression argSecond = argRest.getCar();
-
- // make sure that the next argument is a number as well
- if (argSecond.numberp()) {
- LispNumber num2 = (LispNumber) argSecond;
- LispNumber quotient = new LispNumber(num1.getValue() /
- num2.getValue());
- SExpression argCddr = argRest.getCdr();
-
- if (argCddr.consp()) {
- return call(new Cons(quotient, argCddr));
- }
-
- return quotient;
- }
-
- throw new RuntimeException("/: " + argSecond + " is not a number");
- }
-
- throw new RuntimeException("/: " + argFirst + " is not a number");
- }
-
-}
diff --git a/eval/EQ.java b/eval/EQ.java
deleted file mode 100644
index 0227525..0000000
--- a/eval/EQ.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * EQ
represents the EQ function in Lisp.
- */
-public class EQ extends LispFunction {
-
- // The number of arguments that EQ takes.
- private static final int NUM_ARGS = 2;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to EQ
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("EQ"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to EQ: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression argOne = argList.getCar(); // first argument
- Cons cdr = (Cons) argList.getCdr();
- SExpression argTwo = cdr.getCar(); // second argumnet
-
- if (argOne.atomp() && argTwo.atomp()) {
- return ((argOne.toString().equals(argTwo.toString()))
- ? Symbol.T : Nil.getUniqueInstance());
- }
-
- return ((argOne == argTwo) ? Symbol.T : Nil.getUniqueInstance());
- }
-
-}
diff --git a/eval/EQUAL.java b/eval/EQUAL.java
deleted file mode 100644
index 0e4e02e..0000000
--- a/eval/EQUAL.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * EQUAL
represents the EQUAL function in Lisp.
- */
-public class EQUAL extends LispFunction {
-
- // The number of arguments that EQUAL takes.
- private static final int NUM_ARGS = 2;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to EQUAL
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("EQUAL"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to EQUAL: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression argOne = argList.getCar(); // first argument
- Cons cdr = (Cons) argList.getCdr();
- SExpression argTwo = cdr.getCar(); // second argumnet
-
- if (argOne.consp() && argTwo.consp()) {
- Cons listOne = (Cons) argOne;
- Cons listTwo = (Cons) argTwo;
- SExpression listOneCar = listOne.getCar();
- SExpression listTwoCar = listTwo.getCar();
- SExpression listOneCdr = listOne.getCdr();
- SExpression listTwoCdr = listTwo.getCdr();
-
- SExpression carEqual =
- call(new Cons(listOneCar, LIST.makeList(listTwoCar)));
- SExpression cdrEqual =
- call(new Cons(listOneCdr, LIST.makeList(listTwoCdr)));
-
- return (((carEqual == Symbol.T) && (cdrEqual == Symbol.T))
- ? Symbol.T : Nil.getUniqueInstance());
- }
-
- return ((argOne.toString().equals(argTwo.toString()))
- ? Symbol.T : Nil.getUniqueInstance());
- }
-
-}
diff --git a/eval/EQUALSP.java b/eval/EQUALSP.java
deleted file mode 100644
index 1c6fb65..0000000
--- a/eval/EQUALSP.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * EQUALSP
represents the '=' function in Lisp.
- */
-public class EQUALSP extends LispFunction {
-
- public SExpression call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- Cons originalSExpr = new Cons(new Symbol("="), argList);
-
- throw new RuntimeException("too few arguments given to =: " +
- originalSExpr);
- }
-
- SExpression firstArg = argList.getCar();
- Cons argRest = (Cons) argList.getCdr();
-
- // make sure that the first argument is a number
- if (firstArg.numberp()) {
- LispNumber num1 = (LispNumber) firstArg;
-
- if (argRest.nullp()) {
- return Symbol.T;
- }
-
- SExpression secondArg = argRest.getCar();
-
- // make sure that the second argument is a number as well
- if (secondArg.numberp()) {
- LispNumber num2 = (LispNumber) secondArg;
-
- if (num1.getValue() == num2.getValue()) {
- return call(argRest);
- }
-
- return Nil.getUniqueInstance();
- }
-
- throw new RuntimeException("=: " + secondArg + " is not a number");
- }
-
- throw new RuntimeException("=: " + firstArg + " is not a number");
- }
-
-}
diff --git a/eval/EVAL.java b/eval/EVAL.java
deleted file mode 100644
index 2eacfc2..0000000
--- a/eval/EVAL.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-import java.util.HashMap;
-
-/**
- * EVAL
represents the EVAL function in Lisp.
- */
-public class EVAL extends LispFunction {
-
- // A table to contain all the built-in and user-defined Lisp functions.
- private static HashMap functionTable =
- new HashMap();
-
- static {
- // place all of the built-in functions into the function table
- functionTable.put("*", new MULTIPLY());
- functionTable.put("+", new PLUS());
- functionTable.put("-", new MINUS());
- functionTable.put("/", new DIVIDE());
- functionTable.put("<", new LESSP());
- functionTable.put("=", new EQUALSP());
- functionTable.put(">", new GREATERP());
- functionTable.put("APPLY", new APPLY());
- functionTable.put("ATOM", new ATOM());
- functionTable.put("CAR", new CAR());
- functionTable.put("CDR", new CDR());
- functionTable.put("COND", new COND());
- functionTable.put("CONS", new CONS());
- functionTable.put("DEFUN", new DEFUN());
- functionTable.put("EQ", new EQ());
- functionTable.put("EQUAL", new EQUAL());
- functionTable.put("EVAL", new EVAL());
- functionTable.put("EXIT", new EXIT());
- functionTable.put("FIRST", new CAR());
- functionTable.put("FUNCALL", new FUNCALL());
- functionTable.put("GREATERP", new GREATERP());
- functionTable.put("LAMBDA", new LAMBDA());
- functionTable.put("LENGTH", new LENGTH());
- functionTable.put("LET", new LET());
- functionTable.put("LIST", new LIST());
- functionTable.put("LISTP", new LISTP());
- functionTable.put("LOAD", new LOAD());
- functionTable.put("NULL", new NULL());
- functionTable.put("PRINT", new PRINT());
- functionTable.put("QUOTE", new QUOTE());
- functionTable.put("REST", new CDR());
- functionTable.put("SETF", new SETF());
- functionTable.put("SYMBOL-FUNCTION", new SYMBOL_FUNCTION());
- }
-
- /**
- * Retrieve the function table.
- *
- * @return
- * the function table
- */
- public static HashMap getFunctionTable() {
- return functionTable;
- }
-
- /**
- * Look up a function by its name.
- *
- * @param functionName
- * the name of the function to look up
- * @return
- * the function with the name functionName
if it exists; null
- * otherwise
- */
- public static LispFunction lookupFunction(String functionName) {
- return functionTable.get(functionName);
- }
-
- /**
- * Look up a symbol's value using its name.
- *
- * @param symbolName
- * the name of the symbol to look up (must not be null)
- * @return
- * the value of symbolName
if it has one; null otherwise
- */
- public static SExpression lookupSymbol(String symbolName) {
- if (symbolName.equals("NIL")) {
- return Nil.getUniqueInstance();
- } else if (symbolName.equals("T")) {
- return Symbol.T;
- } else if (symbolName.startsWith(":")) {
- return new Symbol(symbolName);
- }
-
- return SETF.lookup(symbolName);
- }
-
- /**
- * Determine if the given list is dotted.
- *
- * @param list
- * the list to be tested (must not be null)
- * @return
- * true
if list
is dotted; false
- * otherwise
- */
- public static boolean isDotted(Cons list) {
- if (list.nullp()) {
- return false;
- }
-
- SExpression cdr = list.getCdr();
-
- if (cdr.listp()) {
- return isDotted((Cons) cdr);
- }
-
- // the cdr of 'list' is not a list, therefore it is dotted
- return true;
- }
-
- /**
- * Evaluate the given S-expression.
- *
- * @param sexpr
- * the S-expression to evaluate
- * @return
- * the value of sexpr
- */
- public static SExpression eval(SExpression sexpr) {
- Cons expList = LIST.makeList(sexpr);
- EVAL evalFunction = new EVAL();
-
- return evalFunction.call(expList);
- }
-
- // The number of arguments that EVAL takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to EVAL
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("EVAL"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to EVAL: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression arg = argList.getCar();
-
- if (arg.listp()) {
- if (arg.consp()) {
- return evaluateList((Cons) arg);
- }
-
- return arg; // 'arg' is NIL
- }
-
- if (arg.symbolp()) {
- SExpression symbolValue = lookupSymbol(arg.toString());
-
- if (symbolValue != null) {
- return symbolValue;
- }
-
- throw new RuntimeException("variable " + arg + " has no value");
- }
-
- return arg; // 'arg' is a NUMBER or a STRING
- }
-
- // Evaluate the specified list.
- //
- // Parameters: list - the list to evaluate
- // Returns: the value of 'list'
- // Precondition: 'list' must not be null.
- private SExpression evaluateList(Cons list) {
- SExpression car = list.getCar();
- SExpression cdr = list.getCdr();
-
- LispFunction function = lookupFunction(car.toString());
-
- if (function == null) {
- // check if the car of the list is a lambda expression
- if (car.functionp()) {
- function = ((LambdaExpression) car).getFunction();
- } else if (LAMBDA.isLambdaExpression(car)) {
- Cons lexpr = (Cons) car;
-
- function = LAMBDA.createFunction(lexpr);
- } else {
- throw new RuntimeException("undefined function " + car);
- }
- }
-
- // make sure the list of arguments for 'function' is a list
- if (cdr.listp()) {
- Cons args = (Cons) cdr;
-
- // make sure the list of arguments is not dotted
- if (isDotted(args)) {
- throw new RuntimeException("argument list given to " + car +
- " is dotted: " + list);
- }
-
- // determine if we should evaluate the arguments that will be
- // passed to 'function'
- if (function.evaluateArguments()) {
- args = evaluateArgList(args);
- }
-
- return function.call(args);
- }
-
- // the list of arguments is not a list!
- throw new RuntimeException("argument list given to " + car +
- " is dotted: " + list);
- }
-
- // Evaluate a list of arguments for a function.
- //
- // Parameters: arguments - a list of arguments for a function
- // Returns: a list consisting of the values of the S-expressions found in
- // 'arguments'
- // Precondition: 'arguments' must not be null.
- private Cons evaluateArgList(Cons arguments) {
- if (arguments.nullp()) {
- return Nil.getUniqueInstance();
- }
-
- SExpression car = eval(arguments.getCar());
- SExpression cdr = arguments.getCdr();
-
- if (cdr.listp()) {
- return new Cons(car, evaluateArgList((Cons) cdr));
- }
-
- // remove any parameters found after a dot (put here in case the check
- // for a dotted parameter list is not done prior to this call)
- return new Cons(car, Nil.getUniqueInstance());
- }
-
-}
diff --git a/eval/EXIT.java b/eval/EXIT.java
deleted file mode 100644
index 1def13f..0000000
--- a/eval/EXIT.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package eval;
-
-import parser.*;
-
-public class EXIT extends LispFunction {
-
- // The number of arguments that EXIT takes.
- private static final int NUM_ARGS = 0;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to EXIT
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength > NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("EXIT"), argList);
- String errMsg = "too many arguments given to EXIT: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- System.exit(0);
- return null;
- }
-
-}
diff --git a/eval/FUNCALL.java b/eval/FUNCALL.java
deleted file mode 100644
index 395dd88..0000000
--- a/eval/FUNCALL.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * FUNCALL
represents the FUNCALL function in Lisp.
- */
-public class FUNCALL extends LispFunction {
-
- public SExpression call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- Cons originalSExpr = new Cons(new Symbol("FUNCALL"), argList);
-
- throw new RuntimeException("too few arguments given to FUNCALL: " +
- originalSExpr);
- }
-
- SExpression cdr = argList.getCdr();
- Cons applyArgs = new Cons(argList.getCar(), LIST.makeList(cdr));
-
- return APPLY.apply(applyArgs);
- }
-
-}
diff --git a/eval/GREATERP.java b/eval/GREATERP.java
deleted file mode 100644
index 2dfc7aa..0000000
--- a/eval/GREATERP.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * GREATERP
represents the '>' function in Lisp.
- */
-public class GREATERP extends LispFunction {
-
- public SExpression call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- Cons originalSExpr = new Cons(new Symbol(">"), argList);
-
- throw new RuntimeException("too few arguments given to >: " +
- originalSExpr);
- }
-
- SExpression firstArg = argList.getCar();
- Cons argRest = (Cons) argList.getCdr();
-
- // make sure that the first argument is a number
- if (firstArg.numberp()) {
- LispNumber num1 = (LispNumber) firstArg;
-
- if (argRest.nullp()) {
- return Symbol.T;
- }
-
- SExpression secondArg = argRest.getCar();
-
- // make sure that the second argument is a number as well
- if (secondArg.numberp()) {
- LispNumber num2 = (LispNumber) secondArg;
-
- if (num1.getValue() > num2.getValue()) {
- return call(argRest);
- }
-
- return Nil.getUniqueInstance();
- }
-
- throw new RuntimeException(">: " + secondArg + " is not a number");
- }
-
- throw new RuntimeException(">: " + firstArg + " is not a number");
- }
-
-}
diff --git a/eval/LAMBDA.java b/eval/LAMBDA.java
deleted file mode 100644
index eaec557..0000000
--- a/eval/LAMBDA.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * LAMBDA
represents the LAMBDA form in Lisp.
- */
-public class LAMBDA extends LispFunction {
-
- /**
- * Determine if the given S-expression is a lambda expression.
- *
- * @param sexpr
- * the S-expression to test (must not be null)
- * @return
- * true
if sexpr
is a valid lambda expression;
- * false
otherwise
- */
- public static boolean isLambdaExpression(SExpression sexpr) {
- if (sexpr.consp()) {
- SExpression first = ((Cons) sexpr).getCar();
-
- return "LAMBDA".equals(first.toString());
- }
-
- return false;
- }
-
- /**
- * Create an internal representation of a user-defined function from the
- * specified lambda expression.
- *
- * @param lexpr
- * the lambda expression to create the function from (must not be null)
- * @return
- * an internal representation of a user-defined function created from
- * lexpr
- * @throws RuntimeException
- * Indicates that lexpr
is not a valid lambda expression.
- */
- public static UDFunction createFunction(Cons lexpr) {
- LAMBDA lambda = new LAMBDA();
- SExpression cdr = lexpr.getCdr();
-
- // make sure lexpr is a proper list
- if (! cdr.consp()) {
- throw new RuntimeException("invalid lambda expression");
- } else if (EVAL.isDotted((Cons) cdr)) {
- throw new RuntimeException("dotted lambda expression " + lexpr);
- }
-
- Cons rest = (Cons) cdr;
-
- return lambda.call(rest).getFunction();
- }
-
- // The minimum number of arguments that LAMBDA takes.
- private static final int MIN_ARGS = 2;
-
- public LambdaExpression call(Cons argList) {
- // retrieve the number of arguments passed to LAMBDA
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength < MIN_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("LAMBDA"), argList);
- String errMsg = "too few arguments given to LAMBDA: " +
- originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression car = argList.getCar();
-
- // make sure the list of arguments is a proper list
- if (! car.listp()) {
- throw new RuntimeException("LAMBDA: " + car + " is not a list");
- } else if (EVAL.isDotted((Cons) car)) {
- throw new RuntimeException("LAMBDA: " + car +
- " must be a proper list");
- }
-
- Cons lambdaList = (Cons) car;
- Cons body = (Cons) argList.getCdr();
- Cons lexpr = new Cons(new Symbol("LAMBDA"), argList);
- UDFunction function = new UDFunction(":LAMBDA", lambdaList, body);
-
- return new LambdaExpression(lexpr, function);
- }
-
- /**
- * Determine if the arguments passed to this Lisp function should be
- * evaluated.
- *
- * @return
- * false
- */
- public boolean evaluateArguments() {
- return false;
- }
-
-}
diff --git a/eval/LENGTH.java b/eval/LENGTH.java
deleted file mode 100644
index dcab21b..0000000
--- a/eval/LENGTH.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * LENGTH
represents the LENGTH function in Lisp.
- */
-public class LENGTH extends LispFunction {
-
- /**
- * Returns the length of the given list.
- *
- * @param list
- * the list to determine the length of
- * @return
- * the length of list
- */
- public static int getLength(Cons list) {
- LENGTH lengthFunction = new LENGTH();
- LispNumber length = lengthFunction.call(LIST.makeList(list));
-
- return length.getValue();
- }
-
- public LispNumber call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
-
- throw new RuntimeException("too few arguments given to LENGTH: " +
- originalSExpr);
- }
-
- SExpression argCar = argList.getCar();
- SExpression argCdr = argList.getCdr();
-
- // make sure we have received only one argument
- if (! argCdr.nullp()) {
- Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
-
- throw new RuntimeException("too many arguments given to LENGTH: " +
- originalSExpr);
- }
-
- // make sure that the argument is a list
- if (argCar.listp()) {
- Cons arg = (Cons) argCar;
-
- if (arg.nullp()) {
- return new LispNumber(0);
- }
-
- Cons cdr = LIST.makeList(arg.getCdr());
- LispNumber cdrLength = call(cdr);
-
- return new LispNumber(1 + cdrLength.getValue());
- }
-
- throw new RuntimeException("LENGTH: a proper list must not end with " +
- argCar);
- }
-
-}
diff --git a/eval/LESSP.java b/eval/LESSP.java
deleted file mode 100644
index 162d8c6..0000000
--- a/eval/LESSP.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * LESSP
represents the '<' function in Lisp.
- */
-public class LESSP extends LispFunction {
-
- public SExpression call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- Cons originalSExpr = new Cons(new Symbol("<"), argList);
-
- throw new RuntimeException("too few arguments given to <: " +
- originalSExpr);
- }
-
- SExpression firstArg = argList.getCar();
- Cons argRest = (Cons) argList.getCdr();
-
- // make sure that the first argument is a number
- if (firstArg.numberp()) {
- LispNumber num1 = (LispNumber) firstArg;
-
- if (argRest.nullp()) {
- return Symbol.T;
- }
-
- SExpression secondArg = argRest.getCar();
-
- // make sure that the second argument is a number as well
- if (secondArg.numberp()) {
- LispNumber num2 = (LispNumber) secondArg;
-
- if (num1.getValue() < num2.getValue()) {
- return call(argRest);
- }
-
- return Nil.getUniqueInstance();
- }
-
- throw new RuntimeException("<: " + secondArg + " is not a number");
- }
-
- throw new RuntimeException("<: " + firstArg + " is not a number");
- }
-
-}
diff --git a/eval/LET.java b/eval/LET.java
deleted file mode 100644
index becdbdd..0000000
--- a/eval/LET.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * LET
represents the LET form in Lisp.
- */
-public class LET extends LispFunction {
-
- public SExpression call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- throw new RuntimeException("too few arguments given to LET");
- }
-
- // create a new symbol table on top of the current environment to add
- // all the local variables to
- SymbolTable environment = new SymbolTable(SETF.getEnvironment());
-
- SExpression car = argList.getCar();
- Cons cdr = (Cons) argList.getCdr();
-
- addVariablesToTable(environment, car);
- SETF.setEnvironment(environment);
-
- SExpression retval = Nil.getUniqueInstance();
-
- // evaluate all S-expression in the body
- while (cdr.consp()) {
- retval = EVAL.eval(cdr.getCar());
- cdr = (Cons) cdr.getCdr();
- }
-
- // restore the environment to its original value
- SETF.setEnvironment(environment.getParent());
-
- return retval;
- }
-
- // Add a list of variables and their values to the specified symbol table.
- //
- // Parameters: environment - the symbol table to add the variables and
- // their values to (must not be null)
- // vars - a list of variable/value pairs (must be either a
- // proper list of pairs or NIL)
- // Throws: RuntimeException - Indicates that 'vars' is not a proper list or
- // that it contains an member that is not a
- // variable/value pair.
- // Precondition: 'environment' and 'vars' must not be null.
- // Postcondition: All of the variables in 'vars' have been placed into
- // 'environment' with their values.
- private void addVariablesToTable(SymbolTable environment,
- SExpression vars) {
- // makes sure the list of variable/value pairs is a list
- if (! vars.listp()) {
- throw new RuntimeException("LET: " + vars +
- " is not a properly formatted" +
- " variable/value pair list");
- }
-
- // add all variables in 'vars' to 'environment'
- while (vars.consp()) {
- Cons varList = (Cons) vars;
- SExpression varListCar = varList.getCar();
-
- // make sure this variable/value pair is a list
- if (! varListCar.consp()) {
- throw new RuntimeException("LET: " + varListCar +
- " is not a properly formatted" +
- " variable/value pair");
- }
-
- Cons varSpec = (Cons) varListCar;
- SExpression symbol = varSpec.getCar();
- SExpression varSpecCdr = varSpec.getCdr();
-
- // make sure this variable pair has a value associated with it
- if (! varSpecCdr.consp()) {
- throw new RuntimeException("LET: illegal variable " +
- "specification " + varSpec);
- }
-
- Cons varValue = (Cons) varSpecCdr;
- SExpression value = varValue.getCar();
-
- // make sure there are no more members of this variable/value pair
- // and that 'symbol' is actually a symbol
- if ((! varValue.getCdr().nullp()) || (! symbol.symbolp())) {
- throw new RuntimeException("LET: illegal variable " +
- "specification " + varSpec);
- }
-
- environment.put(symbol.toString(), value);
-
- vars = varList.getCdr();
- }
- }
-
- /**
- * Determine if the arguments passed to this Lisp function should be
- * evaluated.
- *
- * @return
- * false
- */
- public boolean evaluateArguments() {
- return false;
- }
-
-}
diff --git a/eval/LIST.java b/eval/LIST.java
deleted file mode 100644
index d801e6e..0000000
--- a/eval/LIST.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * LIST
represents the LIST function in Lisp.
- */
-public class LIST extends LispFunction {
-
- /**
- * Places the given S-expression into a list.
- *
- * @param sexpr
- * the S-expression to be placed into a list
- * @return
- * a list with sexpr
as the car and NIL as the cdr.
- */
- public static Cons makeList(SExpression sexpr) {
- return new Cons(sexpr, Nil.getUniqueInstance());
- }
-
- public Cons call(Cons argList) {
- if (argList.nullp()) {
- // return NIL if there were no arguments passed to LIST
- return Nil.getUniqueInstance();
- }
-
- SExpression argCar = argList.getCar();
- Cons argCdr = (Cons) argList.getCdr();
-
- return new Cons(argCar, call(argCdr));
- }
-
-}
diff --git a/eval/LISTP.java b/eval/LISTP.java
deleted file mode 100644
index b2ad0ce..0000000
--- a/eval/LISTP.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * LISTP
represents the LISTP function in Lisp.
- */
-public class LISTP extends LispFunction {
-
- // The number of arguments that LISTP takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to LISTP
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("LISTP"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to LISTP: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression arg = argList.getCar();
-
- return (arg.listp() ? Symbol.T : Nil.getUniqueInstance());
- }
-
-}
diff --git a/eval/LOAD.java b/eval/LOAD.java
deleted file mode 100644
index 4a94235..0000000
--- a/eval/LOAD.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-import java.io.*;
-
-/**
- * LOAD
represents the LOAD function in Lisp.
- */
-public class LOAD extends LispFunction {
- // The number of arguments that LOAD takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to LOAD
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("LOAD"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to LOAD: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression argCar = argList.getCar();
-
- // make sure the argument is a string
- if (! argCar.stringp()) {
- throw new RuntimeException("LOAD: " + argCar + " is not a string");
- }
-
- LispString quotedName = (LispString) argCar;
- String fileName = quotedName.toString();
-
- // remove the surrounding quotes from the file name
- fileName = fileName.substring(1, (fileName.length() - 1));
-
- return processFile(fileName);
- }
-
- // Evaluate all the S-expressions found in the file with the specified
- // name.
- //
- // Parameters: fileName - the name of the file to be evaluated
- // Returns: 'T' if the file was processed successfully; 'NIL' otherwise
- private SExpression processFile(String fileName) {
- LispParser parser = null;
-
- // attempt to create a new 'LispParser' on the specified file
- try {
- parser = new LispParser(new FileInputStream(fileName), fileName);
- } catch (FileNotFoundException e) {
- System.out.println("LOAD: could not open " + fileName);
-
- return Nil.getUniqueInstance();
- }
-
- // attempt to evaluate all the S-expressions contained in the file
- while (! parser.eof()) {
- try {
- SExpression sexpr = parser.getSExpr();
-
- EVAL.eval(sexpr);
- } catch (RuntimeException e) {
- System.out.println("LOAD: " + e.getMessage());
-
- return Nil.getUniqueInstance();
- } catch (IOException e) {
- System.out.println("LOAD: " + e.getMessage());
-
- return Nil.getUniqueInstance();
- }
- }
-
- // success!
- return Symbol.T;
- }
-
-}
diff --git a/eval/LambdaExpression.java b/eval/LambdaExpression.java
deleted file mode 100644
index 570d162..0000000
--- a/eval/LambdaExpression.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * This class represents a Lisp FUNCTION in the PL-Lisp implementation.
- */
-public class LambdaExpression extends SExpression {
-
- private Cons lexpr;
- private UDFunction function;
-
- /**
- * Create a new FUNCTION with the specified lambda expression and
- * internal representation.
- *
- * @param lexpr
- * the lambda expression of this FUNCTION
- * @param function
- * the internal representation of this FUNCTION
- */
- public LambdaExpression(Cons lexpr, UDFunction function) {
- this.lexpr = lexpr;
- this.function = function;
- }
-
- /**
- * Test if this S-expression is a FUNCTION.
- *
- * @return
- * true
- */
- public boolean functionp() {
- return true;
- }
-
- /**
- * Retrieve the lambda expression of this FUNCTION.
- *
- * @return
- * the lambda expression of this FUNCTION
- */
- public Cons getLExpression() {
- return lexpr;
- }
-
- /**
- * Retrieve the internal representation of this FUNCTION.
- *
- * @return
- * the user-defined function of this FUNCTION
- */
- public UDFunction getFunction() {
- return function;
- }
-
- /**
- * Returns a string representation of this FUNCTION.
- *
- * @return
- * a string representation of this FUNCTION
- */
- public String toString() {
- return lexpr.toString();
- }
-
-}
diff --git a/eval/LispFunction.java b/eval/LispFunction.java
deleted file mode 100644
index c861fa2..0000000
--- a/eval/LispFunction.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * A LispFunction
is an internal representation of a built-in
- * function in the Lisp programming language.
- */
-public abstract class LispFunction {
-
- /**
- * Call this Lisp function with the given list of arguments.
- *
- * @param argList
- * the list of arguments to pass to this function (MUST BE A PROPER LIST)
- * @return
- * the resulting S-expression of calling this function with the specified
- * arguments
- * @throws RuntimeException
- * Indicates that an incorrect number of arguments has been passed to this
- * function or that one of the arguments is not of the expected type.
- */
- public abstract SExpression call(Cons argList);
-
- /**
- * Determine if the arguments passed to this Lisp function should be
- * evaluated. A subclass should override this method to return
- * false
if it does not want its arguments to be evaluated
- * prior to being passed.
- *
- * @return
- * true
- */
- public boolean evaluateArguments() {
- return true;
- }
-
-}
diff --git a/eval/MINUS.java b/eval/MINUS.java
deleted file mode 100644
index a913624..0000000
--- a/eval/MINUS.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * MINUS
represents the '-' function in Lisp.
- */
-public class MINUS extends LispFunction {
-
- public SExpression call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- Cons originalSExpr = new Cons(new Symbol("-"), argList);
-
- throw new RuntimeException("too few arguments given to -: " +
- originalSExpr);
- }
-
- SExpression argFirst = argList.getCar();
- Cons argRest = (Cons) argList.getCdr();
-
- // make sure that the first argument is a number
- if (argFirst.numberp()) {
- LispNumber num1 = (LispNumber) argFirst;
-
- if (argRest.nullp()) {
- // there is only one argument, so return the additive
- // inverse of the number
- return new LispNumber(- num1.getValue());
- }
-
- SExpression argSecond = argRest.getCar();
-
- // make sure that the next argument is a number as well
- if (argSecond.numberp()) {
- LispNumber num2 = (LispNumber) argSecond;
- LispNumber difference = new LispNumber(num1.getValue() -
- num2.getValue());
- SExpression argCddr = argRest.getCdr();
-
- if (argCddr.consp()) {
- return call(new Cons(difference, argCddr));
- }
-
- return difference;
- }
-
- throw new RuntimeException("-: " + argSecond + " is not a number");
- }
-
- throw new RuntimeException("-: " + argFirst + " is not a number");
- }
-
-}
diff --git a/eval/MULTIPLY.java b/eval/MULTIPLY.java
deleted file mode 100644
index ac15950..0000000
--- a/eval/MULTIPLY.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * MULTIPLY
represents the '*' function in Lisp.
- */
-public class MULTIPLY extends LispFunction {
-
- public LispNumber call(Cons argList) {
- if (argList.nullp()) {
- return new LispNumber(1);
- }
-
- SExpression argFirst = argList.getCar();
- Cons argRest = (Cons) argList.getCdr();
-
- if (argFirst.numberp()) {
- LispNumber num1 = (LispNumber) argFirst;
- LispNumber num2 = call(argRest);
-
- return new LispNumber(num1.getValue() * num2.getValue());
- }
-
- throw new RuntimeException("*: " + argFirst + " is not a number");
- }
-
-}
diff --git a/eval/NULL.java b/eval/NULL.java
deleted file mode 100644
index fd30367..0000000
--- a/eval/NULL.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * NULL
represents the NULL function in Lisp.
- */
-public class NULL extends LispFunction {
-
- // The number of arguments that NULL takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to NULL
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("NULL"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to NULL: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression arg = argList.getCar();
-
- return (arg.nullp() ? Symbol.T : Nil.getUniqueInstance());
- }
-
-}
diff --git a/eval/PLUS.java b/eval/PLUS.java
deleted file mode 100644
index 144f46c..0000000
--- a/eval/PLUS.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * PLUS
represents the '+' function in Lisp.
- */
-public class PLUS extends LispFunction {
-
- public LispNumber call(Cons argList) {
- if (argList.nullp()) {
- return new LispNumber(0);
- }
-
- SExpression argFirst = argList.getCar();
- Cons argRest = (Cons) argList.getCdr();
-
- if (argFirst.numberp()) {
- LispNumber num1 = (LispNumber) argFirst;
- LispNumber num2 = call(argRest);
-
- return new LispNumber(num1.getValue() + num2.getValue());
- }
-
- throw new RuntimeException("+: " + argFirst + " is not a number");
- }
-
-}
diff --git a/eval/PRINT.java b/eval/PRINT.java
deleted file mode 100644
index f9fedb5..0000000
--- a/eval/PRINT.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * PRINT
represents the PRINT function in Lisp.
- */
-public class PRINT extends LispFunction {
-
- // The number of arguments that PRINT takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to PRINT
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("PRINT"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to PRINT: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression arg = argList.getCar();
-
- System.out.println(arg);
-
- return arg;
- }
-
-}
diff --git a/eval/QUOTE.java b/eval/QUOTE.java
deleted file mode 100644
index 960ab3e..0000000
--- a/eval/QUOTE.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * QUOTE
represents the QUOTE form in Lisp.
- */
-public class QUOTE extends LispFunction {
-
- // The number of arguments that QUOTE takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to QUOTE
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received exactly one argument
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("QUOTE"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to QUOTE: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- return argList.getCar();
- }
-
- /**
- * Determine if the arguments passed to this Lisp function should be
- * evaluated.
- *
- * @return
- * false
- */
- public boolean evaluateArguments() {
- return false;
- }
-
-}
diff --git a/eval/SETF.java b/eval/SETF.java
deleted file mode 100644
index 90c25d4..0000000
--- a/eval/SETF.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * SETF
represents the SETF form in Lisp.
- */
-public class SETF extends LispFunction {
-
- private static SymbolTable environment = new SymbolTable();
-
- /**
- * Look up the value of a symbol using its name.
- *
- * @param symbolName
- * the name of the symbol to look up
- * @return
- * the value of symbolName
if it has one; null otherwise
- */
- public static SExpression lookup(String symbolName) {
- SymbolTable current = environment;
-
- while (current != null) {
- if (current.contains(symbolName)) {
- return current.get(symbolName);
- }
-
- current = current.getParent();
- }
-
- return null;
- }
-
- /**
- * Set the current environment to the specified value.
- *
- * @param newEnvironment
- * the value to set the environment to
- */
- public static void setEnvironment(SymbolTable newEnvironment) {
- environment = newEnvironment;
- }
-
- /**
- * Retrieve the current environment.
- *
- * @return
- * the current environment
- */
- public static SymbolTable getEnvironment() {
- return environment;
- }
-
- // The number of arguments that SETF takes.
- private static final int NUM_ARGS = 2;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to SETF
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("SETF"), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to SETF: " + originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression symbol = argList.getCar();
-
- // make sure the first argument is a symbol
- if (! symbol.symbolp()) {
- throw new RuntimeException("SETF: " + symbol + " is not a symbol");
- }
-
- Cons cdr = (Cons) argList.getCdr();
- SExpression value = EVAL.eval(cdr.getCar());
-
- SymbolTable current = environment;
-
- // set 'current' to the symbol table that contains 'symbol' or the
- // global symbol table if 'symbol' is not in the environment
- while ((! current.contains(symbol.toString())) &&
- (current.getParent() != null)) {
- current = current.getParent();
- }
-
- current.put(symbol.toString(), value);
-
- return value;
- }
-
- /**
- * Determine if the arguments passed to this Lisp function should be
- * evaluated.
- *
- * @return
- * false
- */
- public boolean evaluateArguments() {
- return false;
- }
-
-}
diff --git a/eval/SYMBOL_FUNCTION.java b/eval/SYMBOL_FUNCTION.java
deleted file mode 100644
index 4a591ee..0000000
--- a/eval/SYMBOL_FUNCTION.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-
-/**
- * SYMBOL_FUNCTION
represents the SYMBOL-FUNCTION function in
- * Lisp.
- */
-public class SYMBOL_FUNCTION extends LispFunction {
-
- // The number of arguments that SYMBOL-FUNCTION takes.
- private static final int NUM_ARGS = 1;
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to SYMBOL-FUNCTION
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("SYMBOL-FUNCTION"),
- argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to SYMBOL-FUNCTION: " +
- originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- SExpression arg = argList.getCar();
-
- // make sure the argument is a symbol
- if (arg.symbolp()) {
- LispFunction function = EVAL.lookupFunction(arg.toString());
-
- // make sure the function actually exists
- if (function != null) {
- if (function instanceof UDFunction) {
- // this is a user-defined function
-
- UDFunction udFunction = (UDFunction) function;
-
- return udFunction.getLexpr();
- }
-
- // this is a built-in function
-
- return new Symbol("SUBR-" + arg.toString());
- }
-
- throw new RuntimeException("SYMBOL-FUNCTION: undefined function " +
- arg);
- }
-
- throw new RuntimeException("SYMBOL-FUNCTION: " + arg +
- " is not a symbol");
- }
-
-}
diff --git a/eval/SymbolTable.java b/eval/SymbolTable.java
deleted file mode 100644
index aa72b28..0000000
--- a/eval/SymbolTable.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-import java.util.HashMap;
-
-/**
- * A SymbolTable
maps symbol names to values.
- */
-public class SymbolTable {
-
- private HashMap table;
- private SymbolTable parent;
-
- /**
- * Create a new symbol table with no parent.
- */
- public SymbolTable() {
- this(null);
- }
-
- /**
- * Create a new symbol table with the specified parent.
- *
- * @param parent
- * the parent of this symbol table
- */
- public SymbolTable(SymbolTable parent) {
- this.table = new HashMap();
- this.parent = parent;
- }
-
- /**
- * Determine if the specified symbol name is in this symbol table.
- *
- * @param symbolName
- * the name of the symbol to look up
- * @return
- * true
if the symbol is in this symbol table;
- * false
otherwise
- */
- public boolean contains(String symbolName) {
- return table.containsKey(symbolName);
- }
-
- /**
- * Returns the value to which the specified symbol name is mapped in this
- * symbol table.
- *
- * @param symbolName
- * the name of the symbol whose associated value is to be returned
- * @return
- * the value to which this symbol table maps symbolName
, or
- * null if no mapping exists
- */
- public SExpression get(String symbolName) {
- return table.get(symbolName);
- }
-
- /**
- * Associates the specified symbol name with the specified value in this
- * symbol table. If the symbol table previously contained a mapping for
- * this symbol name, the old value has been replaced.
- *
- * @param symbolName
- * the name of the symbol with which the specified value is to be
- * associated
- * @param value
- * the value to be associated with the specified symbol name
- */
- public void put(String symbolName, SExpression value) {
- table.put(symbolName, value);
- }
-
- /**
- * Returns the parent of this symbol table.
- *
- * @return
- * the parent of this symbol table
- */
- public SymbolTable getParent() {
- return parent;
- }
-
-}
diff --git a/eval/UDFunction.java b/eval/UDFunction.java
deleted file mode 100644
index 44e02c8..0000000
--- a/eval/UDFunction.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 2
- */
-
-package eval;
-
-import parser.*;
-import java.util.ArrayList;
-
-/**
- * A UDFunction
is an internal representation of a user-defined
- * function in the Lisp programming language.
- */
-public class UDFunction extends LispFunction {
-
- // the number of arguments that this user-defined function takes.
- private final int NUM_ARGS;
-
- private String name;
- private Cons body;
- private Cons lexpr;
- private SymbolTable environment;
- private ArrayList parameters;
-
- /**
- * Create a new user-defined function with the specified name, lambda list
- * and body.
- *
- * @param name
- * the name of this user-defined function
- * @param lambdaList
- * a list of the formal parameters of this user-defined function (MUST BE
- * A PROPER LIST)
- * @param body
- * the body of this user-defined function (MUST BE A PROPER LIST)
- */
- public UDFunction(String name, Cons lambdaList, Cons body) {
- this.name = name;
- this.body = body;
- this.lexpr = new Cons(new Symbol(name), new Cons(lambdaList, body));
- this.environment = SETF.getEnvironment();
- this.parameters = new ArrayList();
-
- // retrieve the names of all the formal parameters of this function
- while (lambdaList.consp()) {
- this.parameters.add(lambdaList.getCar().toString());
-
- lambdaList = (Cons) lambdaList.getCdr();
- }
-
- this.NUM_ARGS = this.parameters.size();
- }
-
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to this function
- int argListLength = LENGTH.getLength(argList);
-
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol(name), argList);
- String errMsg = "too " +
- ((argListLength > NUM_ARGS) ? "many" : "few") +
- " arguments given to " + name + ": " +
- originalSExpr;
-
- throw new RuntimeException(errMsg);
- }
-
- // push a new symbol table onto this function's environment (for its
- // parameters)
- environment = new SymbolTable(environment);
-
- // bind the values of the arguments to the formal parameter names
- for (String param : parameters) {
- SExpression currentArg = argList.getCar();
-
- environment.put(param, currentArg);
-
- argList = (Cons) argList.getCdr();
- }
-
- // store the environment of the S-expression that called this function
- // (the current environment)
- SymbolTable currentEnvironment = SETF.getEnvironment();
-
- // replace the current environment with the environment of this
- // function
- SETF.setEnvironment(environment);
-
- Cons currentSExpression = body;
- SExpression retval = null;
-
- // evaluate all the S-expressions making up this function's body
- while (currentSExpression.consp()) {
- retval = EVAL.eval(currentSExpression.getCar());
- currentSExpression = (Cons) currentSExpression.getCdr();
- }
-
- // replace the environment of the S-expression that called this
- // function
- SETF.setEnvironment(currentEnvironment);
-
- // remove the bindings of the arguments to the formal parameter names
- // in the environment of this function
- environment = new SymbolTable(environment.getParent());
-
- return retval;
- }
-
- /**
- * Return the lambda expression that represents this user-defined function.
- *
- * @return
- * the lambda expression that represents this user-defined function
- */
- public Cons getLexpr() {
- return lexpr;
- }
-
-}
diff --git a/eval/package.html b/eval/package.html
deleted file mode 100644
index e9c971d..0000000
--- a/eval/package.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
- Provides functions and forms to be used during the evaluation of an
- S-expression.
-
diff --git a/main/LispInterpreter.java b/main/LispInterpreter.java
deleted file mode 100644
index 3fbb5d6..0000000
--- a/main/LispInterpreter.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter 1
- */
-
-package main;
-
-import parser.*;
-import eval.*;
-import error.ErrorManager;
-import java.io.*;
-import java.text.MessageFormat;
-
-/**
- * LispInterpreter
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 1.0.1";
- 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.
- *
- * @param args
- * the command-line arguments:
- *
- * args[0]
- file name (optional)
- *
- */
- public static void main(String[] args) {
- LispParser parser = null;
- 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(e.getMessage(), ErrorManager.CRITICAL_LEVEL);
- }
- } 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.eof()) {
- try {
- SExpression sexpr = parser.getSExpr();
- String result = MessageFormat.format("{0}{1}{2}", ANSI_GREEN, EVAL.eval(sexpr), ANSI_RESET);
-
- LispInterpreter.erasePrompt(interactive);
- System.out.println(result);
- } catch (RuntimeException e) {
- LispInterpreter.erasePrompt(interactive);
- ErrorManager.generateError(e.getMessage(), 2);
- } catch (IOException e) {
- ErrorManager.generateError(e.getMessage(), ErrorManager.CRITICAL_LEVEL);
- }
-
- if (interactive) {
- System.out.print(PROMPT);
- }
- }
- }
-
- private static void erasePrompt(boolean interactive) {
- if (interactive) {
- for (int i = 0; i < PROMPT.length(); i++) {
- System.out.print("\b");
- }
- }
- }
-
-}
diff --git a/main/LispInterpreter2.java b/main/LispInterpreter2.java
deleted file mode 100644
index 0c6726a..0000000
--- a/main/LispInterpreter2.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package main;
-
-import parser.*;
-import eval.*;
-import error.ErrorManager;
-import java.io.*;
-import java.net.*;
-import remotefs.RemoteFileInputStream;
-
-public class LispInterpreter2 {
-
- public static final String HOST_NAME = "localhost";
- public static final int PORT_NUM = 5150;
-
- public static void main(String[] args) {
- LispParser parser = null;
-
- if (args.length > 0) {
- try {
- InetAddress host = InetAddress.getByName(HOST_NAME);
- RemoteFileInputStream remoteIn =
- new RemoteFileInputStream(host, PORT_NUM, args[0]);
-
- parser = new LispParser(remoteIn, args[0]);
- } catch (UnknownHostException e) {
- ErrorManager.generateError(e.getMessage(),
- ErrorManager.CRITICAL_LEVEL);
- } catch (FileNotFoundException e) {
- ErrorManager.generateError(e.getMessage(),
- ErrorManager.CRITICAL_LEVEL);
- }
- } else {
- parser = new LispParser(System.in, "System.in");
- }
-
- while (! parser.eof()) {
- try {
- SExpression sexpr = parser.getSExpr();
-
- System.out.println(EVAL.eval(sexpr));
- } catch (RuntimeException e) {
- ErrorManager.generateError(e.getMessage(), 2);
- } catch (IOException e) {
- ErrorManager.generateError(e.getMessage(),
- ErrorManager.CRITICAL_LEVEL);
- }
- }
- }
-
-}
diff --git a/main/LispParserDriver.java b/main/LispParserDriver.java
deleted file mode 100644
index d0ffc46..0000000
--- a/main/LispParserDriver.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Parser
- */
-
-package main;
-
-import parser.*;
-import error.ErrorManager;
-import java.io.*;
-
-/**
- * LispParserDriver
is a program that takes the name of a file
- * as a command-line argument, creates an internal representation of the
- * S-expressions found in the file and prints them to the console. If no file
- * name is provided at the command-line, this program will read from standard
- * input.
- */
-public class LispParserDriver {
-
- /**
- * Create internal representations of the S-expressions found in the file
- * whose name was given as a command-line argument and print them to the
- * console. If no file name was given, retrieve the S-expressions from
- * standard input.
- *
- * @param args
- * the command-line arguments:
- *
- * args[0]
- file name (optional)
- *
- */
- public static void main(String[] args) {
- LispParser parser = null;
-
- 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(e.getMessage(),
- ErrorManager.CRITICAL_LEVEL);
- }
- } else {
- // no file name was given, create a 'LispParser' on standard input
- parser = new LispParser(System.in, "System.in");
- }
-
- while (! parser.eof()) {
- try {
- SExpression sexpr = parser.getSExpr();
-
- System.out.println(sexpr.toString());
- } catch (RuntimeException e) {
- ErrorManager.generateError(e.getMessage(), 2);
- } catch (IOException e) {
- ErrorManager.generateError(e.getMessage(),
- ErrorManager.CRITICAL_LEVEL);
- }
- }
- }
-
-}
diff --git a/main/LispScannerDriver.java b/main/LispScannerDriver.java
deleted file mode 100644
index 13447c3..0000000
--- a/main/LispScannerDriver.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter Phase 1 - Lexical Analysis
- */
-
-package main;
-
-import scanner.*;
-import error.ErrorManager;
-import java.io.*;
-
-/**
- * LispScannerDriver
is a program that takes the name of a file
- * as a command-line argument, retrieves all of the Lisp tokens from the file
- * and prints them to the console. If no file name is provided at the
- * command-line, this program will read from standard input.
- */
-public class LispScannerDriver {
-
- /**
- * Obtain the Lisp tokens from the file whose name was given as a
- * command-line argument and print them to the console. If no file name was
- * given, retrieve the tokens from standard input.
- *
- * @param args
- * the command-line arguments:
- *
- * args[0]
- file name (optional)
- *
- */
- public static void main(String[] args) {
- LispScanner in = null;
-
- if (args.length > 0) {
- // a file name was given at the command-line, attempt to create a
- // 'LispScanner' on it
- try {
- in = new LispScanner(new FileInputStream(args[0]), args[0]);
- } catch (FileNotFoundException e) {
- ErrorManager.generateError(e.getMessage(),
- ErrorManager.CRITICAL_LEVEL);
- }
- } else {
- // no file name was given, create a 'LispScanner' on standard input
- in = new LispScanner(System.in, "System.in");
- }
-
- Token t = null;
-
- do {
- try {
- t = in.nextToken();
-
- System.out.printf("%-15s%-25s%5d%5d%25s\n", t.getType(),
- t.getText(),
- t.getLine(),
- t.getColumn(),
- t.getFName());
- } catch (RuntimeException e) {
- ErrorManager.generateError(e.getMessage(), 2);
- } catch (IOException e) {
- ErrorManager.generateError(e.getMessage(),
- ErrorManager.CRITICAL_LEVEL);
- }
- } while ((t == null) || (t.getType() != Token.Type.EOF));
- }
-
-}
diff --git a/main/package.html b/main/package.html
deleted file mode 100644
index bfdbdab..0000000
--- a/main/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Provides test drivers for the various stages of the Lisp Interpreter.
-
diff --git a/parser/Atom.java b/parser/Atom.java
deleted file mode 100644
index 465de81..0000000
--- a/parser/Atom.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Parser
- */
-
-package parser;
-
-/**
- * This class represents an ATOM in the PL-Lisp implementation.
- */
-public class Atom extends SExpression {
-
- private String text;
-
- /**
- * Create a new ATOM with the specified text.
- *
- * @param text
- * the text representing this ATOM
- */
- public Atom(String text) {
- this.text = text;
- }
-
- /**
- * Test if this S-expression is an ATOM.
- *
- * @return
- * true
- */
- public boolean atomp() {
- return true;
- }
-
- /**
- * Returns a string representation of this ATOM.
- *
- * @return
- * a string representation of this ATOM
- */
- public String toString() {
- return text;
- }
-
-}
diff --git a/parser/Cons.java b/parser/Cons.java
deleted file mode 100644
index 2402a99..0000000
--- a/parser/Cons.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Parser
- */
-
-package parser;
-
-/**
- * This class represents a Lisp CONS cell in the PL-Lisp implementation.
- */
-public class Cons extends SExpression {
-
- private SExpression car;
- private SExpression cdr;
-
- /**
- * Create a new CONS cell with the specified car and cdr.
- *
- * @param car
- * the car of this CONS cell
- * @param cdr
- * the cdr of this CONS cell
- */
- public Cons(SExpression car, SExpression cdr) {
- this.car = car;
- this.cdr = cdr;
- }
-
- /**
- * Retrieve the car of this CONS cell.
- *
- * @return
- * the car of this CONS cell
- */
- public SExpression getCar() {
- return car;
- }
-
- /**
- * Retrieve the cdr of this CONS cell.
- *
- * @return
- * the cdr of this CONS cell
- */
- public SExpression getCdr() {
- return cdr;
- }
-
- /**
- * Set the car of this CONS cell to the specified value.
- *
- * @param newCar
- * the value to assign to the car of this CONS cell
- */
- public void setCar(SExpression newCar) {
- car = newCar;
- }
-
- /**
- * Set the cdr of this CONS cell to the specified value.
- *
- * @param newCdr
- * the value to assign to the cdr of this CONS cell
- */
- public void setCdr(SExpression newCdr) {
- cdr = newCdr;
- }
-
- /**
- * Test if this S-expression is a CONS cell.
- *
- * @return
- * true
- */
- public boolean consp() {
- return true;
- }
-
- /**
- * Returns a string representation of this CONS cell.
- *
- * @return
- * a string representation of this CONS cell
- */
- public String toString() {
- return ("(" + toStringAux());
- }
-
- // Returns a string representation of the car of a CONS cell followed by
- // its cdr. If the cdr of this CONS cell is not a CONS cell itself, this
- // method places a ')' at the end of its return value. Also, if the cdr of
- // this CONS cell is NIL, it will not be included in the return value of
- // this method. When used in conjunction with the 'toString' method of this
- // class, this method provides a means for creating the correct string
- // representation of a list.
- //
- // Returns: a string representation of the car of a CONS cell followed by
- // its cdr
- private String toStringAux() {
- if (cdr.nullp()) {
- return (car.toString() + ")");
- } else if (cdr.consp()) {
- return (car.toString() + " " + ((Cons) cdr).toStringAux());
- }
-
- // the cdr of this CONS cell is not a list
- return (car.toString() + " . " + cdr.toString() + ")");
- }
-
-}
diff --git a/parser/LispNumber.java b/parser/LispNumber.java
deleted file mode 100644
index 34c3bde..0000000
--- a/parser/LispNumber.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Parser
- */
-
-package parser;
-
-/**
- * This class represents a NUMBER in the PL-Lisp implementation.
- */
-public class LispNumber extends Atom {
-
- private int value;
-
- /**
- * Create a new NUMBER with the specified text.
- *
- * @param text
- * the text representing this NUMBER
- * @throws IllegalArgumentException
- * Indicates that text
does not represent a valid integer.
- */
- public LispNumber(String text) {
- super(text.replaceFirst("^0+(?!$)", ""));
-
- try {
- this.value = Integer.parseInt(text);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(text +
- " is not a valid integer");
- }
- }
-
- /**
- * Create a new NUMBER with the specified value.
- *
- * @param value
- * the integer value of this NUMBER
- */
- public LispNumber(int value) {
- super(Integer.toString(value));
-
- this.value = value;
- }
-
- /**
- * Test if this S-expression is a NUMBER.
- *
- * @return
- * true
- */
- public boolean numberp() {
- return true;
- }
-
- /**
- * Retrieve the integer value of this NUMBER.
- *
- * @return
- * the integer value of this NUMBER
- */
- public int getValue() {
- return value;
- }
-
-}
diff --git a/parser/LispParser.java b/parser/LispParser.java
deleted file mode 100644
index 9a7733f..0000000
--- a/parser/LispParser.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Parser
- */
-
-package parser;
-
-import scanner.*;
-import java.io.*;
-
-/**
- * A LispParser
converts a stream of bytes into internal
- * representations of Lisp S-expressions. When the end of stream has been
- * reached the eof
method of this parser will return true.
- */
-public class LispParser {
-
- private LispScanner scanner;
- private Token nextToken;
-
- // A field to store an exception that has been thrown in the 'eof' method
- // as a result of reading in the next token from 'scanner'.
- private Exception delayedException;
-
- // A field to notify us if the next token has already been stored in
- // 'nextToken' by the 'eof' method.
- private boolean nextTokenStored;
-
- /**
- * Create a new LispParser
that produces S-expressions from
- * the specified input stream.
- *
- * @param in
- * the input stream to obtain S-expressions from (must not be
- * null
)
- * @param fileName
- * the name of the file that in
is reading from
- */
- public LispParser(InputStream in, String fileName) {
- scanner = new LispScanner(in, fileName);
- nextToken = null;
- delayedException = null;
- nextTokenStored = false;
- }
-
- /**
- * Determing if this parser has reached the end of its underlying input
- * stream.
- *
- * @return
- * true
if this parser has reached the end of its underlying
- * input stream; false
otherwise
- */
- public boolean eof() {
- if (! nextTokenStored) {
- // attempt to read the next token from 'scanner' and store it in
- // 'nextToken'
- try {
- nextToken = scanner.nextToken();
- nextTokenStored = true;
- } catch (Exception e) {
- // this method should give the illusion of not actually reading
- // a token, so we store any exceptions thrown as a result of
- // reading in the next token from 'scanner' (it will be thrown
- // the next time the 'getSExpr' method is called)
- delayedException = e;
-
- if (nextToken == null) {
- // we have not successfully read in any tokens yet, so we
- // could not have read in an end-of-file token
-
- return false;
- }
- }
- }
-
- return (nextToken.getType() == Token.Type.EOF);
- }
-
- /**
- * Returns the next S-expression from this parser.
- *
- * @return
- * the next S-expression from this parser
- * @throws RuntimeException
- * Indicates that an illegal S-expression was encountered in the
- * underlying input stream.
- * @throws IOException
- * Indicates that an I/O error has occurred.
- */
- public SExpression getSExpr() throws IOException {
- if (delayedException != null) {
- // the 'eof' method has stored an exception for us to throw
-
- // determine the type of the stored exception and throw it!
- if (delayedException instanceof IOException) {
- IOException e = (IOException) delayedException;
-
- // remove the exception from 'delayedException'
- delayedException = null;
-
- throw e;
- } else if (delayedException instanceof RuntimeException) {
- RuntimeException e = (RuntimeException) delayedException;
-
- // remove the exception from 'delayedException'
- delayedException = null;
-
- throw e;
- }
- }
-
- if (! nextTokenStored) {
- // the next token has not been stored in 'nextToken' by the 'eof'
- // method
-
- nextToken = scanner.nextToken();
- } else {
- // the 'eof' method has been called and has read in the next token
- // already to determine if we have reached the end-of-file
-
- nextTokenStored = false;
- }
-
- return sExpr();
- }
-
- // sExpr ::= NUMBER | IDENTIFIER | RESERVED | STRING | QUOTE_MARK sExpr |
- // LEFT_PAREN sExprTail
- //
- // Returns: an S-expression that matches the rules given above
- // Throws: RuntimeException - Indicates that an illegal S-expression was
- // encountered in the underlying input stream.
- // Throws: IOException - Indicates that an I/O error has occurred.
- // Precondition: 'nextToken' is not null.
- private SExpression sExpr() throws IOException {
- // determine the type of 'nextToken' and create the appropriate
- // S-expression
- switch (nextToken.getType()) {
- case NUMBER:
- return new LispNumber(nextToken.getText());
- case IDENTIFIER:
- case RESERVED:
- return new Symbol(nextToken.getText());
- case STRING:
- return new LispString(nextToken.getText());
- case QUOTE_MARK:
- nextToken = scanner.nextToken();
- SExpression arg = sExpr();
-
- return new Cons(new Symbol("QUOTE"),
- new Cons(arg, Nil.getUniqueInstance()));
- case LEFT_PAREN:
- return sExprTail();
- case RIGHT_PAREN:
- throw new RuntimeException("expression begins with \')\'" +
- " - line " + nextToken.getLine() +
- " column " + nextToken.getColumn());
- case EOF:
- throw new RuntimeException("end-of-file encountered" +
- " - line " + nextToken.getLine() +
- " column " + nextToken.getColumn());
- default: // unrecognized token type
- throw new RuntimeException("unrecognizable token" +
- " - line " + nextToken.getLine() +
- " column " + nextToken.getColumn());
- }
- }
-
- // sExprTail ::= RIGHT_PAREN | sExpr sExprTail
- //
- // Returns: an S-expression that matches the rules given above
- // Throws: IOException - Indicates that an I/O error has occurred.
- // Precondition: 'scanner' is not null.
- private SExpression sExprTail() throws IOException {
- nextToken = scanner.nextToken();
-
- // determine the type of 'nextToken' and create the appropriate
- // S-expression
- switch (nextToken.getType()) {
- case RIGHT_PAREN:
- return Nil.getUniqueInstance();
- default:
- SExpression car = sExpr();
- SExpression cdr = sExprTail();
-
- return new Cons(car, cdr);
- }
- }
-
-}
diff --git a/parser/LispString.java b/parser/LispString.java
deleted file mode 100644
index 66b56a3..0000000
--- a/parser/LispString.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Parser
- */
-
-package parser;
-
-/**
- * This class represents a STRING in the PL-Lisp implementation.
- */
-public class LispString extends Atom {
-
- /**
- * Create a new STRING with the specified text.
- *
- * @param text
- * the text representing this STRING
- */
- public LispString(String text) {
- super(text);
- }
-
- /**
- * Test if this S-expression is a STRING.
- *
- * @return
- * true
- */
- public boolean stringp() {
- return true;
- }
-
-}
diff --git a/parser/Nil.java b/parser/Nil.java
deleted file mode 100644
index 5344053..0000000
--- a/parser/Nil.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Parser
- */
-
-package parser;
-
-/**
- * This class represents NIL in the PL-Lisp implementation.
- */
-public class Nil extends Cons {
-
- private static Nil uniqueInstance = new Nil();
-
- /**
- * Retrieve the single unique instance of NIL.
- *
- * @return
- * the single unique instance of NIL
- */
- public static Nil getUniqueInstance() {
- return uniqueInstance;
- }
-
- // We are using the Singleton pattern, so the constructor for 'Nil' is
- // private.
- private Nil() {
- super(null, null);
-
- // the car and cdr of NIL both refer to NIL
- super.setCar(this);
- super.setCdr(this);
- }
-
- /**
- * Test if this S-expression is NULL.
- *
- * @return
- * true
- */
- public boolean nullp() {
- return true;
- }
-
- /**
- * Test if this S-expression is an ATOM.
- *
- * @return
- * true
- */
- public boolean atomp() {
- return true;
- }
-
- /**
- * Test if this S-expression is a CONS cell.
- *
- * @return
- * false
- */
- public boolean consp() {
- return false;
- }
-
- /**
- * Test if this S-expression is a SYMBOL.
- *
- * @return
- * true
- */
- public boolean symbolp() {
- return true;
- }
-
- /**
- * Set the car of this CONS cell to the specified value. This method does
- * nothing (the car of NIL can not be changed).
- *
- * @param newCar
- * the value to assign to the car of this CONS cell
- */
- public void setCar(SExpression newCar) {}
-
- /**
- * Set the cdr of this CONS cell to the specified value. This method does
- * nothing (the cdr of NIL can not be changed).
- *
- * @param newCdr
- * the value to assign to the cdr of this CONS cell
- */
- public void setCdr(SExpression newCdr) {}
-
- /**
- * Returns a string representation of NIL.
- *
- * @return
- * a string representation of NIL
- */
- public String toString() {
- return "NIL";
- }
-
-}
diff --git a/parser/SExpression.java b/parser/SExpression.java
deleted file mode 100644
index bb8aaa4..0000000
--- a/parser/SExpression.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Parser
- */
-
-package parser;
-
-/**
- * This is the base class for memory in the PL-Lisp implementation.
- */
-public class SExpression {
-
- // for mark and sweep garbage collection
- private boolean marked = false;
-
- /**
- * Determine if this SExpression
is marked.
- *
- * @return
- * true
if this SExpression
is marked;
- * false
otherwise
- */
- public final boolean isMarked() {
- return marked;
- }
-
- /**
- * Set the marked status of this S-expression to the specified value.
- *
- * @param value
- * the value to assign to this S-expression's marked status
- */
- public final void setMarked(final boolean value) {
- marked = value;
- }
-
- // Lisp type predicates;
- // by default, all return false (an SExpression effectively has NO type);
- // overridden in subclasses to describe their Lisp type
-
- /**
- * Test if this S-expression is NULL.
- *
- * @return
- * false
- */
- public boolean nullp() {
- return false;
- }
-
- /**
- * Test if this S-expression is an ATOM.
- *
- * @return
- * false
- */
- public boolean atomp() {
- return false;
- }
-
- /**
- * Test if this S-expression is a CONS cell.
- *
- * @return
- * false
- */
- public boolean consp() {
- return false;
- }
-
- /**
- * Test if this S-expression is a LIST.
- *
- * @return
- * the value of (consp() || nullp())
- */
- public boolean listp() {
- return (consp() || nullp());
- }
-
- /**
- * Test if this S-expression is a NUMBER.
- *
- * @return
- * false
- */
- public boolean numberp() {
- return false;
- }
-
- /**
- * Test if this S-expression is a SYMBOL.
- *
- * @return
- * false
- */
- public boolean symbolp() {
- return false;
- }
-
- /**
- * Test if this S-expression is a FUNCTION.
- *
- * @return
- * false
- */
- public boolean functionp() {
- return false;
- }
-
- /**
- * Test if this S-expression is a STRING.
- *
- * @return
- * false
- */
- public boolean stringp() {
- return false;
- }
-
-}
diff --git a/parser/Symbol.java b/parser/Symbol.java
deleted file mode 100644
index 96f1a96..0000000
--- a/parser/Symbol.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Parser
- */
-
-package parser;
-
-/**
- * This class represents a SYMBOL in the PL-Lisp implementation.
- */
-public class Symbol extends Atom {
-
- /** This SYMBOL represents TRUE in the PL-Lisp implementation. */
- public static final Symbol T = new Symbol("T");
-
- /**
- * Create a new SYMBOL with the specified text.
- *
- * @param text
- * the text representing this SYMBOL
- */
- public Symbol(String text) {
- super(text.toUpperCase());
- }
-
- /**
- * Test if this S-expression is a SYMBOL.
- *
- * @return
- * true
- */
- public boolean symbolp() {
- return true;
- }
-
-}
diff --git a/parser/package.html b/parser/package.html
deleted file mode 100644
index ed4dbdd..0000000
--- a/parser/package.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
- Provides the classes necessary for creating an internal representation of
- the Lisp programming language.
-
diff --git a/scanner/LispFilterStream.java b/scanner/LispFilterStream.java
deleted file mode 100644
index d9838dc..0000000
--- a/scanner/LispFilterStream.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter Phase 1 - Lexical Analysis
- */
-
-package scanner;
-
-import java.io.InputStream;
-import java.io.FilterInputStream;
-import java.io.IOException;
-
-/**
- * A LispFilterStream
is an input stream that returns the bytes
- * from an underlying input stream with all Lisp comments removed and replaced
- * with newlines.
- */
-public class LispFilterStream extends FilterInputStream {
-
- private boolean inQuote;
-
- /**
- * Creates a LispFilterStream
with the specified underlying
- * InputStream
.
- *
- * @param in
- * the underlying input stream (must not be null
)
- */
- public LispFilterStream(InputStream in) {
- super(in);
-
- inQuote = false;
- }
-
- /**
- * Reads the next byte of data from this input stream. The value byte is
- * returned as an int
in the range 0
to
- * 255
. If no byte is available because the end of the stream
- * has been reached, the value -1
is returned.
- *
- * @return
- * the next byte of data, or -1
if the end of the stream has
- * been reached.
- * @throws IOException
- * Indicates that an I/O error has occurred.
- */
- @Override
- public int read() throws IOException {
- int next = super.read();
-
- if ((next == ';') && (! inQuote)) {
- // we have entered a comment, consume all the bytes from the
- // underlying input stream until we reach a newline character or
- // the end of the stream
- while ((next != '\n') && (next != -1)) {
- next = super.read();
- }
- } else if (next == '\n') {
- inQuote = false;
- } else if (next == '\"') { // we have entered or left a quoted string
- inQuote = (! inQuote);
- }
-
- return next;
- }
-
- /**
- * Reads up to the specified number of data bytes from this input stream
- * into an array of bytes starting at the specified offset. If no bytes are
- * available because the end of this stream has been reached then
- * -1
is returned. Also, If the specified number of bytes is
- * more than the number of remaining data bytes in this input stream, then
- * only the number of remaining data bytes are copied into the byte array.
- *
- * @param b
- * the buffer into which the data bytes are read (must not be
- * null
)
- * @param off
- * the start offset in b
at which the data is written (must
- * be >= 0
and < b.length
)
- * @param len
- * the maximum number of bytes to read into b
(len +
- * off
must be < b.length
)
- * @return
- * the total number of bytes read into the buffer, or -1
if
- * there is no more data because the end of the stream has been reached
- * @throws IOException
- * Indicates that the first byte could not be read into b
- * for some reason other than reaching the end of the stream.
- * @throws IndexOutOfBoundsException
- * Indicates that this method attempted to access an index in
- * b
that was either negative or greater than or equal to
- * b.length
as a result of the given parameters.
- * @throws NullPointerException
- * Indicates that b
is null
.
- */
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- int bytesRead = 0;
-
- // make sure we are supposed to read at least one byte into 'b'
- if (len > 0) {
- int next = read();
-
- if (next == -1) {
- // there are no more bytes to read from this input stream
-
- return -1;
- }
-
- int i = off;
-
- while (next != -1) {
- ++bytesRead;
-
- b[i++] = (byte) next;
-
- if (i >= (off + len)) { // we have read 'len' bytes into 'b'
- break;
- }
-
- try {
- next = read();
- } catch (IOException e) {
- // treat this exception like an end of stream
-
- break;
- }
- }
- }
-
- return bytesRead;
- }
-
- /**
- * Skip over and discard the specified number of bytes from this input
- * stream. This method may, for a variety of reasons, end up skipping some
- * smaller number of bytes, possibly 0
. The actual number of
- * bytes skipped is returned.
- *
- * @param n
- * the number of bytes to be skipped
- * @return
- * the actual number of bytes skipped
- * @throws IOException
- * Indicates that an I/O error has occurred.
- */
- @Override
- public long skip (long n) throws IOException {
- long bytesSkipped = 0;
-
- while ((n > 0) && (read() != -1)) {
- ++bytesSkipped;
- --n;
- }
-
- return bytesSkipped;
- }
-
-}
diff --git a/scanner/LispScanner.java b/scanner/LispScanner.java
deleted file mode 100644
index df6df9b..0000000
--- a/scanner/LispScanner.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter Phase 1 - Lexical Analysis
- */
-
-package scanner;
-
-import java.io.InputStream;
-import java.io.BufferedInputStream;
-import java.io.IOException;
-
-/**
- * A LispScanner
converts a stream of bytes into a stream of Lisp
- * tokens. When the end of stream has been reached a token with a type of
- * Token.Type.EOF
is returned from the nextToken
- * method of this scanner.
- */
-public class LispScanner {
-
- private LispFilterStream inStream;
- private Token currToken;
- private String fileName;
- private int line;
- private int column;
-
- /**
- * Create a new LispScanner
that produces Lisp tokens from the
- * specified input stream.
- *
- * @param in
- * the input stream to obtain Lisp tokens from (must not be
- * null
)
- * @param fileName
- * the name of the file that in
is reading from
- */
- public LispScanner(InputStream in, String fileName) {
- this.inStream = new LispFilterStream(new BufferedInputStream(in));
- this.currToken = null;
- this.fileName = fileName;
- this.line = 1;
- this.column = 0;
- }
-
- /**
- * Returns the same Lisp token returned from the last call to the
- * nextToken
method of this scanner. In the case that no calls
- * to nextToken
have been made yet, this method returns
- * null
.
- *
- * @return
- * the last Lisp token returned from this scanner or null
(if
- * no tokens have been returned from this scanner yet)
- */
- public Token getCurrToken() {
- return currToken;
- }
-
- /**
- * Returns the next Lisp token from this scanner.
- *
- * @return
- * the next Lisp token from this scanner.
- * @throws RuntimeException
- * Indicates that an illegal character or an unterminated quoted string
- * was encountered in the input stream (not counting comments).
- * @throws IOException
- * Indicates that an I/O error has occurred.
- */
- public Token nextToken() throws IOException {
- currToken = retrieveNextToken();
-
- return currToken;
- }
-
- // Retrieve the next Lisp token from 'inStream'.
- //
- // Returns: the next Lisp token found in 'inStream'
- // Precondition: 'inStream' must not be null.
- // Throws: RuntimeException - Indicates that an illegal character or an
- // unterminated quoted string was encountered in
- // 'inStream'.
- // Throws: IOException - Indicates that an I/O error has occurred.
- private Token retrieveNextToken() throws IOException {
- int c;
-
- while ((c = inStream.read()) != -1) {
- char nextChar = (char) c;
-
- ++column;
-
- // determine the type of the Lisp token from the character obtained
- // from 'inStream'
- switch (nextChar) {
- case '\n':
- // we have hit a new line so increment 'line' and reset
- // 'column'
- ++line;
- column = 0;
-
- break;
- case '(':
- return new Token(Token.Type.LEFT_PAREN,
- "(",
- fileName,
- line,
- column);
- case ')':
- return new Token(Token.Type.RIGHT_PAREN,
- ")",
- fileName,
- line,
- column);
- case '\'':
- return new Token(Token.Type.QUOTE_MARK,
- "\'",
- fileName,
- line,
- column);
- case '\"':
- return retrieveString(nextChar);
- default:
- if (Character.isWhitespace(nextChar)) { // skip whitespace
- continue;
- } else if (Character.isDigit(nextChar)) { // number
- return retrieveNumber(nextChar);
- } else if (isLegalIdChar(nextChar)) { // identifier
- return retrieveIdentifier(nextChar);
- } else {
- // 'nextChar' can not start any Lisp token
-
- throw new RuntimeException("illegal character " +
- "\'" + nextChar + "\'" +
- " - line " + line +
- " column " + column);
- }
- }
- }
-
- // we have reached the end of 'inStream' so we return an end-of-file
- // token
- return new Token(Token.Type.EOF, "EOF", fileName, line, column);
- }
-
- // Retrieve a quoted string token from 'inStream'.
- //
- // Parameters: firstDoubleQuote - the opening double quote of this quoted
- // string
- // Returns: a quoted string token obtained from 'instream'
- // Throws: RuntimeException - Indicates that this quoted string was
- // missing its terminating double quote.
- // Throws: IOException - Indicates that an I/O error has occurred.
- // Precondition: 'firstDoubleQuote' must be the leading double quote
- // character of this quoted string and 'inStream' must not
- // be null.
- private Token retrieveString(char firstDoubleQuote) throws IOException {
- StringBuffer text = new StringBuffer();
- int startLine = line;
- int startColumn = column;
- char prevChar = firstDoubleQuote;
-
- text.append(firstDoubleQuote);
-
- int c;
-
- while ((c = inStream.read()) != -1) {
- char nextChar = (char) c;
-
- ++column;
- text.append(nextChar);
-
- switch(nextChar) {
- case '\n':
- ++line;
- column = 0;
-
- break;
- case '\"':
- if (prevChar != '\\') {
- // we have found the terminating double quote
-
- return new Token(Token.Type.STRING,
- text.toString(),
- fileName,
- startLine,
- startColumn);
- }
-
- // this is an escaped double quote
- }
-
- prevChar = nextChar;
- }
-
- // the end of 'inStream' was reached before the terminating double
- // quote
-
- throw new RuntimeException("unterminated quoted string" +
- " - line " + startLine +
- " column " + startColumn);
- }
-
- // Retrieve a number token from 'inStream'.
- //
- // Parameters: firstDigit - the first digit of this number
- // Returns: a number token obtained from 'inStream'
- // Throws: IOException - Indicates that an I/O error has occurred.
- // Precondition: 'firstDigit' must be the first digit of this number and
- // 'inStream' must not be null.
- private Token retrieveNumber(char firstDigit) throws IOException {
- StringBuffer text = new StringBuffer();
- int startColumn = column;
-
- text.append(firstDigit);
- inStream.mark(1);
-
- int c;
-
- while ((c = inStream.read()) != -1) {
- char nextChar = (char) c;
-
- if (Character.isDigit(nextChar)) {
- // 'nextChar' is a digit in this number
-
- text.append(nextChar);
- ++column;
- } else {
- // we have reached the end of the number
-
- inStream.reset(); // unread the last character
-
- return new Token(Token.Type.NUMBER,
- text.toString(),
- fileName,
- line,
- startColumn);
- }
-
- inStream.mark(1);
- }
-
- // there are no more bytes to be read from 'inStream' after this number
- // token
-
- return new Token(Token.Type.NUMBER,
- text.toString(),
- fileName,
- line,
- startColumn);
- }
-
- // Retrieve an identifier token from 'inStream'.
- //
- // Parameters: firstChar - the first character of this identifier
- // Returns: an identifier token obtained from 'inStream'
- // Throws: IOException - Indicates that an I/O error has occurred.
- // Precondition: 'firsChar' must be the first character of this identifier
- // and 'inStream' must not be null.
- private Token retrieveIdentifier(char firstChar) throws IOException {
- StringBuffer text = new StringBuffer();
- int startColumn = column;
-
- text.append(firstChar);
- inStream.mark(1);
-
- int c;
-
- while ((c = inStream.read()) != -1) {
- char nextChar = (char) c;
-
- if (isLegalIdChar(nextChar)) {
- // 'nextChar' is part of the identifier
-
- text.append(nextChar);
- ++column;
- } else {
- // we have reached the end of this identifier
-
- inStream.reset(); // unread the last character
-
- return new Token(Token.Type.IDENTIFIER,
- text.toString(),
- fileName,
- line,
- startColumn);
- }
-
- inStream.mark(1);
- }
-
- // there are no more bytes to be read from 'inStream' after this
- // identifier token
-
- return new Token(Token.Type.IDENTIFIER,
- text.toString(),
- fileName,
- line,
- startColumn);
- }
-
- // Test if a character is legal to be contained within an identifier in
- // Lisp.
- //
- // Returns: 'true' if the character can be found within an identifier in
- // Lisp; 'false' otherwise
- private boolean isLegalIdChar(char c) {
- return ((! Character.isWhitespace(c)) && (c != '\"')
- && (c != '\'')
- && (c != '\\')
- && (c != '`')
- && (c != '(')
- && (c != ')')
- && (c != '[')
- && (c != ']')
- && (c != '#')
- && (c != '.')
- && (c != ';'));
- }
-
-}
diff --git a/scanner/Token.java b/scanner/Token.java
deleted file mode 100644
index c410102..0000000
--- a/scanner/Token.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter Phase 1 - Lexical Analysis
- */
-
-package scanner;
-
-/**
- * A Token
represents a token in Common Lisp.
- */
-public class Token {
-
- /**
- * An enumeration representing all of the types of tokens found in Common
- * Lisp.
- */
- public enum Type {
- /** A left parenthesis token */
- LEFT_PAREN,
-
- /** A right parenthesis token */
- RIGHT_PAREN,
-
- /** A quoted string token */
- STRING,
-
- /** A quote mark */
- QUOTE_MARK,
-
- /** A number token */
- NUMBER,
-
- /** A reserved word token */
- RESERVED,
-
- /** An identifier token */
- IDENTIFIER,
-
- /** An end-of-file token */
- EOF
- }
-
- private Type type;
- private String text;
- private String fName;
- private int line;
- private int column;
-
- /**
- * Create a new token with the specified type, text, file name, line number
- * and column number.
- *
- * @param type
- * the type of this token
- * @param text
- * the text associated with this token
- * @param fName
- * the name of the file that this token is located in
- * @param line
- * the line number that this token is found on
- * @param column
- * the column number that this token is found on
- */
- public Token(Type type, String text, String fName, int line, int column) {
- this.type = type;
- this.text = text;
- this.fName = fName;
- this.line = line;
- this.column = column;
- }
-
- /**
- * Accessor method to determine the type of this token.
- *
- * @return
- * the type of this token
- */
- public Type getType() {
- return type;
- }
-
- /**
- * Accessor method to determine the text associated with this token.
- *
- * @return
- * the text associated with this token
- */
- public String getText() {
- return text;
- }
-
- /**
- * Accessor method to determine the name of the file that this token was
- * located in.
- *
- * @return
- * the name of the file that this token was located in
- */
- public String getFName() {
- return fName;
- }
-
- /**
- * Accessor method to determine the line number that this token was found
- * on.
- *
- * @return
- * the line number this token was found on
- */
- public int getLine() {
- return line;
- }
-
- /**
- * Accessor method to determine the column number that this token was found
- * on.
- *
- * @return
- * the column number this token was found on
- */
- public int getColumn() {
- return column;
- }
-
-}
diff --git a/scanner/package.html b/scanner/package.html
deleted file mode 100644
index 6be4f13..0000000
--- a/scanner/package.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
- Provides the classes necessary to perform a lexical analysis of the Lisp
- programming language.
-
diff --git a/src/scanner/LispFilterStream.class b/src/scanner/LispFilterStream.class
index 4abccba..c520c13 100644
Binary files a/src/scanner/LispFilterStream.class and b/src/scanner/LispFilterStream.class differ
diff --git a/src/scanner/LispFilterStream.java b/src/scanner/LispFilterStream.java
index d9838dc..3758442 100644
--- a/src/scanner/LispFilterStream.java
+++ b/src/scanner/LispFilterStream.java
@@ -1,9 +1,3 @@
-/*
- * Name: Mike Cifelli
- * Course: CIS 443 - Programming Languages
- * Assignment: Lisp Interpreter Phase 1 - Lexical Analysis
- */
-
package scanner;
import java.io.InputStream;
@@ -11,150 +5,48 @@ import java.io.FilterInputStream;
import java.io.IOException;
/**
- * A LispFilterStream
is an input stream that returns the bytes
- * from an underlying input stream with all Lisp comments removed and replaced
- * with newlines.
+ * Replaces Lisp comments with newlines in an input stream.
*/
public class LispFilterStream extends FilterInputStream {
private boolean inQuote;
+ private int nextCharacter;
- /**
- * Creates a LispFilterStream
with the specified underlying
- * InputStream
.
- *
- * @param in
- * the underlying input stream (must not be null
)
- */
public LispFilterStream(InputStream in) {
super(in);
-
inQuote = false;
+ nextCharacter = 0;
}
- /**
- * Reads the next byte of data from this input stream. The value byte is
- * returned as an int
in the range 0
to
- * 255
. If no byte is available because the end of the stream
- * has been reached, the value -1
is returned.
- *
- * @return
- * the next byte of data, or -1
if the end of the stream has
- * been reached.
- * @throws IOException
- * Indicates that an I/O error has occurred.
- */
@Override
public int read() throws IOException {
- int next = super.read();
+ nextCharacter = super.read();
- if ((next == ';') && (! inQuote)) {
- // we have entered a comment, consume all the bytes from the
- // underlying input stream until we reach a newline character or
- // the end of the stream
- while ((next != '\n') && (next != -1)) {
- next = super.read();
- }
- } else if (next == '\n') {
- inQuote = false;
- } else if (next == '\"') { // we have entered or left a quoted string
- inQuote = (! inQuote);
+ if (haveEnteredComment()) {
+ consumeAllBytesInComment();
+ } else if (haveEncounteredStringBoundary()) {
+ inQuote = (!inQuote);
}
- return next;
+ return nextCharacter;
}
- /**
- * Reads up to the specified number of data bytes from this input stream
- * into an array of bytes starting at the specified offset. If no bytes are
- * available because the end of this stream has been reached then
- * -1
is returned. Also, If the specified number of bytes is
- * more than the number of remaining data bytes in this input stream, then
- * only the number of remaining data bytes are copied into the byte array.
- *
- * @param b
- * the buffer into which the data bytes are read (must not be
- * null
)
- * @param off
- * the start offset in b
at which the data is written (must
- * be >= 0
and < b.length
)
- * @param len
- * the maximum number of bytes to read into b
(len +
- * off
must be < b.length
)
- * @return
- * the total number of bytes read into the buffer, or -1
if
- * there is no more data because the end of the stream has been reached
- * @throws IOException
- * Indicates that the first byte could not be read into b
- * for some reason other than reaching the end of the stream.
- * @throws IndexOutOfBoundsException
- * Indicates that this method attempted to access an index in
- * b
that was either negative or greater than or equal to
- * b.length
as a result of the given parameters.
- * @throws NullPointerException
- * Indicates that b
is null
.
- */
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- int bytesRead = 0;
-
- // make sure we are supposed to read at least one byte into 'b'
- if (len > 0) {
- int next = read();
-
- if (next == -1) {
- // there are no more bytes to read from this input stream
-
- return -1;
- }
-
- int i = off;
-
- while (next != -1) {
- ++bytesRead;
-
- b[i++] = (byte) next;
-
- if (i >= (off + len)) { // we have read 'len' bytes into 'b'
- break;
- }
-
- try {
- next = read();
- } catch (IOException e) {
- // treat this exception like an end of stream
-
- break;
- }
- }
+ private void consumeAllBytesInComment() throws IOException {
+ while (stillInComment()) {
+ nextCharacter = super.read();
}
-
- return bytesRead;
}
- /**
- * Skip over and discard the specified number of bytes from this input
- * stream. This method may, for a variety of reasons, end up skipping some
- * smaller number of bytes, possibly 0
. The actual number of
- * bytes skipped is returned.
- *
- * @param n
- * the number of bytes to be skipped
- * @return
- * the actual number of bytes skipped
- * @throws IOException
- * Indicates that an I/O error has occurred.
- */
- @Override
- public long skip (long n) throws IOException {
- long bytesSkipped = 0;
+ private boolean stillInComment() {
+ return (nextCharacter != '\n') && (nextCharacter != -1);
+ }
- while ((n > 0) && (read() != -1)) {
- ++bytesSkipped;
- --n;
- }
+ private boolean haveEnteredComment() {
+ return (nextCharacter == ';') && (!inQuote);
+ }
- return bytesSkipped;
+ private boolean haveEncounteredStringBoundary() {
+ return nextCharacter == '\"';
}
}
diff --git a/test/scanner/LispFilterStreamTester.java b/test/scanner/LispFilterStreamTester.java
index 3de7dc6..bf27687 100644
--- a/test/scanner/LispFilterStreamTester.java
+++ b/test/scanner/LispFilterStreamTester.java
@@ -8,7 +8,7 @@ import org.junit.Test;
public class LispFilterStreamTester {
private LispFilterStream lispFilterStream;
-
+
@Before
public void setUp() throws Exception {
lispFilterStream = new LispFilterStream(null);
@@ -19,19 +19,4 @@ public class LispFilterStreamTester {
fail("Not yet implemented");
}
- @Test
- public void testReadByteArrayIntInt() {
- fail("Not yet implemented");
- }
-
- @Test
- public void testSkip() {
- fail("Not yet implemented");
- }
-
- @Test
- public void testLispFilterStream() {
- fail("Not yet implemented");
- }
-
}