- for (b = cast(binode, c->constlist); b;
- b = cast(binode, b->right)) {
- enum prop_err perr;
- struct binode *vb = cast(binode, b->left);
- struct var *v = cast(var, vb->left);
- do {
- perr = 0;
- propagate_types(vb->right, c, &perr,
- v->var->type, 0);
- } while (perr & Eretry);
- if (perr & Efail)
- c->parse_error += 1;
- else {
- struct value res = interp_exec(
- c, vb->right, &v->var->type);
- global_alloc(c, v->var->type, v->var, &res);
+ while (retry) {
+ retry = 0;
+ for (b = cast(binode, c->constlist); b;
+ b = cast(binode, b->right)) {
+ enum prop_err perr;
+ struct binode *vb = cast(binode, b->left);
+ struct var *v = cast(var, vb->left);
+ if (v->var->frame_pos >= 0)
+ continue;
+ do {
+ perr = 0;
+ propagate_types(vb->right, c, &perr,
+ v->var->type, 0);
+ } while (perr & Eretry);
+ if (perr & Efail)
+ c->parse_error += 1;
+ else if (!(perr & Enoconst)) {
+ progress = some;
+ struct value res = interp_exec(
+ c, vb->right, &v->var->type);
+ global_alloc(c, v->var->type, v->var, &res);
+ } else {
+ if (progress == cannot)
+ type_err(c, "error: const %v cannot be resolved.",
+ v, NULL, 0, NULL);
+ else
+ retry = 1;
+ }
+ }
+ switch (progress) {
+ case cannot:
+ retry = 0; break;
+ case none:
+ progress = cannot; break;
+ case some:
+ progress = none; break;