Browse Source

Allow for for deep equality comparison for SquiLu objects

mingodad 7 years ago
parent
commit
a373d9a05f
4 changed files with 67 additions and 3 deletions
  1. 2 2
      SquiLu/squirrel/sqbaselib.cpp
  2. 16 1
      SquiLu/squirrel/sqvm.cpp
  3. 1 0
      SquiLu/squirrel/sqvm.h
  4. 48 0
      SquiLu/tests/squilu-test.nut

+ 2 - 2
SquiLu/squirrel/sqbaselib.cpp

@@ -596,7 +596,7 @@ static SQRegFunction base_funcs[]={
 	{_SC("table_setdelegate"),bf_table_setdelegate,3, _SC(".t t|o")},
 	{_SC("table_getdelegate"),bf_table_getdelegate,2, _SC(".t")},
 	{_SC("table_getdelegate_squirrel"),bf_table_getdelegate_squirrel,1, _SC(".")},
-	{_SC("obj_clone"),bf_obj_clone,2, _SC(". t|a|x")},
+	{_SC("obj_clone"),bf_obj_clone,2, _SC(". t|a|x|i|f|s")},
 	{NULL,(SQFUNCTION)0,0,NULL}
 };
 
@@ -1022,7 +1022,7 @@ static SQRESULT array_find(HSQUIRRELVM v)
 	SQObjectPtr temp;
 	for(SQInteger n = 0; n < size; n++) {
 		a->Get(n,temp);
-		if(SQVM::IsEqual(temp,val)) {
+		if(v->IsEqual(temp,val)) {
 			v->Push(n);
 			return 1;
 		}

+ 16 - 1
SquiLu/squirrel/sqvm.cpp

@@ -715,6 +715,16 @@ bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes
 	return true;
 }
 
+bool SQVM::IsEqualDeep(const SQObjectPtr &o1,const SQObjectPtr &o2)
+{
+	if(sq_type(o1) == sq_type(o2)) {
+		if(_rawval(o1) == _rawval(o2)) return true;
+        SQInteger rc;
+        if(ObjCmp(o1, o2, rc) && (rc == 0)) return true;
+        return false;
+	}
+	return IsEqual(o1, o2);
+}
 bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2)
 {
 	bool res = false;
@@ -1071,7 +1081,7 @@ exception_restore:
 				_Swap(TARGET,temp_reg);//TARGET = temp_reg;
 				continue;}
 			OPCODE_TARGET(EQ) {
-				TARGET = IsEqual(STK(arg2),COND_LITERAL)?true:false;
+				TARGET = IsEqualDeep(STK(arg2),COND_LITERAL)?true:false;
 				continue;}
 			OPCODE_TARGET(EQI) {
 				TARGET = IsEqualIdentity(STK(arg2),COND_LITERAL)?true:false;
@@ -1692,6 +1702,11 @@ cloned_mt:
 	case OT_ARRAY:
 		target = _array(self)->Clone();
 		return true;
+	case OT_INTEGER:
+	case OT_FLOAT:
+	case OT_STRING:
+		target = self;
+		return true;
 	default:
 		Raise_Error(_SC("cloning a %s"), GetTypeName(self));
 		return false;

+ 1 - 0
SquiLu/squirrel/sqvm.h

@@ -90,6 +90,7 @@ public:
 	bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
 	bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
 	bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
+	bool IsEqualDeep(const SQObjectPtr &o1,const SQObjectPtr &o2);
 	static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2);
 	static bool IsEqualIdentity(const SQObjectPtr &o1,const SQObjectPtr &o2);
 	bool ToString(const SQObjectPtr &o,SQObjectPtr &res);

+ 48 - 0
SquiLu/tests/squilu-test.nut

@@ -150,6 +150,8 @@ sqt.run("closures", function(){
 sqt.run("calls", function(){
 
 	// get the opportunity to test "type" too ;)
+	local Klass = class {};
+	local aklass = Klass();
 
 	sqt.ok(type(1<2) == "bool")
 	sqt.ok(type(true) == "bool" && type(false) == "bool")
@@ -159,6 +161,8 @@ sqt.run("calls", function(){
 	sqt.ok(type("x") == "string")
 	sqt.ok(type({}) == "table")
 	sqt.ok(type(type) == "function")
+	sqt.ok(type(Klass) == "class")
+	sqt.ok(type(aklass) == "instance")
 
 	sqt.ok(type(sqt.ok) == type(print))
 	local f = null
@@ -1571,4 +1575,48 @@ sqt.run("constants", function(){
 	//print(dostring("return $CTC == \"CTC\";"));
 });
 
+sqt.run("class", function(){
+
+	class Comparable {
+		constructor(n)
+		{
+			name = n;
+		}
+
+		function _typeof() {return "Comparable";};
+
+		function _cmp(other)
+		{
+			if(name<other.name) return -1;
+			if(name>other.name) return 1;
+			return 0;
+		}
+		static function st() {return "st";};
+		name = null;
+		id = 0;
+		static count = 0;
+	}
+	local a = Comparable("Alberto");
+	local b = Comparable("Wouter");
+	local c = Comparable("Alberto");
+	sqt.ok(a < b);
+	sqt.ok(b > a);
+	sqt.ok(a.id == 0);
+	sqt.ok(Comparable.count == 0);
+	sqt.ok(a.count == 0);
+	sqt.ok(Comparable.st() == "st");
+	sqt.ok(a.st() == "st");
+	sqt.ok(typeof(a) == "Comparable");
+	sqt.ok( c == a );
+	sqt.ok( c !== a );
+
+});
+
+sqt.run("globals", function(){
+
+	sqt.ok( obj_clone(3) == 3 );
+	sqt.ok( obj_clone(3.4) == 3.4 );
+	sqt.ok( obj_clone("str") == "str" );
+});
+
 return sqt.results();           //show results