]> ocean-lang.org Git - ocean/commitdiff
oceani: setting ->parse_error now aborts type analysis.
authorNeilBrown <neil@brown.name>
Thu, 6 Jun 2019 22:31:07 +0000 (08:31 +1000)
committerNeilBrown <neil@brown.name>
Thu, 6 Jun 2019 22:31:07 +0000 (08:31 +1000)
When ever we call type_err() or tok_err(), in type analysis,
we currently need to also set *ok=0;  This is uhly and error-prone.

So instead, we can detect ->parse_error being set, and assume
something is no OK.
This is most easily done in a wrapper for propagate_types.

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

index f4d8517f2692bac0623cb2da5bab58f4d4fa05ab..1f4805e85eb9a901571474f45051b618ca60fee6 100644 (file)
@@ -1455,7 +1455,9 @@ propagation is needed.
 ###### core functions
 
        static struct type *propagate_types(struct exec *prog, struct parse_context *c, int *ok,
-                                           struct type *type, int rules)
+                                           struct type *type, int rules);
+       static struct type *__propagate_types(struct exec *prog, struct parse_context *c, int *ok,
+                                             struct type *type, int rules)
        {
                struct type *t;
 
@@ -1476,6 +1478,16 @@ propagation is needed.
                return Tnone;
        }
 
+       static struct type *propagate_types(struct exec *prog, struct parse_context *c, int *ok,
+                                           struct type *type, int rules)
+       {
+               struct type *ret = __propagate_types(prog, c, ok, type, rules);
+
+               if (c->parse_error)
+                       *ok = 0;
+               return ret;
+       }
+
 #### Interpreting
 
 Interpreting an `exec` doesn't require anything but the `exec`.  State
@@ -1746,13 +1758,11 @@ make a copy of an array with controllable depth.
                t = propagate_types(b->left, c, ok, NULL, rules & Rnoconstant);
                if (!t || t->compat != array_compat) {
                        type_err(c, "error: %1 cannot be indexed", prog, t, 0, NULL);
-                       *ok = 0;
                        return NULL;
                } else {
                        if (!type_compat(type, t->array.member, rules)) {
                                type_err(c, "error: have %1 but need %2", prog,
                                         t->array.member, rules, type);
-                               *ok = 0;
                        }
                        return t->array.member;
                }
@@ -1949,19 +1959,15 @@ function will be needed.
                                 f->left, st, 0, NULL);
                else if (f->index == -2) {
                        f->index = find_struct_index(st, f->name);
-                       if (f->index < 0) {
+                       if (f->index < 0)
                                type_err(c, "error: cannot find requested field in %1",
                                         f->left, st, 0, NULL);
-                               *ok = 0;
-                       }
                }
                if (f->index >= 0) {
                        struct type *ft = st->structure.fields[f->index].type;
-                       if (!type_compat(type, ft, rules)) {
+                       if (!type_compat(type, ft, rules))
                                type_err(c, "error: have %1 but need %2", prog,
                                         ft, rules, type);
-                               *ok = 0;
-                       }
                        return ft;
                }
                break;
@@ -2196,11 +2202,9 @@ an executable.
        case Xval:
        {
                struct val *val = cast(val, prog);
-               if (!type_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;
-               }
                return val->val.type;
        }
 
@@ -2391,7 +2395,6 @@ link to find the primary instance.
                struct variable *v = var->var;
                if (!v) {
                        type_err(c, "%d:BUG: no variable!!", prog, NULL, 0, NULL); // NOTEST
-                       *ok = 0;                                        // NOTEST
                        return Tnone;                                   // NOTEST
                }
                if (v->merged)
@@ -2401,7 +2404,6 @@ link to find the primary instance.
                                 prog, NULL, 0, NULL);
                        type_err(c, "info: name was defined as a constant here",
                                 v->where_decl, NULL, 0, NULL);
-                       *ok = 0;
                        return v->val.type;
                }
                if (v->val.type == NULL) {
@@ -2417,7 +2419,6 @@ link to find the primary instance.
                                 type, rules, v->val.type);
                        type_err(c, "info: this is where '%v' was set to %1", v->where_set,
                                 v->val.type, rules, NULL);
-                       *ok = 0;
                }
                if (!type)
                        return v->val.type;
@@ -2612,11 +2613,9 @@ if the result would make a difference.
                /* both must be Tbool, result is Tbool */
                propagate_types(b->left, c, ok, Tbool, 0);
                propagate_types(b->right, c, ok, Tbool, 0);
-               if (type && type != Tbool) {
+               if (type && type != Tbool)
                        type_err(c, "error: %1 operation found where %2 expected", prog,
                                   Tbool, 0, type);
-                       *ok = 0;
-               }
                return Tbool;
 
 ###### interp binode cases
@@ -2732,11 +2731,9 @@ expression operator.
                        if (t)
                                t = propagate_types(b->left, c, ok, t, 0);
                }
-               if (!type_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;
-               }
                return Tbool;
 
 ###### interp binode cases
@@ -2879,22 +2876,18 @@ 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 (!type_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;
-               }
                return Tnum;
 
        case Concat:
                /* both must be Tstr, result is Tstr */
                propagate_types(b->left, c, ok, Tstr, 0);
                propagate_types(b->right, c, ok, Tstr, 0);
-               if (!type_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;
-               }
                return Tstr;
 
        case Bracket:
@@ -3124,11 +3117,9 @@ is in-place.
                        if (t && t != Tnone && t != Tbool) {
                                if (!type)
                                        type = t;
-                               else if (t != type) {
+                               else if (t != type)
                                        type_err(c, "error: expected %1%r, found %2",
                                                 e->left, type, rules, t);
-                                       *ok = 0;
-                               }
                        }
                }
                return type;
@@ -3344,10 +3335,8 @@ it is declared, and error will be raised as the name is created as
                                propagate_types(b->left, c, ok, t,
                                                (b->op == Assign ? Rnoconstant : 0));
                }
-               if (t && t->dup == NULL) {
+               if (t && t->dup == NULL)
                        type_err(c, "error: cannot assign value of type %1", b, t, 0, NULL);
-                       *ok = 0;
-               }
                return Tnone;
 
                break;