Added the following built-ins: AND & OR

This commit is contained in:
Mike Cifelli 2017-02-05 16:00:56 -05:00
parent a9a47be6cd
commit c2a373dc85
8 changed files with 250 additions and 5 deletions

View File

@ -1,7 +1,7 @@
(defun run-unit-test (unit-test) (defun run-unit-test (unit-test)
(cond (cond
((funcall unit-test) (print (cons (symbol-function unit-test) T))) ((funcall unit-test) (print (cons (symbol-function unit-test) T)) T)
(T (print (cons (symbol-function unit-test) 'F))) (T (print (cons (symbol-function unit-test) 'F)) NIL)
) )
) )
@ -12,5 +12,5 @@
) )
(defun unit (test-suite) (defun unit (test-suite)
(cond ((run-test-suite test-suite) T)) (apply 'and (run-test-suite test-suite))
) )

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -41,6 +41,7 @@ public class FunctionTable {
functionTable.put("<", new LESSP()); functionTable.put("<", new LESSP());
functionTable.put("=", new EQUALSP()); functionTable.put("=", new EQUALSP());
functionTable.put(">", new GREATERP()); functionTable.put(">", new GREATERP());
functionTable.put("AND", new AND());
functionTable.put("APPLY", new APPLY()); functionTable.put("APPLY", new APPLY());
functionTable.put("ATOM", new ATOM()); functionTable.put("ATOM", new ATOM());
functionTable.put("CAR", new CAR()); functionTable.put("CAR", new CAR());
@ -62,6 +63,7 @@ public class FunctionTable {
functionTable.put("LISTP", new LISTP()); functionTable.put("LISTP", new LISTP());
functionTable.put("LOAD", new LOAD()); functionTable.put("LOAD", new LOAD());
functionTable.put("NULL", new NULL()); functionTable.put("NULL", new NULL());
functionTable.put("OR", new OR());
functionTable.put("PRINT", new PRINT()); functionTable.put("PRINT", new PRINT());
functionTable.put("QUOTE", new QUOTE()); functionTable.put("QUOTE", new QUOTE());
functionTable.put("REST", new CDR()); functionTable.put("REST", new CDR());

View File

@ -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");
}
}

View File

@ -22,6 +22,11 @@ public class LETTester {
executionContext.clearContext(); executionContext.clearContext();
} }
@After
public void tearDown() {
executionContext.clearContext();
}
@Test @Test
public void simpleLet() { public void simpleLet() {
String input = "(let ((x 1)) x)"; String input = "(let ((x 1)) x)";

View File

@ -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");
}
}

View File

@ -11,9 +11,9 @@ import sexpression.LispNumber;
import table.*; import table.*;
public class SETFTester { public class SETFTester {
private ExecutionContext executionContext; private ExecutionContext executionContext;
public SETFTester() { public SETFTester() {
this.executionContext = ExecutionContext.getInstance(); this.executionContext = ExecutionContext.getInstance();
} }
@ -23,6 +23,11 @@ public class SETFTester {
executionContext.clearContext(); executionContext.clearContext();
} }
@After
public void tearDown() {
executionContext.clearContext();
}
@Test @Test
public void testSetf() { public void testSetf() {
evaluateString("(setf a 23)"); evaluateString("(setf a 23)");