Improve compatibility with lua 5.2.

This commit is contained in:
James Roseborough
2012-09-20 05:15:31 +00:00
parent 406068190b
commit 4d8877e56b
7 changed files with 69 additions and 41 deletions

View File

@@ -47,8 +47,14 @@ public class LuaError extends RuntimeException {
protected Throwable cause; protected Throwable cause;
public String getMessage() { public String getMessage() {
return traceback != null? traceback: if (traceback != null)
(fileline != null? fileline + " ": "") + super.getMessage(); 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. /** Construct LuaError when a program exception occurs.

View File

@@ -183,29 +183,29 @@ public class LuaString extends LuaValue {
} }
// unary operators // 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 // 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( double rhs ) { return valueOf( checkarith() + rhs ); }
public LuaValue add( int 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( double rhs ) { return valueOf( checkarith() - rhs ); }
public LuaValue sub( int 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 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( double rhs ) { return valueOf( checkarith() * rhs ); }
public LuaValue mul( int 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( double rhs ) { return MathLib.dpow(checkarith(),rhs); }
public LuaValue pow( int 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( double lhs ) { return MathLib.dpow(lhs, checkarith()); }
public LuaValue powWith( int 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( double rhs ) { return LuaDouble.ddiv(checkarith(),rhs); }
public LuaValue div( int 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 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( double rhs ) { return LuaDouble.dmod(checkarith(), rhs); }
public LuaValue mod( int 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()); } 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 */ /** Check for number in arithmetic, or throw aritherror */
private double checkarith() { private double checkarith() {
double d = scannumber(10); double d = scannumber();
if ( Double.isNaN(d) ) if ( Double.isNaN(d) )
aritherror(); aritherror();
return d; return d;
@@ -268,7 +268,7 @@ public class LuaString extends LuaValue {
return (long) checkdouble(); return (long) checkdouble();
} }
public double checkdouble() { public double checkdouble() {
double d = scannumber(10); double d = scannumber();
if ( Double.isNaN(d) ) if ( Double.isNaN(d) )
argerror("number"); argerror("number");
return d; return d;
@@ -277,22 +277,19 @@ public class LuaString extends LuaValue {
return valueOf(checkdouble()); return valueOf(checkdouble());
} }
public LuaNumber checknumber(String msg) { public LuaNumber checknumber(String msg) {
double d = scannumber(10); double d = scannumber();
if ( Double.isNaN(d) ) if ( Double.isNaN(d) )
argerror("number"); argerror("number");
return valueOf(d); return valueOf(d);
} }
public LuaValue tonumber() {
return tonumber(10);
}
public boolean isnumber() { public boolean isnumber() {
double d = scannumber(10); double d = scannumber();
return ! Double.isNaN(d); return ! Double.isNaN(d);
} }
public boolean isint() { public boolean isint() {
double d = scannumber(10); double d = scannumber();
if ( Double.isNaN(d) ) if ( Double.isNaN(d) )
return false; return false;
int i = (int) d; int i = (int) d;
@@ -300,7 +297,7 @@ public class LuaString extends LuaValue {
} }
public boolean islong() { public boolean islong() {
double d = scannumber(10); double d = scannumber();
if ( Double.isNaN(d) ) if ( Double.isNaN(d) )
return false; return false;
long l = (long) d; long l = (long) d;
@@ -309,7 +306,7 @@ public class LuaString extends LuaValue {
public byte tobyte() { return (byte) toint(); } public byte tobyte() { return (byte) toint(); }
public char tochar() { return (char) 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 float tofloat() { return (float) todouble(); }
public int toint() { return (int) tolong(); } public int toint() { return (int) tolong(); }
public long tolong() { return (long) todouble(); } public long tolong() { return (long) todouble(); }
@@ -627,6 +624,17 @@ public class LuaString extends LuaValue {
// --------------------- number conversion ----------------------- // --------------------- 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 * 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 * @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. * Convert to a number in base 10, or base 16 if the string starts with '0x',
* @param base the base to use, such as 10 * or return Double.NaN if it cannot be converted to a number.
* @return double value if conversion is valid, or Double.NaN if not * @return double value if conversion is valid, or Double.NaN if not
*/ */
public double scannumber( int base ) { public double scannumber() {
if ( base >= 2 && base <= 36 ) {
int i=m_offset,j=m_offset+m_length; int i=m_offset,j=m_offset+m_length;
while ( i<j && m_bytes[i]==' ' ) ++i; while ( i<j && m_bytes[i]==' ' ) ++i;
while ( i<j && m_bytes[j-1]==' ' ) --j; while ( i<j && m_bytes[j-1]==' ' ) --j;
if ( i>=j ) if ( i>=j )
return Double.NaN; return Double.NaN;
if ( ( base == 10 || base == 16 ) && ( m_bytes[i]=='0' && i+1<j && (m_bytes[i+1]=='x'||m_bytes[i+1]=='X') ) ) { if ( m_bytes[i]=='0' && i+1<j && (m_bytes[i+1]=='x'||m_bytes[i+1]=='X'))
base = 16; return scanlong(16, i+2, j);
i+=2; double l = scanlong(10, i, j);
} return Double.isNaN(l)? scandouble(i,j): l;
double l = scanlong( base, i, j );
return Double.isNaN(l) && base==10? scandouble(i,j): l;
} }
/**
* Convert to a number in a base, or return Double.NaN if not a number.
* @param base the base to use between 2 and 36
* @return double value if conversion is valid, or Double.NaN if not
*/
public double scannumber(int base) {
if ( base < 2 || base > 36 )
return Double.NaN; return Double.NaN;
int i=m_offset,j=m_offset+m_length;
while ( i<j && m_bytes[i]==' ' ) ++i;
while ( i<j && m_bytes[j-1]==' ' ) --j;
if ( i>=j )
return Double.NaN;
return scanlong( base, i, j );
} }
/** /**

View File

@@ -321,7 +321,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
public LuaValue call(LuaValue e, LuaValue base) { public LuaValue call(LuaValue e, LuaValue base) {
if (base.isnil()) if (base.isnil())
return e.tonumber(); return e.tonumber();
final int b = base.optint(10); final int b = base.checkint();
if ( b < 2 || b > 36 ) if ( b < 2 || b > 36 )
argerror(2, "base out of range"); argerror(2, "base out of range");
return e.checkstring().tonumber(b); return e.checkstring().tonumber(b);

View File

@@ -555,5 +555,10 @@ public class FragmentsTest extends TestSuite {
"end\n"+ "end\n"+
"g()\n"); "g()\n");
} }
public void testNullError() {
runFragment( LuaValue.varargsOf(LuaValue.FALSE, LuaValue.NIL),
"return pcall(error)\n");
}
} }
} }

View File

@@ -72,8 +72,8 @@ print( 'pcall(pairs,"a")', pcall(pairs,"a") )
print( 'pcall(pairs,1)', pcall(pairs,1) ) print( 'pcall(pairs,1)', pcall(pairs,1) )
for k,v in pairs({}) do print('pairs1',k,v)end 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({'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'}) 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','one','two'}) do print('pairs4',k,v)end
for k,v in pairs({[20]='30',[30]='20'}) do print('pairs5',k,v)end for k,v in pairs({[20]='30',[30]='20'}) do print('pairs5',k,v)end
-- _G -- _G

Binary file not shown.

View File

@@ -228,7 +228,6 @@ local x = -1
local mz, z = 0/x, 0 -- minus zero, zero local mz, z = 0/x, 0 -- minus zero, zero
print('mz, z', mz, z) print('mz, z', mz, z)
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} local a = {[mz] = 1}
print('a[z] == 1 and a[mz] == 1', a[z] == 1 and 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 -- string with same binary representation as 0.0 (may create problems