Minor cleaning in the eval pacakge, added unit tests for the sexpression package
This commit is contained in:
parent
7b7556cc65
commit
62a509eb4b
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>APPLY</code> represents the APPLY function in Lisp.
|
* <code>APPLY</code> represents the APPLY function in Lisp.
|
||||||
|
@ -20,9 +11,8 @@ public class APPLY extends LispFunction {
|
||||||
* Call APPLY with the specified argument list.
|
* Call APPLY with the specified argument list.
|
||||||
*
|
*
|
||||||
* @param argList
|
* @param argList
|
||||||
* the list of arguments to be sent to APPLY (MUST BE A PROPER LIST)
|
* the list of arguments to be sent to APPLY (MUST BE A PROPER LIST)
|
||||||
* @return
|
* @return the result of evaluating APPLY on <code>argList</code>
|
||||||
* the result of evaluating APPLY on <code>argList</code>
|
|
||||||
*/
|
*/
|
||||||
public static SExpression apply(Cons argList) {
|
public static SExpression apply(Cons argList) {
|
||||||
return new APPLY().call(argList);
|
return new APPLY().call(argList);
|
||||||
|
@ -38,16 +28,15 @@ public class APPLY extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength != NUM_ARGS) {
|
if (argListLength != NUM_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("APPLY"), argList);
|
Cons originalSExpr = new Cons(new Symbol("APPLY"), argList);
|
||||||
String errMsg = "too " +
|
String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to APPLY: "
|
||||||
((argListLength > NUM_ARGS) ? "many" : "few") +
|
+ originalSExpr;
|
||||||
" arguments given to APPLY: " + originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression car = argList.getCar(); // function name
|
SExpression car = argList.getCar(); // function name
|
||||||
Cons cdr = (Cons) argList.getCdr();
|
Cons cdr = (Cons) argList.getCdr();
|
||||||
SExpression cadr = cdr.getCar(); // argument list
|
SExpression cadr = cdr.getCar(); // argument list
|
||||||
|
|
||||||
// make sure the second argument is a list
|
// make sure the second argument is a list
|
||||||
if (cadr.listp()) {
|
if (cadr.listp()) {
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>ATOM</code> represents the ATOM function in Lisp.
|
* <code>ATOM</code> represents the ATOM function in Lisp.
|
||||||
|
@ -27,9 +17,8 @@ public class ATOM extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength != NUM_ARGS) {
|
if (argListLength != NUM_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("ATOM"), argList);
|
Cons originalSExpr = new Cons(new Symbol("ATOM"), argList);
|
||||||
String errMsg = "too " +
|
String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to ATOM: "
|
||||||
((argListLength > NUM_ARGS) ? "many" : "few") +
|
+ originalSExpr;
|
||||||
" arguments given to ATOM: " + originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>CAR</code> represents the CAR function in Lisp.
|
* <code>CAR</code> represents the CAR function in Lisp.
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>CDR</code> represents the CDR function in Lisp.
|
* <code>CDR</code> represents the CDR function in Lisp.
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>COND</code> represents the COND form in Lisp.
|
* <code>COND</code> represents the COND form in Lisp.
|
||||||
|
@ -22,8 +13,8 @@ public class COND extends LispFunction {
|
||||||
return Nil.getUniqueInstance();
|
return Nil.getUniqueInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argCar = argList.getCar(); // first clause
|
SExpression argCar = argList.getCar(); // first clause
|
||||||
Cons argCdr = (Cons) argList.getCdr(); // list of remaining clauses
|
Cons argCdr = (Cons) argList.getCdr(); // list of remaining clauses
|
||||||
|
|
||||||
// make sure the first clause is a list and is not NIL
|
// make sure the first clause is a list and is not NIL
|
||||||
if (argCar.consp()) {
|
if (argCar.consp()) {
|
||||||
|
@ -58,16 +49,13 @@ public class COND extends LispFunction {
|
||||||
return Nil.getUniqueInstance();
|
return Nil.getUniqueInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RuntimeException("COND: clause " + argCar +
|
throw new RuntimeException("COND: clause " + argCar + " should be a list");
|
||||||
" should be a list");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the arguments passed to this Lisp function should be
|
* Determine if the arguments passed to this Lisp function should be evaluated.
|
||||||
* evaluated.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return <code>false</code>
|
||||||
* <code>false</code>
|
|
||||||
*/
|
*/
|
||||||
public boolean evaluateArguments() {
|
public boolean evaluateArguments() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>CONS</code> represents the CONS function in Lisp.
|
* <code>CONS</code> represents the CONS function in Lisp.
|
||||||
|
@ -26,9 +17,8 @@ public class CONS extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength != NUM_ARGS) {
|
if (argListLength != NUM_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("CONS"), argList);
|
Cons originalSExpr = new Cons(new Symbol("CONS"), argList);
|
||||||
String errMsg = "too " +
|
String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to CONS: "
|
||||||
((argListLength > NUM_ARGS) ? "many" : "few") +
|
+ originalSExpr;
|
||||||
" arguments given to CONS: " + originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,9 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import sexpression.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>DEFUN</code> represents the DEFUN form in Lisp.
|
* <code>DEFUN</code> represents the DEFUN form in Lisp.
|
||||||
*/
|
*/
|
||||||
|
@ -28,16 +19,15 @@ public class DEFUN extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength < MIN_ARGS) {
|
if (argListLength < MIN_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("DEFUN"), argList);
|
Cons originalSExpr = new Cons(new Symbol("DEFUN"), argList);
|
||||||
String errMsg = "too few arguments given to DEFUN: " +
|
String errMsg = "too few arguments given to DEFUN: " + originalSExpr;
|
||||||
originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression name = argList.getCar(); // name of the function
|
SExpression name = argList.getCar(); // name of the function
|
||||||
|
|
||||||
// make sure the function name is a symbol
|
// make sure the function name is a symbol
|
||||||
if (! name.symbolp()) {
|
if (!name.symbolp()) {
|
||||||
throw new RuntimeException("DEFUN: " + name + " is not a symbol");
|
throw new RuntimeException("DEFUN: " + name + " is not a symbol");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,14 +35,13 @@ public class DEFUN extends LispFunction {
|
||||||
SExpression cadr = cdr.getCar();
|
SExpression cadr = cdr.getCar();
|
||||||
|
|
||||||
// make sure the list of arguments (lambda list) is a proper list
|
// make sure the list of arguments (lambda list) is a proper list
|
||||||
if (! cadr.listp()) {
|
if (!cadr.listp()) {
|
||||||
throw new RuntimeException("DEFUN: " + cadr + " is not a list");
|
throw new RuntimeException("DEFUN: " + cadr + " is not a list");
|
||||||
} else if (EVAL.isDotted((Cons) cadr)) {
|
} else if (EVAL.isDotted((Cons) cadr)) {
|
||||||
throw new RuntimeException("DEFUN: " + cadr +
|
throw new RuntimeException("DEFUN: " + cadr + " is not a proper list");
|
||||||
" is not a proper list");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cons lambdaList = (Cons) cadr; // lambda list of the function
|
Cons lambdaList = (Cons) cadr; // lambda list of the function
|
||||||
|
|
||||||
// list of S-expressions making up the body of the function
|
// list of S-expressions making up the body of the function
|
||||||
Cons body = (Cons) cdr.getCdr();
|
Cons body = (Cons) cdr.getCdr();
|
||||||
|
@ -61,23 +50,19 @@ public class DEFUN extends LispFunction {
|
||||||
|
|
||||||
// give a warning if this function has already been defined
|
// give a warning if this function has already been defined
|
||||||
if (functionTable.containsKey(name.toString())) {
|
if (functionTable.containsKey(name.toString())) {
|
||||||
System.out.println("WARNING: redefining function " +
|
System.out.println("WARNING: redefining function " + name.toString());
|
||||||
name.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// place the function in the function table
|
// place the function in the function table
|
||||||
functionTable.put(name.toString(),
|
functionTable.put(name.toString(), new UserDefinedFunction(name.toString(), lambdaList, body));
|
||||||
new UserDefinedFunction(name.toString(), lambdaList, body));
|
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the arguments passed to this Lisp function should be
|
* Determine if the arguments passed to this Lisp function should be evaluated.
|
||||||
* evaluated.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return <code>false</code>
|
||||||
* <code>false</code>
|
|
||||||
*/
|
*/
|
||||||
public boolean evaluateArguments() {
|
public boolean evaluateArguments() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.LispNumber;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>DIVIDE</code> represents the '/' function in Lisp.
|
* <code>DIVIDE</code> represents the '/' function in Lisp.
|
||||||
|
@ -22,8 +12,7 @@ public class DIVIDE extends LispFunction {
|
||||||
if (argList.nullp()) {
|
if (argList.nullp()) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("/"), argList);
|
Cons originalSExpr = new Cons(new Symbol("/"), argList);
|
||||||
|
|
||||||
throw new RuntimeException("too few arguments given to /: " +
|
throw new RuntimeException("too few arguments given to /: " + originalSExpr);
|
||||||
originalSExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argFirst = argList.getCar();
|
SExpression argFirst = argList.getCar();
|
||||||
|
@ -44,8 +33,7 @@ public class DIVIDE extends LispFunction {
|
||||||
// make sure that the next argument is a number as well
|
// make sure that the next argument is a number as well
|
||||||
if (argSecond.numberp()) {
|
if (argSecond.numberp()) {
|
||||||
LispNumber num2 = (LispNumber) argSecond;
|
LispNumber num2 = (LispNumber) argSecond;
|
||||||
LispNumber quotient = new LispNumber(num1.getValue() /
|
LispNumber quotient = new LispNumber(num1.getValue() / num2.getValue());
|
||||||
num2.getValue());
|
|
||||||
SExpression argCddr = argRest.getCdr();
|
SExpression argCddr = argRest.getCdr();
|
||||||
|
|
||||||
if (argCddr.consp()) {
|
if (argCddr.consp()) {
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>EQ</code> represents the EQ function in Lisp.
|
* <code>EQ</code> represents the EQ function in Lisp.
|
||||||
|
@ -27,20 +17,18 @@ public class EQ extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength != NUM_ARGS) {
|
if (argListLength != NUM_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("EQ"), argList);
|
Cons originalSExpr = new Cons(new Symbol("EQ"), argList);
|
||||||
String errMsg = "too " +
|
String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to EQ: "
|
||||||
((argListLength > NUM_ARGS) ? "many" : "few") +
|
+ originalSExpr;
|
||||||
" arguments given to EQ: " + originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argOne = argList.getCar(); // first argument
|
SExpression argOne = argList.getCar(); // first argument
|
||||||
Cons cdr = (Cons) argList.getCdr();
|
Cons cdr = (Cons) argList.getCdr();
|
||||||
SExpression argTwo = cdr.getCar(); // second argumnet
|
SExpression argTwo = cdr.getCar(); // second argumnet
|
||||||
|
|
||||||
if (argOne.atomp() && argTwo.atomp()) {
|
if (argOne.atomp() && argTwo.atomp()) {
|
||||||
return ((argOne.toString().equals(argTwo.toString()))
|
return ((argOne.toString().equals(argTwo.toString())) ? Symbol.T : Nil.getUniqueInstance());
|
||||||
? Symbol.T : Nil.getUniqueInstance());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((argOne == argTwo) ? Symbol.T : Nil.getUniqueInstance());
|
return ((argOne == argTwo) ? Symbol.T : Nil.getUniqueInstance());
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>EQUAL</code> represents the EQUAL function in Lisp.
|
* <code>EQUAL</code> represents the EQUAL function in Lisp.
|
||||||
|
@ -27,16 +17,15 @@ public class EQUAL extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength != NUM_ARGS) {
|
if (argListLength != NUM_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("EQUAL"), argList);
|
Cons originalSExpr = new Cons(new Symbol("EQUAL"), argList);
|
||||||
String errMsg = "too " +
|
String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to EQUAL: "
|
||||||
((argListLength > NUM_ARGS) ? "many" : "few") +
|
+ originalSExpr;
|
||||||
" arguments given to EQUAL: " + originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argOne = argList.getCar(); // first argument
|
SExpression argOne = argList.getCar(); // first argument
|
||||||
Cons cdr = (Cons) argList.getCdr();
|
Cons cdr = (Cons) argList.getCdr();
|
||||||
SExpression argTwo = cdr.getCar(); // second argumnet
|
SExpression argTwo = cdr.getCar(); // second argumnet
|
||||||
|
|
||||||
if (argOne.consp() && argTwo.consp()) {
|
if (argOne.consp() && argTwo.consp()) {
|
||||||
Cons listOne = (Cons) argOne;
|
Cons listOne = (Cons) argOne;
|
||||||
|
@ -46,17 +35,13 @@ public class EQUAL extends LispFunction {
|
||||||
SExpression listOneCdr = listOne.getCdr();
|
SExpression listOneCdr = listOne.getCdr();
|
||||||
SExpression listTwoCdr = listTwo.getCdr();
|
SExpression listTwoCdr = listTwo.getCdr();
|
||||||
|
|
||||||
SExpression carEqual =
|
SExpression carEqual = call(new Cons(listOneCar, LIST.makeList(listTwoCar)));
|
||||||
call(new Cons(listOneCar, LIST.makeList(listTwoCar)));
|
SExpression cdrEqual = call(new Cons(listOneCdr, LIST.makeList(listTwoCdr)));
|
||||||
SExpression cdrEqual =
|
|
||||||
call(new Cons(listOneCdr, LIST.makeList(listTwoCdr)));
|
|
||||||
|
|
||||||
return (((carEqual == Symbol.T) && (cdrEqual == Symbol.T))
|
return (((carEqual == Symbol.T) && (cdrEqual == Symbol.T)) ? Symbol.T : Nil.getUniqueInstance());
|
||||||
? Symbol.T : Nil.getUniqueInstance());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((argOne.toString().equals(argTwo.toString()))
|
return ((argOne.toString().equals(argTwo.toString())) ? Symbol.T : Nil.getUniqueInstance());
|
||||||
? Symbol.T : Nil.getUniqueInstance());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.LispNumber;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>EQUALSP</code> represents the '=' function in Lisp.
|
* <code>EQUALSP</code> represents the '=' function in Lisp.
|
||||||
|
@ -23,8 +12,7 @@ public class EQUALSP extends LispFunction {
|
||||||
if (argList.nullp()) {
|
if (argList.nullp()) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("="), argList);
|
Cons originalSExpr = new Cons(new Symbol("="), argList);
|
||||||
|
|
||||||
throw new RuntimeException("too few arguments given to =: " +
|
throw new RuntimeException("too few arguments given to =: " + originalSExpr);
|
||||||
originalSExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression firstArg = argList.getCar();
|
SExpression firstArg = argList.getCar();
|
||||||
|
|
|
@ -1,27 +1,16 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import sexpression.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>EVAL</code> represents the EVAL function in Lisp.
|
* <code>EVAL</code> represents the EVAL function in Lisp.
|
||||||
*/
|
*/
|
||||||
public class EVAL extends LispFunction {
|
public class EVAL extends LispFunction {
|
||||||
|
|
||||||
// A table to contain all the built-in and user-defined Lisp functions.
|
// A table to contain all the built-in and user-defined Lisp functions.
|
||||||
private static HashMap<String, LispFunction> functionTable =
|
private static HashMap<String, LispFunction> functionTable = new HashMap<String, LispFunction>();
|
||||||
new HashMap<String, LispFunction>();
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// place all of the built-in functions into the function table
|
// place all of the built-in functions into the function table
|
||||||
|
@ -63,8 +52,7 @@ public class EVAL extends LispFunction {
|
||||||
/**
|
/**
|
||||||
* Retrieve the function table.
|
* Retrieve the function table.
|
||||||
*
|
*
|
||||||
* @return
|
* @return the function table
|
||||||
* the function table
|
|
||||||
*/
|
*/
|
||||||
public static HashMap<String, LispFunction> getFunctionTable() {
|
public static HashMap<String, LispFunction> getFunctionTable() {
|
||||||
return functionTable;
|
return functionTable;
|
||||||
|
@ -74,10 +62,8 @@ public class EVAL extends LispFunction {
|
||||||
* Look up a function by its name.
|
* Look up a function by its name.
|
||||||
*
|
*
|
||||||
* @param functionName
|
* @param functionName
|
||||||
* the name of the function to look up
|
* the name of the function to look up
|
||||||
* @return
|
* @return the function with the name <code>functionName</code> if it exists; null otherwise
|
||||||
* the function with the name <code>functionName</code> if it exists; null
|
|
||||||
* otherwise
|
|
||||||
*/
|
*/
|
||||||
public static LispFunction lookupFunction(String functionName) {
|
public static LispFunction lookupFunction(String functionName) {
|
||||||
return functionTable.get(functionName);
|
return functionTable.get(functionName);
|
||||||
|
@ -87,9 +73,8 @@ public class EVAL extends LispFunction {
|
||||||
* Look up a symbol's value using its name.
|
* Look up a symbol's value using its name.
|
||||||
*
|
*
|
||||||
* @param symbolName
|
* @param symbolName
|
||||||
* the name of the symbol to look up (must not be null)
|
* the name of the symbol to look up (must not be null)
|
||||||
* @return
|
* @return the value of <code>symbolName</code> if it has one; null otherwise
|
||||||
* the value of <code>symbolName</code> if it has one; null otherwise
|
|
||||||
*/
|
*/
|
||||||
public static SExpression lookupSymbol(String symbolName) {
|
public static SExpression lookupSymbol(String symbolName) {
|
||||||
if (symbolName.equals("NIL")) {
|
if (symbolName.equals("NIL")) {
|
||||||
|
@ -107,10 +92,8 @@ public class EVAL extends LispFunction {
|
||||||
* Determine if the given list is dotted.
|
* Determine if the given list is dotted.
|
||||||
*
|
*
|
||||||
* @param list
|
* @param list
|
||||||
* the list to be tested (must not be null)
|
* the list to be tested (must not be null)
|
||||||
* @return
|
* @return <code>true</code> if <code>list</code> is dotted; <code>false</code> otherwise
|
||||||
* <code>true</code> if <code>list</code> is dotted; <code>false</code>
|
|
||||||
* otherwise
|
|
||||||
*/
|
*/
|
||||||
public static boolean isDotted(Cons list) {
|
public static boolean isDotted(Cons list) {
|
||||||
if (list.nullp()) {
|
if (list.nullp()) {
|
||||||
|
@ -131,9 +114,8 @@ public class EVAL extends LispFunction {
|
||||||
* Evaluate the given S-expression.
|
* Evaluate the given S-expression.
|
||||||
*
|
*
|
||||||
* @param sexpr
|
* @param sexpr
|
||||||
* the S-expression to evaluate
|
* the S-expression to evaluate
|
||||||
* @return
|
* @return the value of <code>sexpr</code>
|
||||||
* the value of <code>sexpr</code>
|
|
||||||
*/
|
*/
|
||||||
public static SExpression eval(SExpression sexpr) {
|
public static SExpression eval(SExpression sexpr) {
|
||||||
Cons expList = LIST.makeList(sexpr);
|
Cons expList = LIST.makeList(sexpr);
|
||||||
|
@ -152,9 +134,8 @@ public class EVAL extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength != NUM_ARGS) {
|
if (argListLength != NUM_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("EVAL"), argList);
|
Cons originalSExpr = new Cons(new Symbol("EVAL"), argList);
|
||||||
String errMsg = "too " +
|
String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to EVAL: "
|
||||||
((argListLength > NUM_ARGS) ? "many" : "few") +
|
+ originalSExpr;
|
||||||
" arguments given to EVAL: " + originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
@ -166,7 +147,7 @@ public class EVAL extends LispFunction {
|
||||||
return evaluateList((Cons) arg);
|
return evaluateList((Cons) arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return arg; // 'arg' is NIL
|
return arg; // 'arg' is NIL
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg.symbolp()) {
|
if (arg.symbolp()) {
|
||||||
|
@ -179,7 +160,7 @@ public class EVAL extends LispFunction {
|
||||||
throw new RuntimeException("variable " + arg + " has no value");
|
throw new RuntimeException("variable " + arg + " has no value");
|
||||||
}
|
}
|
||||||
|
|
||||||
return arg; // 'arg' is a NUMBER or a STRING
|
return arg; // 'arg' is a NUMBER or a STRING
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the specified list.
|
// Evaluate the specified list.
|
||||||
|
@ -212,8 +193,7 @@ public class EVAL extends LispFunction {
|
||||||
|
|
||||||
// make sure the list of arguments is not dotted
|
// make sure the list of arguments is not dotted
|
||||||
if (isDotted(args)) {
|
if (isDotted(args)) {
|
||||||
throw new RuntimeException("argument list given to " + car +
|
throw new RuntimeException("argument list given to " + car + " is dotted: " + list);
|
||||||
" is dotted: " + list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine if we should evaluate the arguments that will be
|
// determine if we should evaluate the arguments that will be
|
||||||
|
@ -226,15 +206,14 @@ public class EVAL extends LispFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// the list of arguments is not a list!
|
// the list of arguments is not a list!
|
||||||
throw new RuntimeException("argument list given to " + car +
|
throw new RuntimeException("argument list given to " + car + " is dotted: " + list);
|
||||||
" is dotted: " + list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate a list of arguments for a function.
|
// Evaluate a list of arguments for a function.
|
||||||
//
|
//
|
||||||
// Parameters: arguments - 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
|
// Returns: a list consisting of the values of the S-expressions found in
|
||||||
// 'arguments'
|
// 'arguments'
|
||||||
// Precondition: 'arguments' must not be null.
|
// Precondition: 'arguments' must not be null.
|
||||||
private Cons evaluateArgList(Cons arguments) {
|
private Cons evaluateArgList(Cons arguments) {
|
||||||
if (arguments.nullp()) {
|
if (arguments.nullp()) {
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
public class EXIT extends LispFunction {
|
public class EXIT extends LispFunction {
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>FUNCALL</code> represents the FUNCALL function in Lisp.
|
* <code>FUNCALL</code> represents the FUNCALL function in Lisp.
|
||||||
|
@ -21,8 +12,7 @@ public class FUNCALL extends LispFunction {
|
||||||
if (argList.nullp()) {
|
if (argList.nullp()) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("FUNCALL"), argList);
|
Cons originalSExpr = new Cons(new Symbol("FUNCALL"), argList);
|
||||||
|
|
||||||
throw new RuntimeException("too few arguments given to FUNCALL: " +
|
throw new RuntimeException("too few arguments given to FUNCALL: " + originalSExpr);
|
||||||
originalSExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression cdr = argList.getCdr();
|
SExpression cdr = argList.getCdr();
|
||||||
|
|
|
@ -1,17 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.LispNumber;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>GREATERP</code> represents the '>' function in Lisp.
|
* <code>GREATERP</code> represents the '>' function in Lisp.
|
||||||
|
@ -23,8 +12,7 @@ public class GREATERP extends LispFunction {
|
||||||
if (argList.nullp()) {
|
if (argList.nullp()) {
|
||||||
Cons originalSExpr = new Cons(new Symbol(">"), argList);
|
Cons originalSExpr = new Cons(new Symbol(">"), argList);
|
||||||
|
|
||||||
throw new RuntimeException("too few arguments given to >: " +
|
throw new RuntimeException("too few arguments given to >: " + originalSExpr);
|
||||||
originalSExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression firstArg = argList.getCar();
|
SExpression firstArg = argList.getCar();
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>LAMBDA</code> represents the LAMBDA form in Lisp.
|
* <code>LAMBDA</code> represents the LAMBDA form in Lisp.
|
||||||
|
@ -20,10 +11,9 @@ public class LAMBDA extends LispFunction {
|
||||||
* Determine if the given S-expression is a lambda expression.
|
* Determine if the given S-expression is a lambda expression.
|
||||||
*
|
*
|
||||||
* @param sexpr
|
* @param sexpr
|
||||||
* the S-expression to test (must not be null)
|
* the S-expression to test (must not be null)
|
||||||
* @return
|
* @return <code>true</code> if <code>sexpr</code> is a valid lambda expression;
|
||||||
* <code>true</code> if <code>sexpr</code> is a valid lambda expression;
|
* <code>false</code> otherwise
|
||||||
* <code>false</code> otherwise
|
|
||||||
*/
|
*/
|
||||||
public static boolean isLambdaExpression(SExpression sexpr) {
|
public static boolean isLambdaExpression(SExpression sexpr) {
|
||||||
if (sexpr.consp()) {
|
if (sexpr.consp()) {
|
||||||
|
@ -36,23 +26,21 @@ public class LAMBDA extends LispFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an internal representation of a user-defined function from the
|
* Create an internal representation of a user-defined function from the specified lambda
|
||||||
* specified lambda expression.
|
* expression.
|
||||||
*
|
*
|
||||||
* @param lexpr
|
* @param lexpr
|
||||||
* the lambda expression to create the function from (must not be null)
|
* the lambda expression to create the function from (must not be null)
|
||||||
* @return
|
* @return an internal representation of a user-defined function created from <code>lexpr</code>
|
||||||
* an internal representation of a user-defined function created from
|
|
||||||
* <code>lexpr</code>
|
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* Indicates that <code>lexpr</code> is not a valid lambda expression.
|
* Indicates that <code>lexpr</code> is not a valid lambda expression.
|
||||||
*/
|
*/
|
||||||
public static UserDefinedFunction createFunction(Cons lexpr) {
|
public static UserDefinedFunction createFunction(Cons lexpr) {
|
||||||
LAMBDA lambda = new LAMBDA();
|
LAMBDA lambda = new LAMBDA();
|
||||||
SExpression cdr = lexpr.getCdr();
|
SExpression cdr = lexpr.getCdr();
|
||||||
|
|
||||||
// make sure lexpr is a proper list
|
// make sure lexpr is a proper list
|
||||||
if (! cdr.consp()) {
|
if (!cdr.consp()) {
|
||||||
throw new RuntimeException("invalid lambda expression");
|
throw new RuntimeException("invalid lambda expression");
|
||||||
} else if (EVAL.isDotted((Cons) cdr)) {
|
} else if (EVAL.isDotted((Cons) cdr)) {
|
||||||
throw new RuntimeException("dotted lambda expression " + lexpr);
|
throw new RuntimeException("dotted lambda expression " + lexpr);
|
||||||
|
@ -73,8 +61,7 @@ public class LAMBDA extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength < MIN_ARGS) {
|
if (argListLength < MIN_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("LAMBDA"), argList);
|
Cons originalSExpr = new Cons(new Symbol("LAMBDA"), argList);
|
||||||
String errMsg = "too few arguments given to LAMBDA: " +
|
String errMsg = "too few arguments given to LAMBDA: " + originalSExpr;
|
||||||
originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
@ -82,11 +69,10 @@ public class LAMBDA extends LispFunction {
|
||||||
SExpression car = argList.getCar();
|
SExpression car = argList.getCar();
|
||||||
|
|
||||||
// make sure the list of arguments is a proper list
|
// make sure the list of arguments is a proper list
|
||||||
if (! car.listp()) {
|
if (!car.listp()) {
|
||||||
throw new RuntimeException("LAMBDA: " + car + " is not a list");
|
throw new RuntimeException("LAMBDA: " + car + " is not a list");
|
||||||
} else if (EVAL.isDotted((Cons) car)) {
|
} else if (EVAL.isDotted((Cons) car)) {
|
||||||
throw new RuntimeException("LAMBDA: " + car +
|
throw new RuntimeException("LAMBDA: " + car + " must be a proper list");
|
||||||
" must be a proper list");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cons lambdaList = (Cons) car;
|
Cons lambdaList = (Cons) car;
|
||||||
|
@ -98,11 +84,9 @@ public class LAMBDA extends LispFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the arguments passed to this Lisp function should be
|
* Determine if the arguments passed to this Lisp function should be evaluated.
|
||||||
* evaluated.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return <code>false</code>
|
||||||
* <code>false</code>
|
|
||||||
*/
|
*/
|
||||||
public boolean evaluateArguments() {
|
public boolean evaluateArguments() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.LispNumber;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>LENGTH</code> represents the LENGTH function in Lisp.
|
* <code>LENGTH</code> represents the LENGTH function in Lisp.
|
||||||
|
|
|
@ -1,17 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.LispNumber;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>LESSP</code> represents the '<' function in Lisp.
|
* <code>LESSP</code> represents the '<' function in Lisp.
|
||||||
|
@ -23,8 +12,7 @@ public class LESSP extends LispFunction {
|
||||||
if (argList.nullp()) {
|
if (argList.nullp()) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("<"), argList);
|
Cons originalSExpr = new Cons(new Symbol("<"), argList);
|
||||||
|
|
||||||
throw new RuntimeException("too few arguments given to <: " +
|
throw new RuntimeException("too few arguments given to <: " + originalSExpr);
|
||||||
originalSExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression firstArg = argList.getCar();
|
SExpression firstArg = argList.getCar();
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>LET</code> represents the LET form in Lisp.
|
* <code>LET</code> represents the LET form in Lisp.
|
||||||
|
@ -49,22 +40,19 @@ public class LET extends LispFunction {
|
||||||
// Add a list of variables and their values to the specified symbol table.
|
// Add a list of variables and their values to the specified symbol table.
|
||||||
//
|
//
|
||||||
// Parameters: environment - the symbol table to add the variables and
|
// Parameters: environment - the symbol table to add the variables and
|
||||||
// their values to (must not be null)
|
// their values to (must not be null)
|
||||||
// vars - a list of variable/value pairs (must be either a
|
// vars - a list of variable/value pairs (must be either a
|
||||||
// proper list of pairs or NIL)
|
// proper list of pairs or NIL)
|
||||||
// Throws: RuntimeException - Indicates that 'vars' is not a proper list or
|
// Throws: RuntimeException - Indicates that 'vars' is not a proper list or
|
||||||
// that it contains an member that is not a
|
// that it contains an member that is not a
|
||||||
// variable/value pair.
|
// variable/value pair.
|
||||||
// Precondition: 'environment' and 'vars' must not be null.
|
// Precondition: 'environment' and 'vars' must not be null.
|
||||||
// Postcondition: All of the variables in 'vars' have been placed into
|
// Postcondition: All of the variables in 'vars' have been placed into
|
||||||
// 'environment' with their values.
|
// 'environment' with their values.
|
||||||
private void addVariablesToTable(SymbolTable environment,
|
private void addVariablesToTable(SymbolTable environment, SExpression vars) {
|
||||||
SExpression vars) {
|
|
||||||
// makes sure the list of variable/value pairs is a list
|
// makes sure the list of variable/value pairs is a list
|
||||||
if (! vars.listp()) {
|
if (!vars.listp()) {
|
||||||
throw new RuntimeException("LET: " + vars +
|
throw new RuntimeException("LET: " + vars + " is not a properly formatted" + " variable/value pair list");
|
||||||
" is not a properly formatted" +
|
|
||||||
" variable/value pair list");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all variables in 'vars' to 'environment'
|
// add all variables in 'vars' to 'environment'
|
||||||
|
@ -73,10 +61,9 @@ public class LET extends LispFunction {
|
||||||
SExpression varListCar = varList.getCar();
|
SExpression varListCar = varList.getCar();
|
||||||
|
|
||||||
// make sure this variable/value pair is a list
|
// make sure this variable/value pair is a list
|
||||||
if (! varListCar.consp()) {
|
if (!varListCar.consp()) {
|
||||||
throw new RuntimeException("LET: " + varListCar +
|
throw new RuntimeException("LET: " + varListCar + " is not a properly formatted"
|
||||||
" is not a properly formatted" +
|
+ " variable/value pair");
|
||||||
" variable/value pair");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cons varSpec = (Cons) varListCar;
|
Cons varSpec = (Cons) varListCar;
|
||||||
|
@ -84,9 +71,8 @@ public class LET extends LispFunction {
|
||||||
SExpression varSpecCdr = varSpec.getCdr();
|
SExpression varSpecCdr = varSpec.getCdr();
|
||||||
|
|
||||||
// make sure this variable pair has a value associated with it
|
// make sure this variable pair has a value associated with it
|
||||||
if (! varSpecCdr.consp()) {
|
if (!varSpecCdr.consp()) {
|
||||||
throw new RuntimeException("LET: illegal variable " +
|
throw new RuntimeException("LET: illegal variable " + "specification " + varSpec);
|
||||||
"specification " + varSpec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cons varValue = (Cons) varSpecCdr;
|
Cons varValue = (Cons) varSpecCdr;
|
||||||
|
@ -94,9 +80,8 @@ public class LET extends LispFunction {
|
||||||
|
|
||||||
// make sure there are no more members of this variable/value pair
|
// make sure there are no more members of this variable/value pair
|
||||||
// and that 'symbol' is actually a symbol
|
// and that 'symbol' is actually a symbol
|
||||||
if ((! varValue.getCdr().nullp()) || (! symbol.symbolp())) {
|
if ((!varValue.getCdr().nullp()) || (!symbol.symbolp())) {
|
||||||
throw new RuntimeException("LET: illegal variable " +
|
throw new RuntimeException("LET: illegal variable " + "specification " + varSpec);
|
||||||
"specification " + varSpec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
environment.put(symbol.toString(), value);
|
environment.put(symbol.toString(), value);
|
||||||
|
@ -106,11 +91,9 @@ public class LET extends LispFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the arguments passed to this Lisp function should be
|
* Determine if the arguments passed to this Lisp function should be evaluated.
|
||||||
* evaluated.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return <code>false</code>
|
||||||
* <code>false</code>
|
|
||||||
*/
|
*/
|
||||||
public boolean evaluateArguments() {
|
public boolean evaluateArguments() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>LIST</code> represents the LIST function in Lisp.
|
* <code>LIST</code> represents the LIST function in Lisp.
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>LISTP</code> represents the LISTP function in Lisp.
|
* <code>LISTP</code> represents the LISTP function in Lisp.
|
||||||
|
@ -27,9 +17,8 @@ public class LISTP extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength != NUM_ARGS) {
|
if (argListLength != NUM_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("LISTP"), argList);
|
Cons originalSExpr = new Cons(new Symbol("LISTP"), argList);
|
||||||
String errMsg = "too " +
|
String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to LISTP: "
|
||||||
((argListLength > NUM_ARGS) ? "many" : "few") +
|
+ originalSExpr;
|
||||||
" arguments given to LISTP: " + originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,10 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import java.io.FileInputStream;
|
||||||
import sexpression.Cons;
|
import java.io.FileNotFoundException;
|
||||||
import sexpression.LispString;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
import java.io.*;
|
import parser.LispParser;
|
||||||
|
import sexpression.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>LOAD</code> represents the LOAD function in Lisp.
|
* <code>LOAD</code> represents the LOAD function in Lisp.
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
|
||||||
|
@ -19,13 +12,12 @@ public class LambdaExpression extends SExpression {
|
||||||
private UserDefinedFunction function;
|
private UserDefinedFunction function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new FUNCTION with the specified lambda expression and
|
* Create a new FUNCTION with the specified lambda expression and internal representation.
|
||||||
* internal representation.
|
|
||||||
*
|
*
|
||||||
* @param lexpr
|
* @param lexpr
|
||||||
* the lambda expression of this FUNCTION
|
* the lambda expression of this FUNCTION
|
||||||
* @param function
|
* @param function
|
||||||
* the internal representation of this FUNCTION
|
* the internal representation of this FUNCTION
|
||||||
*/
|
*/
|
||||||
public LambdaExpression(Cons lexpr, UserDefinedFunction function) {
|
public LambdaExpression(Cons lexpr, UserDefinedFunction function) {
|
||||||
this.lexpr = lexpr;
|
this.lexpr = lexpr;
|
||||||
|
@ -35,8 +27,7 @@ public class LambdaExpression extends SExpression {
|
||||||
/**
|
/**
|
||||||
* Test if this S-expression is a FUNCTION.
|
* Test if this S-expression is a FUNCTION.
|
||||||
*
|
*
|
||||||
* @return
|
* @return <code>true</code>
|
||||||
* <code>true</code>
|
|
||||||
*/
|
*/
|
||||||
public boolean functionp() {
|
public boolean functionp() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -45,8 +36,7 @@ public class LambdaExpression extends SExpression {
|
||||||
/**
|
/**
|
||||||
* Retrieve the lambda expression of this FUNCTION.
|
* Retrieve the lambda expression of this FUNCTION.
|
||||||
*
|
*
|
||||||
* @return
|
* @return the lambda expression of this FUNCTION
|
||||||
* the lambda expression of this FUNCTION
|
|
||||||
*/
|
*/
|
||||||
public Cons getLExpression() {
|
public Cons getLExpression() {
|
||||||
return lexpr;
|
return lexpr;
|
||||||
|
@ -55,8 +45,7 @@ public class LambdaExpression extends SExpression {
|
||||||
/**
|
/**
|
||||||
* Retrieve the internal representation of this FUNCTION.
|
* Retrieve the internal representation of this FUNCTION.
|
||||||
*
|
*
|
||||||
* @return
|
* @return the user-defined function of this FUNCTION
|
||||||
* the user-defined function of this FUNCTION
|
|
||||||
*/
|
*/
|
||||||
public UserDefinedFunction getFunction() {
|
public UserDefinedFunction getFunction() {
|
||||||
return function;
|
return function;
|
||||||
|
@ -65,8 +54,7 @@ public class LambdaExpression extends SExpression {
|
||||||
/**
|
/**
|
||||||
* Returns a string representation of this FUNCTION.
|
* Returns a string representation of this FUNCTION.
|
||||||
*
|
*
|
||||||
* @return
|
* @return a string representation of this FUNCTION
|
||||||
* a string representation of this FUNCTION
|
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return lexpr.toString();
|
return lexpr.toString();
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A <code>LispFunction</code> is an internal representation of a built-in
|
* A <code>LispFunction</code> is an internal representation of a built-in function in the Lisp
|
||||||
* function in the Lisp programming language.
|
* programming language.
|
||||||
*/
|
*/
|
||||||
public abstract class LispFunction {
|
public abstract class LispFunction {
|
||||||
|
|
||||||
|
@ -20,24 +13,20 @@ public abstract class LispFunction {
|
||||||
* Call this Lisp function with the given list of arguments.
|
* Call this Lisp function with the given list of arguments.
|
||||||
*
|
*
|
||||||
* @param argList
|
* @param argList
|
||||||
* the list of arguments to pass to this function (MUST BE A PROPER LIST)
|
* the list of arguments to pass to this function (MUST BE A PROPER LIST)
|
||||||
* @return
|
* @return the resulting S-expression of calling this function with the specified arguments
|
||||||
* the resulting S-expression of calling this function with the specified
|
|
||||||
* arguments
|
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* Indicates that an incorrect number of arguments has been passed to this
|
* Indicates that an incorrect number of arguments has been passed to this function
|
||||||
* function or that one of the arguments is not of the expected type.
|
* or that one of the arguments is not of the expected type.
|
||||||
*/
|
*/
|
||||||
public abstract SExpression call(Cons argList);
|
public abstract SExpression call(Cons argList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the arguments passed to this Lisp function should be
|
* Determine if the arguments passed to this Lisp function should be evaluated. A subclass
|
||||||
* evaluated. A subclass should override this method to return
|
* should override this method to return <code>false</code> if it does not want its arguments to
|
||||||
* <code>false</code> if it does not want its arguments to be evaluated
|
* be evaluated prior to being passed.
|
||||||
* prior to being passed.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return <code>true</code>
|
||||||
* <code>true</code>
|
|
||||||
*/
|
*/
|
||||||
public boolean evaluateArguments() {
|
public boolean evaluateArguments() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.LispNumber;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>MINUS</code> represents the '-' function in Lisp.
|
* <code>MINUS</code> represents the '-' function in Lisp.
|
||||||
|
@ -22,8 +12,7 @@ public class MINUS extends LispFunction {
|
||||||
if (argList.nullp()) {
|
if (argList.nullp()) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("-"), argList);
|
Cons originalSExpr = new Cons(new Symbol("-"), argList);
|
||||||
|
|
||||||
throw new RuntimeException("too few arguments given to -: " +
|
throw new RuntimeException("too few arguments given to -: " + originalSExpr);
|
||||||
originalSExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argFirst = argList.getCar();
|
SExpression argFirst = argList.getCar();
|
||||||
|
@ -36,7 +25,7 @@ public class MINUS extends LispFunction {
|
||||||
if (argRest.nullp()) {
|
if (argRest.nullp()) {
|
||||||
// there is only one argument, so return the additive
|
// there is only one argument, so return the additive
|
||||||
// inverse of the number
|
// inverse of the number
|
||||||
return new LispNumber(- num1.getValue());
|
return new LispNumber(-num1.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argSecond = argRest.getCar();
|
SExpression argSecond = argRest.getCar();
|
||||||
|
@ -44,8 +33,7 @@ public class MINUS extends LispFunction {
|
||||||
// make sure that the next argument is a number as well
|
// make sure that the next argument is a number as well
|
||||||
if (argSecond.numberp()) {
|
if (argSecond.numberp()) {
|
||||||
LispNumber num2 = (LispNumber) argSecond;
|
LispNumber num2 = (LispNumber) argSecond;
|
||||||
LispNumber difference = new LispNumber(num1.getValue() -
|
LispNumber difference = new LispNumber(num1.getValue() - num2.getValue());
|
||||||
num2.getValue());
|
|
||||||
SExpression argCddr = argRest.getCdr();
|
SExpression argCddr = argRest.getCdr();
|
||||||
|
|
||||||
if (argCddr.consp()) {
|
if (argCddr.consp()) {
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.LispNumber;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>MULTIPLY</code> represents the '*' function in Lisp.
|
* <code>MULTIPLY</code> represents the '*' function in Lisp.
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.Nil;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>NULL</code> represents the NULL function in Lisp.
|
* <code>NULL</code> represents the NULL function in Lisp.
|
||||||
|
@ -27,9 +17,8 @@ public class NULL extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength != NUM_ARGS) {
|
if (argListLength != NUM_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("NULL"), argList);
|
Cons originalSExpr = new Cons(new Symbol("NULL"), argList);
|
||||||
String errMsg = "too " +
|
String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to NULL: "
|
||||||
((argListLength > NUM_ARGS) ? "many" : "few") +
|
+ originalSExpr;
|
||||||
" arguments given to NULL: " + originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.LispNumber;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>PLUS</code> represents the '+' function in Lisp.
|
* <code>PLUS</code> represents the '+' function in Lisp.
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>PRINT</code> represents the PRINT function in Lisp.
|
* <code>PRINT</code> represents the PRINT function in Lisp.
|
||||||
|
@ -26,9 +17,8 @@ public class PRINT extends LispFunction {
|
||||||
// make sure we have received the proper number of arguments
|
// make sure we have received the proper number of arguments
|
||||||
if (argListLength != NUM_ARGS) {
|
if (argListLength != NUM_ARGS) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("PRINT"), argList);
|
Cons originalSExpr = new Cons(new Symbol("PRINT"), argList);
|
||||||
String errMsg = "too " +
|
String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to PRINT: "
|
||||||
((argListLength > NUM_ARGS) ? "many" : "few") +
|
+ originalSExpr;
|
||||||
" arguments given to PRINT: " + originalSExpr;
|
|
||||||
|
|
||||||
throw new RuntimeException(errMsg);
|
throw new RuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>QUOTE</code> represents the QUOTE form in Lisp.
|
* <code>QUOTE</code> represents the QUOTE form in Lisp.
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>SETF</code> represents the SETF form in Lisp.
|
* <code>SETF</code> represents the SETF form in Lisp.
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
import sexpression.*;
|
||||||
import sexpression.Cons;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
import sexpression.Symbol;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>SYMBOL_FUNCTION</code> represents the SYMBOL-FUNCTION function in
|
* <code>SYMBOL_FUNCTION</code> represents the SYMBOL-FUNCTION function in
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
/*
|
|
||||||
* Name: Mike Cifelli
|
|
||||||
* Course: CIS 443 - Programming Languages
|
|
||||||
* Assignment: Lisp Interpreter 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eval;
|
package eval;
|
||||||
|
|
||||||
import parser.*;
|
|
||||||
import sexpression.SExpression;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import sexpression.SExpression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A <code>SymbolTable</code> maps symbol names to values.
|
* A <code>SymbolTable</code> maps symbol names to values.
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +23,7 @@ public class SymbolTable {
|
||||||
* Create a new symbol table with the specified parent.
|
* Create a new symbol table with the specified parent.
|
||||||
*
|
*
|
||||||
* @param parent
|
* @param parent
|
||||||
* the parent of this symbol table
|
* the parent of this symbol table
|
||||||
*/
|
*/
|
||||||
public SymbolTable(SymbolTable parent) {
|
public SymbolTable(SymbolTable parent) {
|
||||||
this.table = new HashMap<String, SExpression>();
|
this.table = new HashMap<String, SExpression>();
|
||||||
|
@ -41,39 +34,34 @@ public class SymbolTable {
|
||||||
* Determine if the specified symbol name is in this symbol table.
|
* Determine if the specified symbol name is in this symbol table.
|
||||||
*
|
*
|
||||||
* @param symbolName
|
* @param symbolName
|
||||||
* the name of the symbol to look up
|
* the name of the symbol to look up
|
||||||
* @return
|
* @return <code>true</code> if the symbol is in this symbol table; <code>false</code> otherwise
|
||||||
* <code>true</code> if the symbol is in this symbol table;
|
|
||||||
* <code>false</code> otherwise
|
|
||||||
*/
|
*/
|
||||||
public boolean contains(String symbolName) {
|
public boolean contains(String symbolName) {
|
||||||
return table.containsKey(symbolName);
|
return table.containsKey(symbolName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value to which the specified symbol name is mapped in this
|
* Returns the value to which the specified symbol name is mapped in this symbol table.
|
||||||
* symbol table.
|
|
||||||
*
|
*
|
||||||
* @param symbolName
|
* @param symbolName
|
||||||
* the name of the symbol whose associated value is to be returned
|
* the name of the symbol whose associated value is to be returned
|
||||||
* @return
|
* @return the value to which this symbol table maps <code>symbolName</code>, or null if no
|
||||||
* the value to which this symbol table maps <code>symbolName</code>, or
|
* mapping exists
|
||||||
* null if no mapping exists
|
|
||||||
*/
|
*/
|
||||||
public SExpression get(String symbolName) {
|
public SExpression get(String symbolName) {
|
||||||
return table.get(symbolName);
|
return table.get(symbolName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Associates the specified symbol name with the specified value in this
|
* Associates the specified symbol name with the specified value in this symbol table. If the
|
||||||
* symbol table. If the symbol table previously contained a mapping for
|
* symbol table previously contained a mapping for this symbol name, the old value has been
|
||||||
* this symbol name, the old value has been replaced.
|
* replaced.
|
||||||
*
|
*
|
||||||
* @param symbolName
|
* @param symbolName
|
||||||
* the name of the symbol with which the specified value is to be
|
* the name of the symbol with which the specified value is to be associated
|
||||||
* associated
|
|
||||||
* @param value
|
* @param value
|
||||||
* the value to be associated with the specified symbol name
|
* the value to be associated with the specified symbol name
|
||||||
*/
|
*/
|
||||||
public void put(String symbolName, SExpression value) {
|
public void put(String symbolName, SExpression value) {
|
||||||
table.put(symbolName, value);
|
table.put(symbolName, value);
|
||||||
|
@ -82,8 +70,7 @@ public class SymbolTable {
|
||||||
/**
|
/**
|
||||||
* Returns the parent of this symbol table.
|
* Returns the parent of this symbol table.
|
||||||
*
|
*
|
||||||
* @return
|
* @return the parent of this symbol table
|
||||||
* the parent of this symbol table
|
|
||||||
*/
|
*/
|
||||||
public SymbolTable getParent() {
|
public SymbolTable getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
package sexpression;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class SExpressionTester {
|
||||||
|
|
||||||
|
private void assertSExpressionMatchesString(String expected, SExpression sExpression) {
|
||||||
|
assertEquals(expected, sExpression.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNilToString() {
|
||||||
|
String input = "NIL";
|
||||||
|
|
||||||
|
assertSExpressionMatchesString(input, Nil.getUniqueInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNumberToString() {
|
||||||
|
String input = "12";
|
||||||
|
|
||||||
|
assertSExpressionMatchesString(input, new LispNumber(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNumberValueToString() {
|
||||||
|
String expected = "12";
|
||||||
|
|
||||||
|
assertSExpressionMatchesString(expected, new LispNumber(12));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringToString() {
|
||||||
|
String input = "\"hi\"";
|
||||||
|
|
||||||
|
assertSExpressionMatchesString(input, new LispString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSymbolToString() {
|
||||||
|
String input = "symbol";
|
||||||
|
|
||||||
|
assertSExpressionMatchesString(input.toUpperCase(), new Symbol(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleConsToString() {
|
||||||
|
String expected = "(1)";
|
||||||
|
Cons cons = new Cons(new LispNumber(1), Nil.getUniqueInstance());
|
||||||
|
|
||||||
|
assertSExpressionMatchesString(expected, cons);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComplexConsToString() {
|
||||||
|
String expected = "(1 A \"string\")";
|
||||||
|
Cons list = new Cons(new LispNumber(1),
|
||||||
|
new Cons(new Symbol("a"),
|
||||||
|
new Cons(new LispString("\"string\""), Nil.getUniqueInstance())));
|
||||||
|
|
||||||
|
assertSExpressionMatchesString(expected, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue