Răsfoiți Sursa

Added object eqq and neqq methods. Expanded gravity_value_equals to support Lists and Maps.

Marco Bambini 8 ani în urmă
părinte
comite
732091c6bd

+ 24 - 0
src/runtime/gravity_core.c

@@ -400,6 +400,28 @@ static bool object_isa (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, u
 	RETURN_VALUE(VALUE_FROM_BOOL(c1 == c2), rindex);
 }
 
+static bool object_eqq (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    
+    gravity_value_t v1 = GET_VALUE(0);
+    gravity_value_t v2 = GET_VALUE(1);
+    
+    // compare class first
+    if (gravity_value_getclass(v1) != gravity_value_getclass(v2))
+        RETURN_VALUE(VALUE_FROM_FALSE, rindex);
+    
+    // then compare value
+    RETURN_VALUE(VALUE_FROM_BOOL(gravity_value_equals(v1, v2)), rindex);
+}
+
+static bool object_neqq (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    object_eqq(vm, args, nargs, rindex);
+    gravity_value_t value = GET_VALUE(rindex);
+    if (VALUE_ISA_BOOL(value)) {
+         RETURN_VALUE(VALUE_FROM_BOOL(!VALUE_AS_BOOL(value)), rindex);
+    }
+    return true;
+}
 
 static bool object_cmp (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
 	#pragma unused(vm, nargs)
@@ -2158,6 +2180,8 @@ static void gravity_core_init (void) {
 	gravity_class_bind(gravity_class_object, GRAVITY_CLASS_CLASS_NAME, NEW_CLOSURE_VALUE(object_class));
 	gravity_class_bind(gravity_class_object, GRAVITY_OPERATOR_ISA_NAME, NEW_CLOSURE_VALUE(object_isa));
 	gravity_class_bind(gravity_class_object, GRAVITY_OPERATOR_CMP_NAME, NEW_CLOSURE_VALUE(object_cmp));
+    gravity_class_bind(gravity_class_object, GRAVITY_OPERATOR_EQQ_NAME, NEW_CLOSURE_VALUE(object_eqq));
+    gravity_class_bind(gravity_class_object, GRAVITY_OPERATOR_NEQQ_NAME, NEW_CLOSURE_VALUE(object_neqq));
 	gravity_class_bind(gravity_class_object, GRAVITY_CLASS_INT_NAME, NEW_CLOSURE_VALUE(convert_object_int));
 	gravity_class_bind(gravity_class_object, GRAVITY_CLASS_FLOAT_NAME, NEW_CLOSURE_VALUE(convert_object_float));
 	gravity_class_bind(gravity_class_object, GRAVITY_CLASS_BOOL_NAME, NEW_CLOSURE_VALUE(convert_object_bool));

+ 1 - 0
src/shared/gravity_opcodes.h

@@ -182,6 +182,7 @@ typedef enum {
 #define GRAVITY_OPERATOR_OR_NAME		"||"
 #define GRAVITY_OPERATOR_CMP_NAME		"=="
 #define GRAVITY_OPERATOR_EQQ_NAME		"==="
+#define GRAVITY_OPERATOR_NEQQ_NAME      "!=="
 #define GRAVITY_OPERATOR_ISA_NAME		"is"
 #define GRAVITY_OPERATOR_MATCH_NAME		"=~"
 #define GRAVITY_OPERATOR_NEG_NAME		"neg"

+ 19 - 0
src/shared/gravity_value.c

@@ -1389,6 +1389,10 @@ void gravity_instance_blacken (gravity_vm *vm, gravity_instance_t *i) {
 }
 	
 // MARK: -
+static bool hash_value_compare_cb (gravity_value_t v1, gravity_value_t v2, void *data) {
+    #pragma unused (data)
+    return gravity_value_equals(v1, v2);
+}
 
 bool gravity_value_equals (gravity_value_t v1, gravity_value_t v2) {
 	
@@ -1415,6 +1419,21 @@ bool gravity_value_equals (gravity_value_t v1, gravity_value_t v2) {
         gravity_range_t *r1 = VALUE_AS_RANGE(v1);
         gravity_range_t *r2 = VALUE_AS_RANGE(v2);
         return ((r1->from == r2->from) && (r1->to == r2->to));
+    } else if (v1.isa == gravity_class_list) {
+        gravity_list_t *list1 = VALUE_AS_LIST(v1);
+        gravity_list_t *list2 = VALUE_AS_LIST(v2);
+        if (marray_size(list1->array) != marray_size(list2->array)) return false;
+        size_t count = marray_size(list1->array);
+        for (size_t i=0; i<count; ++i) {
+            gravity_value_t value1 = marray_get(list1->array, i);
+            gravity_value_t value2 = marray_get(list2->array, i);
+            if (!gravity_value_equals(value1, value2)) return false;
+        }
+        return true;
+    } else if (v1.isa == gravity_class_map) {
+        gravity_map_t *map1 = VALUE_AS_MAP(v1);
+        gravity_map_t *map2 = VALUE_AS_MAP(v2);
+        return gravity_hash_compare(map1->hash, map2->hash, hash_value_compare_cb, NULL);
 	}
 	
 	// if here means that they are two heap allocated objects

+ 0 - 1
src/shared/gravity_value.h

@@ -176,7 +176,6 @@ typedef struct {
 extern gravity_class_t *gravity_class_object;
 extern gravity_class_t *gravity_class_bool;
 extern gravity_class_t *gravity_class_null;
-extern gravity_class_t *gravity_class_undefined;
 extern gravity_class_t *gravity_class_int;
 extern gravity_class_t *gravity_class_float;
 extern gravity_class_t *gravity_class_function;