]> ocean-lang.org Git - ocean/commitdiff
oceani: delegate type compatability to type.
authorNeilBrown <neil@brown.name>
Sun, 28 Apr 2019 03:45:26 +0000 (13:45 +1000)
committerNeilBrown <neil@brown.name>
Wed, 1 May 2019 08:09:53 +0000 (18:09 +1000)
Rename vtype_compat to type_compat, and have it
call the ->compat function if the required type
provides it.
Otherwise require type equivalence.

Signed-off-by: NeilBrown <neil@brown.name>
csrc/oceani.mdc

index e29f8915a856e9620c5c26e1dd4be63f6a0ec664..a0fd796bbcc0478881dc15cadc9948be3f7a1f44 100644 (file)
@@ -454,7 +454,7 @@ which are often passed around by value.
                int (*cmp_eq)(struct value v1, struct value v2);
                struct value (*dup)(struct value val);
                void (*free)(struct value val);
-               struct type *(*compat)(struct type *this, struct type *other);
+               int (*compat)(struct type *this, struct type *other);
                long long (*to_int)(struct value *v);
                double (*to_float)(struct value *v);
                int (*to_mpq)(mpq_t *q, struct value *v);
@@ -505,6 +505,21 @@ which are often passed around by value.
                        v.type->free(v);
        }
 
+       static int type_compat(struct type *require, struct type *have, int rules)
+       {
+               if ((rules & Rboolok) && have == Tbool)
+                       return 1;
+               if ((rules & Rnolabel) && have == Tlabel)
+                       return 0;
+               if (!require || !have)
+                       return 1;
+
+               if (require->compat)
+                       return require->compat(require, have);
+
+               return require == have;
+       }
+
        static struct value val_prepare(struct type *type)
        {
                struct value rv;
@@ -620,18 +635,6 @@ to parse each type from a string.
                }
        }
 
-       static int vtype_compat(struct type *require, struct type *have, int rules)
-       {
-               if ((rules & Rboolok) && have == Tbool)
-                       return 1;
-               if ((rules & Rnolabel) && have == Tlabel)
-                       return 0;
-               if (!require || !have)
-                       return 1;
-
-               return require == have;
-       }
-
 ###### value functions
 
        static struct value _val_prepare(struct type *type)
@@ -1560,7 +1563,7 @@ an executable.
                case Xval:
                {
                        struct val *val = cast(val, prog);
-                       if (!vtype_compat(type, val->val.type, rules)) {
+                       if (!type_compat(type, val->val.type, rules)) {
                                type_err(c, "error: expected %1%r found %2",
                                           prog, type, rules, val->val.type);
                                *ok = 0;
@@ -1764,7 +1767,7 @@ link to find the primary instance.
                        }
                        return type;
                }
-               if (!vtype_compat(type, v->val.type, rules)) {
+               if (!type_compat(type, v->val.type, rules)) {
                        type_err(c, "error: expected %1%r but variable '%v' is %2", prog,
                                 type, rules, v->val.type);
                        type_err(c, "info: this is where '%v' was set to %1", v->where_set,
@@ -1973,7 +1976,7 @@ expression operator.
                        if (t)
                                t = propagate_types(b->left, c, ok, t, 0);
                }
-               if (!vtype_compat(type, Tbool, 0)) {
+               if (!type_compat(type, Tbool, 0)) {
                        type_err(c, "error: Comparison returns %1 but %2 expected", prog,
                                    Tbool, rules, type);
                        *ok = 0;
@@ -2116,7 +2119,7 @@ precedence is handled better I might be able to discard this.
                 * unary ops fit here too */
                propagate_types(b->left, c, ok, Tnum, 0);
                propagate_types(b->right, c, ok, Tnum, 0);
-               if (!vtype_compat(type, Tnum, 0)) {
+               if (!type_compat(type, Tnum, 0)) {
                        type_err(c, "error: Arithmetic returns %1 but %2 expected", prog,
                                   Tnum, rules, type);
                        *ok = 0;
@@ -2127,7 +2130,7 @@ precedence is handled better I might be able to discard this.
                /* both must be Tstr, result is Tstr */
                propagate_types(b->left, c, ok, Tstr, 0);
                propagate_types(b->right, c, ok, Tstr, 0);
-               if (!vtype_compat(type, Tstr, 0)) {
+               if (!type_compat(type, Tstr, 0)) {
                        type_err(c, "error: Concat returns %1 but %2 expected", prog,
                                   Tstr, rules, type);
                        *ok = 0;
@@ -3029,14 +3032,14 @@ defined.
                struct casepart *cp;
 
                t = propagate_types(cs->forpart, c, ok, Tnone, 0);
-               if (!vtype_compat(Tnone, t, 0))
+               if (!type_compat(Tnone, t, 0))
                        *ok = 0;
                t = propagate_types(cs->dopart, c, ok, Tnone, 0);
-               if (!vtype_compat(Tnone, t, 0))
+               if (!type_compat(Tnone, t, 0))
                        *ok = 0;
                if (cs->dopart) {
                        t = propagate_types(cs->thenpart, c, ok, Tnone, 0);
-                       if (!vtype_compat(Tnone, t, 0))
+                       if (!type_compat(Tnone, t, 0))
                                *ok = 0;
                }
                if (cs->casepart == NULL)