Added the following built-ins: AND & OR
This commit is contained in:
parent
a9a47be6cd
commit
c2a373dc85
|
@ -1,7 +1,7 @@
|
|||
(defun run-unit-test (unit-test)
|
||||
(cond
|
||||
((funcall unit-test) (print (cons (symbol-function unit-test) T)))
|
||||
(T (print (cons (symbol-function unit-test) 'F)))
|
||||
((funcall unit-test) (print (cons (symbol-function unit-test) T)) T)
|
||||
(T (print (cons (symbol-function unit-test) 'F)) NIL)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -12,5 +12,5 @@
|
|||
)
|
||||
|
||||
(defun unit (test-suite)
|
||||
(cond ((run-test-suite test-suite) T))
|
||||
(apply 'and (run-test-suite test-suite))
|
||||
)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package function.builtin.special;
|
||||
|
||||
import function.*;
|
||||
import function.builtin.EVAL;
|
||||
import sexpression.*;
|
||||
|
||||
public class AND extends LispFunction {
|
||||
|
||||
private ArgumentValidator argumentValidator;
|
||||
|
||||
public AND() {
|
||||
this.argumentValidator = new ArgumentValidator("AND");
|
||||
}
|
||||
|
||||
public SExpression call(Cons argumentList) {
|
||||
argumentValidator.validate(argumentList);
|
||||
|
||||
return callTailRecursive(argumentList, Symbol.T);
|
||||
}
|
||||
|
||||
private SExpression callTailRecursive(Cons argumentList, SExpression lastValue) {
|
||||
SExpression currentValue = EVAL.eval(argumentList.getCar());
|
||||
Cons remainingValues = (Cons) argumentList.getCdr();
|
||||
|
||||
if (argumentList.nullp())
|
||||
return lastValue;
|
||||
|
||||
if (currentValue.nullp())
|
||||
return currentValue;
|
||||
|
||||
return callTailRecursive(remainingValues, currentValue);
|
||||
}
|
||||
|
||||
public boolean evaluateArguments() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package function.builtin.special;
|
||||
|
||||
import function.*;
|
||||
import function.builtin.EVAL;
|
||||
import sexpression.*;
|
||||
|
||||
public class OR extends LispFunction {
|
||||
|
||||
private ArgumentValidator argumentValidator;
|
||||
|
||||
public OR() {
|
||||
this.argumentValidator = new ArgumentValidator("OR");
|
||||
}
|
||||
|
||||
public SExpression call(Cons argumentList) {
|
||||
argumentValidator.validate(argumentList);
|
||||
|
||||
return callTailRecursive(argumentList);
|
||||
}
|
||||
|
||||
private SExpression callTailRecursive(Cons argumentList) {
|
||||
SExpression currentValue = EVAL.eval(argumentList.getCar());
|
||||
Cons remainingValues = (Cons) argumentList.getCdr();
|
||||
|
||||
if (remainingValues.nullp() || !currentValue.nullp())
|
||||
return currentValue;
|
||||
|
||||
return callTailRecursive(remainingValues);
|
||||
}
|
||||
|
||||
public boolean evaluateArguments() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -41,6 +41,7 @@ public class FunctionTable {
|
|||
functionTable.put("<", new LESSP());
|
||||
functionTable.put("=", new EQUALSP());
|
||||
functionTable.put(">", new GREATERP());
|
||||
functionTable.put("AND", new AND());
|
||||
functionTable.put("APPLY", new APPLY());
|
||||
functionTable.put("ATOM", new ATOM());
|
||||
functionTable.put("CAR", new CAR());
|
||||
|
@ -62,6 +63,7 @@ public class FunctionTable {
|
|||
functionTable.put("LISTP", new LISTP());
|
||||
functionTable.put("LOAD", new LOAD());
|
||||
functionTable.put("NULL", new NULL());
|
||||
functionTable.put("OR", new OR());
|
||||
functionTable.put("PRINT", new PRINT());
|
||||
functionTable.put("QUOTE", new QUOTE());
|
||||
functionTable.put("REST", new CDR());
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package function.builtin.special;
|
||||
|
||||
import static testutil.TestUtilities.*;
|
||||
import static testutil.TypeAssertions.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import function.builtin.EVAL.UndefinedSymbolException;
|
||||
import sexpression.LispNumber;
|
||||
import table.ExecutionContext;
|
||||
|
||||
public class ANDTester {
|
||||
|
||||
private ExecutionContext executionContext;
|
||||
|
||||
public ANDTester() {
|
||||
this.executionContext = ExecutionContext.getInstance();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
executionContext.clearContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
executionContext.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andByItself() {
|
||||
String input = "(and)";
|
||||
|
||||
assertT(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andWithNil() {
|
||||
String input = "(and nil)";
|
||||
|
||||
assertNil(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andWithT() {
|
||||
String input = "(and t)";
|
||||
|
||||
assertT(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andWithNumber() {
|
||||
String input = "(and 7)";
|
||||
|
||||
assertSExpressionsMatch(new LispNumber("7"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andWithSeveralValues() {
|
||||
String input = "(and t t nil t t)";
|
||||
|
||||
assertNil(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void andWithSeveralNumbers() {
|
||||
String input = "(and 1 2 3)";
|
||||
|
||||
assertSExpressionsMatch(new LispNumber("3"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test(expected = UndefinedSymbolException.class)
|
||||
public void andShortCircuits() {
|
||||
String input = "(and nil (setf x 22))";
|
||||
|
||||
assertNil(evaluateString(input));
|
||||
evaluateString("x");
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,11 @@ public class LETTester {
|
|||
executionContext.clearContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
executionContext.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleLet() {
|
||||
String input = "(let ((x 1)) x)";
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package function.builtin.special;
|
||||
|
||||
import static testutil.TestUtilities.*;
|
||||
import static testutil.TypeAssertions.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import function.builtin.EVAL.UndefinedSymbolException;
|
||||
import sexpression.LispNumber;
|
||||
import table.ExecutionContext;
|
||||
|
||||
public class ORTester {
|
||||
|
||||
private ExecutionContext executionContext;
|
||||
|
||||
public ORTester() {
|
||||
this.executionContext = ExecutionContext.getInstance();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
executionContext.clearContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
executionContext.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orByItself() {
|
||||
String input = "(or)";
|
||||
|
||||
assertNil(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orWithNil() {
|
||||
String input = "(or nil)";
|
||||
|
||||
assertNil(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orWithT() {
|
||||
String input = "(or t)";
|
||||
|
||||
assertT(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orWithNumber() {
|
||||
String input = "(or 7)";
|
||||
|
||||
assertSExpressionsMatch(new LispNumber("7"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orWithSeveralValues() {
|
||||
String input = "(or nil nil nil t nil)";
|
||||
|
||||
assertT(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orWithSeveralNumbers() {
|
||||
String input = "(or 1 2 3)";
|
||||
|
||||
assertSExpressionsMatch(new LispNumber("1"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test(expected = UndefinedSymbolException.class)
|
||||
public void orShortCircuits() {
|
||||
String input = "(or t (setf x 22))";
|
||||
|
||||
assertT(evaluateString(input));
|
||||
evaluateString("x");
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,11 @@ public class SETFTester {
|
|||
executionContext.clearContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
executionContext.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetf() {
|
||||
evaluateString("(setf a 23)");
|
||||
|
|
Loading…
Reference in New Issue