diff options
Diffstat (limited to 'src')
3 files changed, 30 insertions, 2 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/ConditionMustBeBoolean.java b/src/main/java/org/zwobble/couscous/interpreter/ConditionMustBeBoolean.java new file mode 100644 index 0000000..c69c290 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/ConditionMustBeBoolean.java @@ -0,0 +1,14 @@ +package org.zwobble.couscous.interpreter; + +import org.zwobble.couscous.values.InterpreterValue; + +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper=false) +public class ConditionMustBeBoolean extends InterpreterException { + private static final long serialVersionUID = 1L; + + InterpreterValue actual; +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java index 6586f6a..232441c 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java @@ -45,8 +45,11 @@ public class Evaluator implements ExpressionNodeVisitor<InterpreterValue> { @Override public InterpreterValue visit(TernaryConditionalNode ternaryConditional) { - val condition = (BooleanValue)eval(ternaryConditional.getCondition()); - val branch = condition.getValue() + val condition = eval(ternaryConditional.getCondition()); + if (!(condition instanceof BooleanValue)) { + throw new ConditionMustBeBoolean(condition); + } + val branch = ((BooleanValue)condition).getValue() ? ternaryConditional.getIfTrue() : ternaryConditional.getIfFalse(); return eval(branch); diff --git a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java index 3adea06..dbf20f8 100644 --- a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java +++ b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java @@ -3,7 +3,9 @@ package org.zwobble.couscous.tests.interpreter; import org.junit.Test; import org.zwobble.couscous.ast.FormalArgumentNode; import org.zwobble.couscous.ast.TernaryConditionalNode; +import org.zwobble.couscous.interpreter.ConditionMustBeBoolean; import org.zwobble.couscous.interpreter.Environment; +import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.StringValue; import com.google.common.collect.ImmutableMap; @@ -12,6 +14,7 @@ import static org.junit.Assert.assertEquals; import static org.zwobble.couscous.ast.Assignment.assign; import static org.zwobble.couscous.ast.LiteralNode.literal; import static org.zwobble.couscous.interpreter.Evaluator.eval; +import static org.zwobble.couscous.tests.util.ExtraAsserts.assertThrows; import lombok.val; @@ -38,6 +41,14 @@ public class EvaluatorTests { assertEquals(new StringValue("F"), result); } + @Test + public void errorIfConditionIsNotBoolean() { + val exception = assertThrows(ConditionMustBeBoolean.class, + () -> eval(emptyEnvironment(), + new TernaryConditionalNode(literal(1), literal("T"), literal("F")))); + assertEquals(new ConditionMustBeBoolean(new IntegerValue(1)), exception); + } + private static Environment emptyEnvironment() { return new Environment(ImmutableMap.of()); } |
