diff --git a/src/core/org/luaj/vm2/LuaError.java b/src/core/org/luaj/vm2/LuaError.java index c233ca41..7c6c5540 100644 --- a/src/core/org/luaj/vm2/LuaError.java +++ b/src/core/org/luaj/vm2/LuaError.java @@ -47,8 +47,14 @@ public class LuaError extends RuntimeException { protected Throwable cause; public String getMessage() { - return traceback != null? traceback: - (fileline != null? fileline + " ": "") + super.getMessage(); + if (traceback != null) + return traceback; + String m = super.getMessage(); + if (m == null) + return null; + if (fileline != null) + return fileline + " " + m; + return m; } /** Construct LuaError when a program exception occurs. diff --git a/src/core/org/luaj/vm2/LuaString.java b/src/core/org/luaj/vm2/LuaString.java index 5e540dee..59ec8a78 100644 --- a/src/core/org/luaj/vm2/LuaString.java +++ b/src/core/org/luaj/vm2/LuaString.java @@ -183,29 +183,29 @@ public class LuaString extends LuaValue { } // unary operators - public LuaValue neg() { double d = scannumber(10); return Double.isNaN(d)? super.neg(): valueOf(-d); } + public LuaValue neg() { double d = scannumber(); return Double.isNaN(d)? super.neg(): valueOf(-d); } // basic binary arithmetic - public LuaValue add( LuaValue rhs ) { double d = scannumber(10); return Double.isNaN(d)? arithmt(ADD,rhs): rhs.add(d); } + public LuaValue add( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(ADD,rhs): rhs.add(d); } public LuaValue add( double rhs ) { return valueOf( checkarith() + rhs ); } public LuaValue add( int rhs ) { return valueOf( checkarith() + rhs ); } - public LuaValue sub( LuaValue rhs ) { double d = scannumber(10); return Double.isNaN(d)? arithmt(SUB,rhs): rhs.subFrom(d); } + public LuaValue sub( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(SUB,rhs): rhs.subFrom(d); } public LuaValue sub( double rhs ) { return valueOf( checkarith() - rhs ); } public LuaValue sub( int rhs ) { return valueOf( checkarith() - rhs ); } public LuaValue subFrom( double lhs ) { return valueOf( lhs - checkarith() ); } - public LuaValue mul( LuaValue rhs ) { double d = scannumber(10); return Double.isNaN(d)? arithmt(MUL,rhs): rhs.mul(d); } + public LuaValue mul( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(MUL,rhs): rhs.mul(d); } public LuaValue mul( double rhs ) { return valueOf( checkarith() * rhs ); } public LuaValue mul( int rhs ) { return valueOf( checkarith() * rhs ); } - public LuaValue pow( LuaValue rhs ) { double d = scannumber(10); return Double.isNaN(d)? arithmt(POW,rhs): rhs.powWith(d); } + public LuaValue pow( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(POW,rhs): rhs.powWith(d); } public LuaValue pow( double rhs ) { return MathLib.dpow(checkarith(),rhs); } public LuaValue pow( int rhs ) { return MathLib.dpow(checkarith(),rhs); } public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs, checkarith()); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs, checkarith()); } - public LuaValue div( LuaValue rhs ) { double d = scannumber(10); return Double.isNaN(d)? arithmt(DIV,rhs): rhs.divInto(d); } + public LuaValue div( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(DIV,rhs): rhs.divInto(d); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(checkarith(),rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(checkarith(),rhs); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs, checkarith()); } - public LuaValue mod( LuaValue rhs ) { double d = scannumber(10); return Double.isNaN(d)? arithmt(MOD,rhs): rhs.modFrom(d); } + public LuaValue mod( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(MOD,rhs): rhs.modFrom(d); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(checkarith(), rhs); } public LuaValue mod( int rhs ) { return LuaDouble.dmod(checkarith(), rhs); } public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs, checkarith()); } @@ -252,7 +252,7 @@ public class LuaString extends LuaValue { /** Check for number in arithmetic, or throw aritherror */ private double checkarith() { - double d = scannumber(10); + double d = scannumber(); if ( Double.isNaN(d) ) aritherror(); return d; @@ -268,7 +268,7 @@ public class LuaString extends LuaValue { return (long) checkdouble(); } public double checkdouble() { - double d = scannumber(10); + double d = scannumber(); if ( Double.isNaN(d) ) argerror("number"); return d; @@ -277,22 +277,19 @@ public class LuaString extends LuaValue { return valueOf(checkdouble()); } public LuaNumber checknumber(String msg) { - double d = scannumber(10); + double d = scannumber(); if ( Double.isNaN(d) ) argerror("number"); return valueOf(d); } - public LuaValue tonumber() { - return tonumber(10); - } public boolean isnumber() { - double d = scannumber(10); + double d = scannumber(); return ! Double.isNaN(d); } public boolean isint() { - double d = scannumber(10); + double d = scannumber(); if ( Double.isNaN(d) ) return false; int i = (int) d; @@ -300,7 +297,7 @@ public class LuaString extends LuaValue { } public boolean islong() { - double d = scannumber(10); + double d = scannumber(); if ( Double.isNaN(d) ) return false; long l = (long) d; @@ -309,7 +306,7 @@ public class LuaString extends LuaValue { public byte tobyte() { return (byte) toint(); } public char tochar() { return (char) toint(); } - public double todouble() { double d=scannumber(10); return Double.isNaN(d)? 0: d; } + public double todouble() { double d=scannumber(); return Double.isNaN(d)? 0: d; } public float tofloat() { return (float) todouble(); } public int toint() { return (int) tolong(); } public long tolong() { return (long) todouble(); } @@ -627,6 +624,17 @@ public class LuaString extends LuaValue { // --------------------- number conversion ----------------------- + /** + * convert to a number using baee 10 or base 16 if it starts with '0x', + * or NIL if it can't be converted + * @return IntValue, DoubleValue, or NIL depending on the content of the string. + * @see LuaValue#tonumber() + */ + public LuaValue tonumber() { + double d = scannumber(); + return Double.isNaN(d)? NIL: valueOf(d); + } + /** * convert to a number using a supplied base, or NIL if it can't be converted * @param base the base to use, such as 10 @@ -639,26 +647,36 @@ public class LuaString extends LuaValue { } /** - * Convert to a number in a base, or return Double.NaN if not a number. - * @param base the base to use, such as 10 + * Convert to a number in base 10, or base 16 if the string starts with '0x', + * or return Double.NaN if it cannot be converted to a number. * @return double value if conversion is valid, or Double.NaN if not */ - public double scannumber( int base ) { - if ( base >= 2 && base <= 36 ) { - int i=m_offset,j=m_offset+m_length; - while ( i=j ) - return Double.NaN; - if ( ( base == 10 || base == 16 ) && ( m_bytes[i]=='0' && i+1=j ) + return Double.NaN; + if ( m_bytes[i]=='0' && i+1 36 ) + return Double.NaN; + int i=m_offset,j=m_offset+m_length; + while ( i=j ) + return Double.NaN; + return scanlong( base, i, j ); } /** diff --git a/src/core/org/luaj/vm2/lib/BaseLib.java b/src/core/org/luaj/vm2/lib/BaseLib.java index d77ea2d0..1266cbb1 100644 --- a/src/core/org/luaj/vm2/lib/BaseLib.java +++ b/src/core/org/luaj/vm2/lib/BaseLib.java @@ -321,7 +321,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder { public LuaValue call(LuaValue e, LuaValue base) { if (base.isnil()) return e.tonumber(); - final int b = base.optint(10); + final int b = base.checkint(); if ( b < 2 || b > 36 ) argerror(2, "base out of range"); return e.checkstring().tonumber(b); diff --git a/test/junit/org/luaj/vm2/FragmentsTest.java b/test/junit/org/luaj/vm2/FragmentsTest.java index 9a7b410b..e9fe961a 100644 --- a/test/junit/org/luaj/vm2/FragmentsTest.java +++ b/test/junit/org/luaj/vm2/FragmentsTest.java @@ -555,5 +555,10 @@ public class FragmentsTest extends TestSuite { "end\n"+ "g()\n"); } + + public void testNullError() { + runFragment( LuaValue.varargsOf(LuaValue.FALSE, LuaValue.NIL), + "return pcall(error)\n"); + } } } diff --git a/test/lua/baselib.lua b/test/lua/baselib.lua index 9cb89006..96c50ce8 100644 --- a/test/lua/baselib.lua +++ b/test/lua/baselib.lua @@ -72,8 +72,8 @@ print( 'pcall(pairs,"a")', pcall(pairs,"a") ) print( 'pcall(pairs,1)', pcall(pairs,1) ) for k,v in pairs({}) do print('pairs1',k,v)end for k,v in pairs({'one','two'}) do print('pairs2',k,v)end -for k,v in pairs({aa='aaa',bb='bbb'}) do print('pairs3',k,v)end -for k,v in pairs({aa='aaa',bb='bbb','one','two'}) do print('pairs4',k,v)end +for k,v in pairs({aa='aaa'}) do print('pairs3',k,v)end +for k,v in pairs({aa='aaa','one','two'}) do print('pairs4',k,v)end for k,v in pairs({[20]='30',[30]='20'}) do print('pairs5',k,v)end -- _G diff --git a/test/lua/luaj3.0-tests.zip b/test/lua/luaj3.0-tests.zip index 740fcbb7..50515d1c 100644 Binary files a/test/lua/luaj3.0-tests.zip and b/test/lua/luaj3.0-tests.zip differ diff --git a/test/lua/mathlib.lua b/test/lua/mathlib.lua index 9ed3ac3c..5f14e6f6 100644 --- a/test/lua/mathlib.lua +++ b/test/lua/mathlib.lua @@ -228,7 +228,6 @@ local x = -1 local mz, z = 0/x, 0 -- minus zero, zero print('mz, z', mz, z) print('mz == z', mz == z) -print('1/mz < 0 and 0 < 1/z', 1/mz < 0 and 0 < 1/z) local a = {[mz] = 1} print('a[z] == 1 and a[mz] == 1', a[z] == 1 and a[mz] == 1) -- string with same binary representation as 0.0 (may create problems