Refactor eq and __eq metatag processing.

This commit is contained in:
James Roseborough
2010-08-25 05:05:00 +00:00
parent d5b58107c6
commit c98a0cf799
12 changed files with 85 additions and 66 deletions

View File

@@ -70,4 +70,9 @@ public class LuaBoolean extends LuaValue {
public LuaValue getmetatable() {
return s_metatable;
}
// __eq metatag processing
public boolean eqmt( LuaValue val ) {
return s_metatable!=null && val.isboolean()? LuaValue.eqmtcall(this, val, s_metatable): false;
}
}

View File

@@ -75,10 +75,9 @@ public class LuaDouble extends LuaNumber {
public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; }
// arithmetic equality
public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v) || rhs.type()==TNUMBER && eqmt_b(rhs)? TRUE: FALSE; }
public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); }
public boolean eq_b( double rhs ) { return v == rhs; }
public boolean eq_b( int rhs ) { return v == rhs; }
public boolean raweq( LuaValue val ) { return val.raweq(v); }
public boolean raweq( double val ) { return v == val; }
public boolean raweq( int val ) { return v == val; }
// basic binary arithmetic
public LuaValue add( LuaValue rhs ) { return rhs.add(v); }

View File

@@ -68,5 +68,8 @@ public class LuaFunction extends LuaValue {
this.env = env!=null? env: NIL;
}
// __eq metatag processing
public boolean eqmt( LuaValue val ) {
return s_metatable!=null && val.isfunction()? LuaValue.eqmtcall(this, val, s_metatable): false;
}
}

View File

@@ -105,10 +105,9 @@ public class LuaInteger extends LuaNumber {
public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; }
// arithmetic equality
public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v) || rhs.type()==TNUMBER && eqmt_b(rhs)? TRUE: FALSE; }
public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); }
public boolean eq_b( double rhs ) { return v == rhs; }
public boolean eq_b( int rhs ) { return v == rhs; }
public boolean raweq( LuaValue val ) { return val.raweq(v); }
public boolean raweq( double val ) { return v == val; }
public boolean raweq( int val ) { return v == val; }
// arithmetic operators
public LuaValue add( LuaValue rhs ) { return rhs.add(v); }

View File

@@ -83,4 +83,9 @@ public class LuaNil extends LuaValue {
public Object optuserdata(Object defval) { return defval; }
public Object optuserdata(Class c, Object defval) { return defval; }
public LuaValue optvalue(LuaValue defval) { return defval; }
// __eq metatag processing
public boolean eqmt( LuaValue val ) {
return s_metatable!=null && val.isnil()? LuaValue.eqmtcall(this, val, s_metatable): false;
}
}

View File

@@ -67,4 +67,8 @@ public class LuaNumber extends LuaValue {
public LuaValue concatTo(LuaNumber lhs) { return strvalue().concatTo(lhs.strvalue()); }
public LuaValue concatTo(LuaString lhs) { return strvalue().concatTo(lhs); }
// __eq metatag processing
public boolean eqmt( LuaValue val ) {
return s_metatable!=null && val.isnumber()? LuaValue.eqmtcall(this, val, s_metatable): false;
}
}

View File

