###### 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;
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
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;
}
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;
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;
}
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)
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) {
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;
/* 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
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
* 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:
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;
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;