diff --git a/src/main/java/dk/camelot64/kickc/model/operators/Operator.java b/src/main/java/dk/camelot64/kickc/model/operators/Operator.java index 37ac6a60c..57b011772 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/Operator.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/Operator.java @@ -1,5 +1,11 @@ package dk.camelot64.kickc.model.operators; +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.values.ConstantBool; +import dk.camelot64.kickc.model.values.ConstantEnumerable; +import dk.camelot64.kickc.model.values.ConstantInteger; +import dk.camelot64.kickc.model.values.ConstantLiteral; + import java.io.Serializable; /** @@ -64,4 +70,12 @@ public class Operator implements Serializable { return result; } + static Boolean getBool(ConstantLiteral literal) { + if(literal instanceof ConstantBool) + return ((ConstantBool) literal).getBool(); + if(literal instanceof ConstantEnumerable) + return !((ConstantEnumerable) literal).getInteger().equals(0L); + throw new CompileError("Not a boolean" + literal); + } + } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBinary.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBinary.java index 2055a15eb..da66e1ba9 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBinary.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBinary.java @@ -33,4 +33,7 @@ public abstract class OperatorBinary extends Operator { public boolean isAssociative() { return associative; } + + + } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicAnd.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicAnd.java index a22d2253d..cd5ac834d 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicAnd.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicAnd.java @@ -3,6 +3,7 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.values.ConstantBool; +import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; /** Binary logic and Operator ( x && y ) */ @@ -14,10 +15,7 @@ public class OperatorLogicAnd extends OperatorBinary { @Override public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) { - if(left instanceof ConstantBool && right instanceof ConstantBool) { - return new ConstantBool(((ConstantBool) left).getBool() && ((ConstantBool) right).getBool()); - } - throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right); + return new ConstantBool(getBool(left) && getBool(right)); } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicNot.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicNot.java index b6f27261d..a820cd02c 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicNot.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicNot.java @@ -16,13 +16,7 @@ public class OperatorLogicNot extends OperatorUnary { @Override public ConstantLiteral calculateLiteral(ConstantLiteral left, ProgramScope scope) { - if(left instanceof ConstantEnumerable) { - left = new ConstantBool(((ConstantEnumerable) left).getInteger()!=0); - } - if(left instanceof ConstantBool) { - return new ConstantBool(!((ConstantBool) left).getBool() ); - } - throw new CompileError("Calculation not implemented " + getOperator() + " " + left ); + return new ConstantBool(!getBool(left)); } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicOr.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicOr.java index 336be99c0..bf9f9abbe 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicOr.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicOr.java @@ -1,6 +1,5 @@ package dk.camelot64.kickc.model.operators; -import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -14,10 +13,7 @@ public class OperatorLogicOr extends OperatorBinary { @Override public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) { - if(left instanceof ConstantBool && right instanceof ConstantBool) { - return new ConstantBool(((ConstantBool) left).getBool() || ((ConstantBool) right).getBool()); - } - throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right); + return new ConstantBool(getBool(left) || getBool(right)); } @Override @@ -25,5 +21,4 @@ public class OperatorLogicOr extends OperatorBinary { return SymbolType.BOOLEAN; } - } diff --git a/src/test/java/dk/camelot64/kickc/parsing/macros/TestPreprocessor.java b/src/test/java/dk/camelot64/kickc/parsing/macros/TestPreprocessor.java index 29f4bc763..2158bdac5 100644 --- a/src/test/java/dk/camelot64/kickc/parsing/macros/TestPreprocessor.java +++ b/src/test/java/dk/camelot64/kickc/parsing/macros/TestPreprocessor.java @@ -162,6 +162,8 @@ public class TestPreprocessor { assertEquals("name:y;", parse("#if defined A\nx;\n#endif\ny;")); // Output generated by #elif assertEquals("name:y;name:w;", parse("#if 0\nx;\n#elif 1\ny;\n#elif 1\nz;\n#else\nq;\n#endif\nw;")); + // Output generated by #if using defined and || operator + assertEquals("name:x;name:y;", parse("#define A X\n#if defined(A) || defined(B)\nx;\n#endif\ny;")); } /**