Resolves #1 - Added the IF Special Form
This commit is contained in:
parent
35550c46ac
commit
0c3d3ae024
|
@ -0,0 +1,52 @@
|
||||||
|
package function.builtin.special;
|
||||||
|
|
||||||
|
import static function.builtin.EVAL.eval;
|
||||||
|
|
||||||
|
import function.*;
|
||||||
|
import sexpression.*;
|
||||||
|
|
||||||
|
public class IF extends LispFunction {
|
||||||
|
|
||||||
|
private ArgumentValidator argumentValidator;
|
||||||
|
|
||||||
|
public IF() {
|
||||||
|
this.argumentValidator = new ArgumentValidator("IF");
|
||||||
|
this.argumentValidator.setMinimumNumberOfArguments(2);
|
||||||
|
this.argumentValidator.setMaximumNumberOfArguments(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SExpression call(Cons argumentList) {
|
||||||
|
argumentValidator.validate(argumentList);
|
||||||
|
|
||||||
|
SExpression test = eval(argumentList.getCar());
|
||||||
|
SExpression thenForm = getThenForm(argumentList);
|
||||||
|
SExpression elseForm = getElseForm(argumentList);
|
||||||
|
|
||||||
|
return isNil(test) ? eval(elseForm) : eval(thenForm);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNil(SExpression test) {
|
||||||
|
return test.nullp();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SExpression getThenForm(Cons argumentList) {
|
||||||
|
Cons expressions = getRestOfList(argumentList);
|
||||||
|
|
||||||
|
return expressions.getCar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cons getRestOfList(Cons argumentList) {
|
||||||
|
return (Cons) argumentList.getCdr();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SExpression getElseForm(Cons argumentList) {
|
||||||
|
Cons expressions = getRestOfList(argumentList);
|
||||||
|
|
||||||
|
return getRestOfList(expressions).getCar();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean evaluateArguments() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -60,6 +60,7 @@ public class FunctionTable {
|
||||||
functionTable.put("FIRST", new CAR());
|
functionTable.put("FIRST", new CAR());
|
||||||
functionTable.put("FUNCALL", new FUNCALL());
|
functionTable.put("FUNCALL", new FUNCALL());
|
||||||
functionTable.put("GREATERP", new GREATERP());
|
functionTable.put("GREATERP", new GREATERP());
|
||||||
|
functionTable.put("IF", new IF());
|
||||||
functionTable.put("LAMBDA", new LAMBDA());
|
functionTable.put("LAMBDA", new LAMBDA());
|
||||||
functionTable.put("LENGTH", new LENGTH());
|
functionTable.put("LENGTH", new LENGTH());
|
||||||
functionTable.put("LET", new LET());
|
functionTable.put("LET", new LET());
|
||||||
|
|
|
@ -22,6 +22,13 @@ public class CONDTester {
|
||||||
assertSExpressionsMatch(parseString("T"), evaluateString(input));
|
assertSExpressionsMatch(parseString("T"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCondWithNumber() {
|
||||||
|
String input = "(cond ((+ 1 2)))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("3"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithSingleExpression() {
|
public void testCondWithSingleExpression() {
|
||||||
String input = "(cond (T \"true\"))";
|
String input = "(cond (T \"true\"))";
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
package function.builtin.special;
|
||||||
|
|
||||||
|
import static testutil.TestUtilities.evaluateString;
|
||||||
|
import static testutil.TypeAssertions.*;
|
||||||
|
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import function.ArgumentValidator.*;
|
||||||
|
import function.builtin.EVAL.UndefinedSymbolException;
|
||||||
|
import table.ExecutionContext;
|
||||||
|
|
||||||
|
public class IFTester {
|
||||||
|
|
||||||
|
private ExecutionContext executionContext;
|
||||||
|
|
||||||
|
public IFTester() {
|
||||||
|
this.executionContext = ExecutionContext.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
executionContext.clearContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
executionContext.clearContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ifWithOneExpression_ReturnsExpression() {
|
||||||
|
String input = "(if t t)";
|
||||||
|
|
||||||
|
assertT(evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ifWithOneExpression_ReturnsNil() {
|
||||||
|
String input = "(if nil t)";
|
||||||
|
|
||||||
|
assertNil(evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ifWithTwoExpressions_ReturnsFirst() {
|
||||||
|
String input = "(if t t nil)";
|
||||||
|
|
||||||
|
assertT(evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ifWithTwoExpressions_ReturnsSecond() {
|
||||||
|
String input = "(if nil nil t)";
|
||||||
|
|
||||||
|
assertT(evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ifWithNumericConditional() {
|
||||||
|
String input = "(if 23 t nil)";
|
||||||
|
|
||||||
|
assertT(evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UndefinedSymbolException.class)
|
||||||
|
public void ifWithNilCondition_DoesNotEvaluateThenForm() {
|
||||||
|
String input = "(if nil (setf x 22))";
|
||||||
|
|
||||||
|
assertNil(evaluateString(input));
|
||||||
|
evaluateString("x");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UndefinedSymbolException.class)
|
||||||
|
public void ifWithTrueCondition_DoesNotEvaluateElseForm() {
|
||||||
|
String input = "(if t nil (setf x 22))";
|
||||||
|
|
||||||
|
assertNil(evaluateString(input));
|
||||||
|
evaluateString("x");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = TooFewArgumentsException.class)
|
||||||
|
public void ifWithTooFewArguments() {
|
||||||
|
evaluateString("(if t)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = TooManyArgumentsException.class)
|
||||||
|
public void ifWithTooManyArguments() {
|
||||||
|
evaluateString("(if t t t t)");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue