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("FUNCALL", new FUNCALL());
|
||||
functionTable.put("GREATERP", new GREATERP());
|
||||
functionTable.put("IF", new IF());
|
||||
functionTable.put("LAMBDA", new LAMBDA());
|
||||
functionTable.put("LENGTH", new LENGTH());
|
||||
functionTable.put("LET", new LET());
|
||||
|
|
|
@ -22,6 +22,13 @@ public class CONDTester {
|
|||
assertSExpressionsMatch(parseString("T"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCondWithNumber() {
|
||||
String input = "(cond ((+ 1 2)))";
|
||||
|
||||
assertSExpressionsMatch(parseString("3"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCondWithSingleExpression() {
|
||||
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