@@ -1310,6 +1310,24 @@ typval_compare(
13101310 }
13111311 n1 = res ;
13121312 }
1313+ else if (tv1 -> v_type == VAR_CLASS || tv2 -> v_type == VAR_CLASS )
1314+ {
1315+ if (typval_compare_class (tv1 , tv2 , type , ic , & res ) == FAIL )
1316+ {
1317+ clear_tv (tv1 );
1318+ return FAIL ;
1319+ }
1320+ n1 = res ;
1321+ }
1322+ else if (tv1 -> v_type == VAR_OBJECT || tv2 -> v_type == VAR_OBJECT )
1323+ {
1324+ if (typval_compare_object (tv1 , tv2 , type , ic , & res ) == FAIL )
1325+ {
1326+ clear_tv (tv1 );
1327+ return FAIL ;
1328+ }
1329+ n1 = res ;
1330+ }
13131331 else if (tv1 -> v_type == VAR_DICT || tv2 -> v_type == VAR_DICT )
13141332 {
13151333 if (typval_compare_dict (tv1 , tv2 , type , ic , & res ) == FAIL )
@@ -1579,6 +1597,77 @@ typval_compare_blob(
15791597 return OK ;
15801598}
15811599
1600+ /*
1601+ * Compare "tv1" to "tv2" as classes according to "type".
1602+ * Put the result, false or true, in "res".
1603+ * Return FAIL and give an error message when the comparison can't be done.
1604+ */
1605+ int
1606+ typval_compare_class (
1607+ typval_T * tv1 ,
1608+ typval_T * tv2 ,
1609+ exprtype_T type UNUSED ,
1610+ int ic UNUSED ,
1611+ int * res )
1612+ {
1613+ // TODO: use "type"
1614+ * res = tv1 -> vval .v_class == tv2 -> vval .v_class ;
1615+ return OK ;
1616+ }
1617+
1618+ /*
1619+ * Compare "tv1" to "tv2" as objects according to "type".
1620+ * Put the result, false or true, in "res".
1621+ * Return FAIL and give an error message when the comparison can't be done.
1622+ */
1623+ int
1624+ typval_compare_object (
1625+ typval_T * tv1 ,
1626+ typval_T * tv2 ,
1627+ exprtype_T type ,
1628+ int ic ,
1629+ int * res )
1630+ {
1631+ int res_match = type == EXPR_EQUAL || type == EXPR_IS ? TRUE : FALSE;
1632+
1633+ if (tv1 -> vval .v_object == NULL && tv2 -> vval .v_object == NULL )
1634+ {
1635+ * res = res_match ;
1636+ return OK ;
1637+ }
1638+ if (tv1 -> vval .v_object == NULL || tv2 -> vval .v_object == NULL )
1639+ {
1640+ * res = !res_match ;
1641+ return OK ;
1642+ }
1643+
1644+ class_T * cl1 = tv1 -> vval .v_object -> obj_class ;
1645+ class_T * cl2 = tv2 -> vval .v_object -> obj_class ;
1646+ if (cl1 != cl2 || cl1 == NULL || cl2 == NULL )
1647+ {
1648+ * res = !res_match ;
1649+ return OK ;
1650+ }
1651+
1652+ object_T * obj1 = tv1 -> vval .v_object ;
1653+ object_T * obj2 = tv2 -> vval .v_object ;
1654+ if (type == EXPR_IS || type == EXPR_ISNOT )
1655+ {
1656+ * res = obj1 == obj2 ? res_match : !res_match ;
1657+ return OK ;
1658+ }
1659+
1660+ for (int i = 0 ; i < cl1 -> class_obj_member_count ; ++ i )
1661+ if (!tv_equal ((typval_T * )(obj1 + 1 ) + i ,
1662+ (typval_T * )(obj2 + 1 ) + i , ic , TRUE))
1663+ {
1664+ * res = !res_match ;
1665+ return OK ;
1666+ }
1667+ * res = res_match ;
1668+ return OK ;
1669+ }
1670+
15821671/*
15831672 * Compare "tv1" to "tv2" as dictionaries according to "type" and "ic".
15841673 * Put the result, false or true, in "res".
@@ -1920,11 +2009,12 @@ tv_equal(
19202009 return tv1 -> vval .v_instr == tv2 -> vval .v_instr ;
19212010
19222011 case VAR_CLASS :
2012+ // A class only exists once, equality is identity.
19232013 return tv1 -> vval .v_class == tv2 -> vval .v_class ;
19242014
19252015 case VAR_OBJECT :
1926- // TODO: compare values
1927- return tv1 -> vval . v_object == tv2 -> vval . v_object ;
2016+ ( void ) typval_compare_object ( tv1 , tv2 , EXPR_EQUAL , ic , & r );
2017+ return r ;
19282018
19292019 case VAR_PARTIAL :
19302020 return tv1 -> vval .v_partial == tv2 -> vval .v_partial ;
0 commit comments