From a6be40dda96f13fc9e6d4dce8dd7c6774b7e9ddc Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 28 Apr 2019 13:45:26 +1000 Subject: [PATCH] oceani: delegate type compatability to type. 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 --- csrc/oceani.mdc | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index e29f891..a0fd796 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -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) -- 2.43.0