@@ -292,14 +292,16 @@ public class LuaString extends LuaValue {
// object comparison, used in key comparison
public boolean equals( Object o ) {
if ( o instanceof LuaString ) {
return eq_b( (LuaString) o );
return raweq( (LuaString) o );
}
return false;
}
public boolean eq_b( LuaString s ) {
if ( s == this )
return true;
public boolean raweq( LuaValue val ) {
return (this == val) || val.raweq(this);
}
public boolean raweq( LuaString s ) {
if ( s.m_length != m_length )
return false;
if ( s.m_bytes == m_bytes && s.m_offset == m_offset )
@@ -312,8 +314,9 @@ public class LuaString extends LuaValue {
return true;
}
public boolean eq_b( LuaValue val ) {
return val == this || (val.type()==TSTRING && val.eq_b(this));
// metatag equality
public boolean eqmt( LuaValue val ) {
return s_metatable!=null && val.type()==TSTRING? LuaValue.eqmtcall(this, val, s_metatable): false;
}
public static boolean equals( LuaString a, int i, LuaString b, int j, int n ) {

View File

@@ -287,18 +287,6 @@ public class LuaTable extends LuaValue {
return LuaInteger.valueOf(length());
}
public LuaValue eq( LuaValue rhs ) {
return rhs.eq_b(this)? TRUE: FALSE;
}
public boolean eq_b( LuaValue rhs ) {
return rhs.eq_b(this);
}
public boolean eq_b( LuaTable val ) {
return this == val || (m_metatable!=null && val.eqmt_b(this));
}
public int maxn() {
int n = 0;
for ( int i=0; i<array.length; i++ )
@@ -426,7 +414,7 @@ public class LuaTable extends LuaValue {
// This loop is guaranteed to terminate as long as we never allow the
// table to get 100% full.
LuaValue k;
while ( ( k = hashKeys[i] ) != null && !k.eq_b(key) ) {
while ( ( k = hashKeys[i] ) != null && !k.raweq(key) ) {
i = ( i + 1 ) % hashKeys.length;
}
return i;
@@ -587,4 +575,9 @@ public class LuaTable extends LuaValue {
l.copyInto(a);
return a;
}
// __eq metatag processing
public boolean eqmt( LuaValue val ) {
return m_metatable!=null && val.istable()? LuaValue.eqmtcall(this, m_metatable, val, val.getmetatable()): false;
}
}

View File

@@ -243,5 +243,9 @@ public class LuaThread extends LuaValue implements Runnable {
}
// __eq metatag processing
public boolean eqmt( LuaValue val ) {
return s_metatable!=null && val.isthread()? LuaValue.eqmtcall(this, val, s_metatable): false;
}
}

View File

@@ -104,15 +104,14 @@ public class LuaUserdata extends LuaValue {
return m_instance.equals(u.m_instance);
}
public LuaValue eq( LuaValue rhs ) {
return rhs.eq_b(this)? TRUE: FALSE;
// equality without metatag processing
public boolean raweq( LuaValue val ) { return val.raweq(this); }
public boolean raweq( LuaUserdata val ) {
return this == val || m_instance.equals(val.m_instance);
}
public boolean eq_b( LuaValue rhs ) {
return rhs.eq_b(this);
}
public boolean eq_b( LuaUserdata val ) {
return this == val || m_instance.equals(val.m_instance) || (m_metatable!=null && val.eqmt_b(this));
// __eq metatag processing
public boolean eqmt( LuaValue val ) {
return m_metatable!=null && val.isuserdata()? LuaValue.eqmtcall(this, m_metatable, val, val.getmetatable()): false;
}
}

View File

@@ -255,21 +255,30 @@ public class LuaValue extends Varargs {
// object equality, used for key comparison
public boolean equals(Object obj) { return this == obj; }
// arithmetic equality
public LuaValue eq( LuaValue val ) { return this == val || eq_b(val)? TRUE: FALSE; }
public boolean eq_b( LuaValue val ) { return this == val || (type() == val.type() && eqmt_b(val)); }
public boolean eq_b( LuaTable val ) { return false; }
public boolean eq_b( LuaUserdata val ) { return false; }
public boolean eq_b( LuaString val ) { return false; }
public boolean eq_b( double val ) { return false; }
public boolean eq_b( int val ) { return false; }
public LuaValue neq( LuaValue val ) { return eq_b(val)? FALSE: TRUE; }
public boolean neq_b( LuaValue val ) { return ! eq_b(val); }
public boolean neq_b( double val ) { return ! eq_b(val); }
public boolean neq_b( int val ) { return ! eq_b(val); }
protected boolean eqmt_b( LuaValue op2 ) {
LuaValue h = metatag(EQ);
return !h.isnil() && h==op2.metatag(EQ)? h.call(this,op2).toboolean(): false;
// arithmetic equality with metatag processing
public LuaValue eq( LuaValue val ) { return raweq(val) || eqmt(val)? TRUE: FALSE; }
public LuaValue neq( LuaValue val ) { return raweq(val) || eqmt(val)? FALSE: TRUE; }
public boolean eq_b( LuaValue val ) { return raweq(val) || eqmt(val); }
public boolean neq_b( LuaValue val ) { return !(raweq(val) || eqmt(val)); }
// equality without metatag processing
public boolean raweq( LuaValue val ) { return this == val; }
public boolean raweq( LuaUserdata val ) { return false; }
public boolean raweq( LuaString val ) { return false; }
public boolean raweq( double val ) { return false; }
public boolean raweq( int val ) { return false; }
// __eq metatag processing
public boolean eqmt( LuaValue val ) { return false; }
public static final boolean eqmtcall(LuaValue lhs, LuaValue lhsmt, LuaValue rhs, LuaValue rhsmt) {
if ( lhsmt == null || rhsmt == null ) return false;
LuaValue h = lhsmt.rawget(EQ);
return h.isnil() || h!=rhsmt.rawget(EQ)? false: h.call(lhs,rhs).toboolean();
}
public static final boolean eqmtcall(LuaValue lhs, LuaValue rhs, LuaValue sharedmt) {
if ( sharedmt == null ) return false;
LuaValue h = sharedmt.rawget(EQ);
return h.isnil()? false: h.call(lhs,rhs).toboolean();
}
// arithmetic operators

View File

@@ -137,7 +137,7 @@ public class WeakTable extends LuaTable {
return 0;
}
else {
if ( k.eq_b(key) )
if ( k.raweq(key) )
return i;
i = ( i + 1 ) % hashKeys.length;
}
@@ -205,9 +205,9 @@ public class WeakTable extends LuaTable {
return o!=null? (LuaValue)o: NIL;
}
public boolean eq_b(LuaValue rhs) {
public boolean raweq(LuaValue rhs) {
Object o = ref.get();
return o!=null && rhs.eq_b((LuaValue)o);
return o!=null && rhs.raweq((LuaValue)o);
}
public boolean isweaknil() {
@@ -233,11 +233,11 @@ public class WeakTable extends LuaTable {
return o!=null? userdataOf(o,mt): NIL;
}
public boolean eq_b(LuaValue rhs) {
public boolean raweq(LuaValue rhs) {
if ( ! rhs.isuserdata() )
return false;
LuaValue v = (LuaValue) ref.get();
if ( v != null && v.eq_b(rhs) )
if ( v != null && v.raweq(rhs) )
return true;
return rhs.touserdata() == ob.get();
}
@@ -287,15 +287,11 @@ public class WeakTable extends LuaTable {
return keyhash;
}
public boolean eq_b(LuaValue rhs) {
//return rhs.eq_b(weakkey.strongvalue());
return weakkey.eq_b(rhs);
public boolean raweq(LuaValue rhs) {
//return rhs.raweq(weakkey.strongvalue());
return weakkey.raweq(rhs);
}
public boolean eq_b( LuaString rhs ) { return false; }
public boolean eq_b( double val ) { return false; }
public boolean eq_b( int val ) { return false; }
public boolean isweaknil() {
return weakkey.isweaknil() || weakvalue.isweaknil();
}