From 20effd70ff4d91a7501dc062e60caaa9e362bed5 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 7 Jun 2019 08:31:07 +1000 Subject: [PATCH] oceani: setting ->parse_error now aborts type analysis. 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 --- csrc/oceani.mdc | 55 ++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index f4d8517..1f4805e 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -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; -- 2.43.0