diff --git a/src/main/java/org/squiddev/cobalt/LuaBoolean.java b/src/main/java/org/squiddev/cobalt/LuaBoolean.java index 8c38d5da..ba231b7c 100644 --- a/src/main/java/org/squiddev/cobalt/LuaBoolean.java +++ b/src/main/java/org/squiddev/cobalt/LuaBoolean.java @@ -61,7 +61,7 @@ public final class LuaBoolean extends LuaValue { */ public final boolean v; - LuaBoolean(boolean b) { + private LuaBoolean(boolean b) { super(TBOOLEAN); this.v = b; } diff --git a/src/main/java/org/squiddev/cobalt/LuaValue.java b/src/main/java/org/squiddev/cobalt/LuaValue.java index 25956f9a..bd484484 100644 --- a/src/main/java/org/squiddev/cobalt/LuaValue.java +++ b/src/main/java/org/squiddev/cobalt/LuaValue.java @@ -362,7 +362,7 @@ public boolean toBoolean() { * @see Constants#TNUMBER */ public double toDouble() { - return Double.NaN; + return 0.0; } /** diff --git a/src/main/java/org/squiddev/cobalt/OperationHelper.java b/src/main/java/org/squiddev/cobalt/OperationHelper.java index 1713e92a..e14fb561 100644 --- a/src/main/java/org/squiddev/cobalt/OperationHelper.java +++ b/src/main/java/org/squiddev/cobalt/OperationHelper.java @@ -29,6 +29,7 @@ import org.squiddev.cobalt.function.LuaFunction; import static org.squiddev.cobalt.Constants.*; +import static org.squiddev.cobalt.LuaDouble.NAN; import static org.squiddev.cobalt.LuaDouble.valueOf; import static org.squiddev.cobalt.LuaInteger.valueOf; import static org.squiddev.cobalt.debug.DebugFrame.FLAG_LEQ; @@ -260,6 +261,9 @@ public static boolean lt(LuaState state, LuaValue left, LuaValue right) throws L if (tLeft != right.type()) { throw ErrorFactory.compareError(left, right); } + + if (left == right && (tLeft == TNUMBER || tLeft == TSTRING)) return false; + switch (tLeft) { case TNUMBER: return left.toDouble() < right.toDouble(); @@ -280,6 +284,9 @@ public static boolean le(LuaState state, LuaValue left, LuaValue right) throws L if (tLeft != right.type()) { throw ErrorFactory.compareError(left, right); } + + if (left == right && (tLeft == TNUMBER || tLeft == TSTRING)) return (tLeft != TNUMBER) || !Double.isNaN(left.toDouble()); + switch (tLeft) { case TNUMBER: return left.toDouble() <= right.toDouble(); @@ -308,6 +315,8 @@ public static boolean le(LuaState state, LuaValue left, LuaValue right) throws L public static boolean eq(LuaState state, LuaValue left, LuaValue right) throws LuaError, UnwindThrowable { int tLeft = left.type(); + if (left == right) return (tLeft != TNUMBER) || !Double.isNaN(left.toDouble()); + if (tLeft != right.type()) return false; switch (tLeft) { @@ -317,11 +326,9 @@ public static boolean eq(LuaState state, LuaValue left, LuaValue right) throws L return left.toDouble() == right.toDouble(); case TBOOLEAN: return left.toBoolean() == right.toBoolean(); - case TSTRING: - return left == right || left.raweq(right); case TUSERDATA: case TTABLE: { - if (left == right || left.raweq(right)) return true; + if (left.raweq(right)) return true; LuaTable leftMeta = left.getMetatable(state); if (leftMeta == null) return false; @@ -332,8 +339,9 @@ public static boolean eq(LuaState state, LuaValue left, LuaValue right) throws L LuaValue h = leftMeta.rawget(CachedMetamethod.EQ); return !(h.isNil() || h != rightMeta.rawget(CachedMetamethod.EQ)) && OperationHelper.call(state, h, left, right).toBoolean(); } + case TSTRING: default: - return left == right || left.raweq(right); + return left.raweq(right); } } //endregion @@ -411,7 +419,7 @@ public static LuaValue neg(LuaState state, LuaValue value, int stack) throws Lua } private static boolean checkNumber(LuaValue lua, double value) { - return lua.type() == TNUMBER || !Double.isNaN(value); + return lua.type() == TNUMBER || (lua.type() == TSTRING && !Double.isNaN(value)); } //endregion diff --git a/src/test/java/org/squiddev/cobalt/vm/TypeTest.java b/src/test/java/org/squiddev/cobalt/vm/TypeTest.java index 310a7b03..d50db8d2 100644 --- a/src/test/java/org/squiddev/cobalt/vm/TypeTest.java +++ b/src/test/java/org/squiddev/cobalt/vm/TypeTest.java @@ -383,9 +383,9 @@ public void testToBoolean() { @Test public void testToDouble() { - assertDoubleEquals(Double.NaN, somenil.toDouble()); - assertDoubleEquals(Double.NaN, somefalse.toDouble()); - assertDoubleEquals(Double.NaN, sometrue.toDouble()); + assertDoubleEquals(0.0, somenil.toDouble()); + assertDoubleEquals(0.0, somefalse.toDouble()); + assertDoubleEquals(0.0, sometrue.toDouble()); assertDoubleEquals(0, zero.toDouble()); assertDoubleEquals(sampleint, intint.toDouble()); assertDoubleEquals((double) samplelong, longdouble.toDouble()); @@ -394,12 +394,12 @@ public void testToDouble() { assertDoubleEquals(sampleint, stringint.toDouble()); assertDoubleEquals((double) samplelong, stringlong.toDouble()); assertDoubleEquals(sampledouble, stringdouble.toDouble()); - assertDoubleEquals(Double.NaN, thread.toDouble()); - assertDoubleEquals(Double.NaN, table.toDouble()); - assertDoubleEquals(Double.NaN, userdataobj.toDouble()); - assertDoubleEquals(Double.NaN, userdatacls.toDouble()); - assertDoubleEquals(Double.NaN, somefunc.toDouble()); - assertDoubleEquals(Double.NaN, someclosure.toDouble()); + assertDoubleEquals(0.0, thread.toDouble()); + assertDoubleEquals(0.0, table.toDouble()); + assertDoubleEquals(0.0, userdataobj.toDouble()); + assertDoubleEquals(0.0, userdatacls.toDouble()); + assertDoubleEquals(0.0, somefunc.toDouble()); + assertDoubleEquals(0.0, someclosure.toDouble()); } @Test