struct variable *previous;
struct value val;
struct binding *name;
+ struct exec *where_decl;// where name was declared
struct exec *where_set; // where type was set
## variable fields
};
switch (v ? v->scope : OutScope) {
case InScope:
- /* Signal error ... once I build error signalling support */
+ /* Caller will report the error */
return NULL;
case CondScope:
for (;
struct variable *v = var_decl(config2context(config), $1.txt);
$0 = new_pos(var, $1);
$0->var = v;
+ if (v)
+ v->where_decl = $0;
+ else {
+ v = var_ref(config2context(config), $1.txt);
+ $0->var = v;
+ type_err(config2context(config), "error: variable '%v' redeclared",
+ $0, Vnone, Vnone);
+ type_err(config2context(config), "info: this is where '%v' was first declared",
+ v->where_decl, Vnone, Vnone);
+ }
} }$
| IDENTIFIER ::= ${ {
struct variable *v = var_decl(config2context(config), $1.txt);
- v->constant = 1;
$0 = new_pos(var, $1);
$0->var = v;
+ if (v) {
+ v->where_decl = $0;
+ v->constant = 1;
+ } else {
+ v = var_ref(config2context(config), $1.txt);
+ $0->var = v;
+ type_err(config2context(config), "error: variable '%v' redeclared",
+ $0, Vnone, Vnone);
+ type_err(config2context(config), "info: this is where '%v' was first declared",
+ v->where_decl, Vnone, Vnone);
+ }
} }$
Variable -> IDENTIFIER ${ {
return type;
}
if (!vtype_compat(type, v->val.vtype, bool_permitted)) {
- type_err(c, "error: expected %1 but variable %v is %2", prog,
+ type_err(c, "error: expected %1 but variable '%v' is %2", prog,
type, v->val.vtype);
- type_err(c, "info: this is where %v was set to %1", v->where_set,
+ type_err(c, "info: this is where '%v' was set to %1", v->where_set,
v->val.vtype, Vnone);
*ok = 0;
}
if (t > Vunknown) {
if (propagate_types(b->right, c, ok, t, 0) != t)
if (b->left->type == Xvar)
- type_err(c, "info: variable %v was set as %1 here.",
+ type_err(c, "info: variable '%v' was set as %1 here.",
cast(var, b->left)->var->where_set, t, Vnone);
} else {
t = propagate_types(b->right, c, ok, Vnolabel, 0);