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

@@ -69,5 +69,10 @@ public class LuaBoolean extends LuaValue {
public LuaValue getmetatable() { public LuaValue getmetatable() {
return s_metatable; 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; } public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; }
// arithmetic equality // arithmetic equality
public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v) || rhs.type()==TNUMBER && eqmt_b(rhs)? TRUE: FALSE; } public boolean raweq( LuaValue val ) { return val.raweq(v); }
public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); } public boolean raweq( double val ) { return v == val; }
public boolean eq_b( double rhs ) { return v == rhs; } public boolean raweq( int val ) { return v == val; }
public boolean eq_b( int rhs ) { return v == rhs; }
// basic binary arithmetic // basic binary arithmetic
public LuaValue add( LuaValue rhs ) { return rhs.add(v); } 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; 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; } public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; }
// arithmetic equality // arithmetic equality
public LuaValue eq( LuaValue rhs ) { return rhs.eq_b(v) || rhs.type()==TNUMBER && eqmt_b(rhs)? TRUE: FALSE; } public boolean raweq( LuaValue val ) { return val.raweq(v); }
public boolean eq_b( LuaValue rhs ) { return rhs.eq_b(v); } public boolean raweq( double val ) { return v == val; }
public boolean eq_b( double rhs ) { return v == rhs; } public boolean raweq( int val ) { return v == val; }
public boolean eq_b( int rhs ) { return v == rhs; }
// arithmetic operators // arithmetic operators
public LuaValue add( LuaValue rhs ) { return rhs.add(v); } 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(Object defval) { return defval; }
public Object optuserdata(Class c, Object defval) { return defval; } public Object optuserdata(Class c, Object defval) { return defval; }
public LuaValue optvalue(LuaValue 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(LuaNumber lhs) { return strvalue().concatTo(lhs.strvalue()); }
public LuaValue concatTo(LuaString lhs) { return strvalue().concatTo(lhs); } 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 // object comparison, used in key comparison
public boolean equals( Object o ) { public boolean equals( Object o ) {
if ( o instanceof LuaString ) { if ( o instanceof LuaString ) {
return eq_b( (LuaString) o ); return raweq( (LuaString) o );
} }
return false; return false;
} }
public boolean eq_b( LuaString s ) { public boolean raweq( LuaValue val ) {
if ( s == this ) return (this == val) || val.raweq(this);
return true; }
public boolean raweq( LuaString s ) {
if ( s.m_length != m_length ) if ( s.m_length != m_length )
return false; return false;
if ( s.m_bytes == m_bytes && s.m_offset == m_offset ) if ( s.m_bytes == m_bytes && s.m_offset == m_offset )
@@ -311,9 +313,10 @@ public class LuaString extends LuaValue {
return false; return false;
return true; return true;
} }
public boolean eq_b( LuaValue val ) { // metatag equality
return val == this || (val.type()==TSTRING && val.eq_b(this)); 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 ) { public static boolean equals( LuaString a, int i, LuaString b, int j, int n ) {

View File

@@ -286,18 +286,6 @@ public class LuaTable extends LuaValue {
public LuaValue len() { public LuaValue len() {
return LuaInteger.valueOf(length()); 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() { public int maxn() {
int n = 0; int n = 0;
@@ -426,7 +414,7 @@ public class LuaTable extends LuaValue {
// This loop is guaranteed to terminate as long as we never allow the // This loop is guaranteed to terminate as long as we never allow the
// table to get 100% full. // table to get 100% full.
LuaValue k; LuaValue k;
while ( ( k = hashKeys[i] ) != null && !k.eq_b(key) ) { while ( ( k = hashKeys[i] ) != null && !k.raweq(key) ) {
i = ( i + 1 ) % hashKeys.length; i = ( i + 1 ) % hashKeys.length;
} }
return i; return i;
@@ -587,4 +575,9 @@ public class LuaTable extends LuaValue {
l.copyInto(a); l.copyInto(a);
return 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

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

View File

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

View File

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