continpc = pc;
gen(n->nincr, L); // contin: incr
patch(p1, pc); // test:
+ if(n->ntest != N)
+ if(n->ntest->ninit != N)
+ gen(n->ntest->ninit, L);
bgen(n->ntest, 0, breakpc); // if(!test) goto break
if(labloop != L) {
labloop->op = OFOR;
p1 = gbranch(AJMP, T); // goto test
p2 = gbranch(AJMP, T); // p2: goto else
patch(p1, pc); // test:
+ if(n->ntest != N)
+ if(n->ntest->ninit != N)
+ gen(n->ntest->ninit, L);
bgen(n->ntest, 0, p2); // if(!test) goto p2
gen(n->nbody, L); // then
p3 = gbranch(AJMP, T); // goto done
patch(p1, pc);
+ if(n->ntest != N)
+ if(n->ntest->ninit != N)
+ gen(n->ntest->ninit, L);
tempname(&tmp, n->ntest->type);
cgen(n->ntest, &tmp);
}
| new_name '=' expr
{
- walktype($3, Erv); // this is a little harry
+ gettype($3);
defaultlit($3);
dodclvar($1, $3->type);
$$ = nod(OAS, $1, $3);
new_name type '=' expr
{
Node *c = treecopy($4);
- walktype(c, Erv);
+ gettype(c);
convlit(c, $2);
dodclconst($1, c);
| new_name '=' expr
{
Node *c = treecopy($3);
- walktype(c, Erv);
+ gettype(c);
dodclconst($1, c);
lastconst = $3;
| new_name type
{
Node *c = treecopy(lastconst);
- walktype(c, Erv);
+ gettype(c);
convlit(c, $2);
dodclconst($1, c);
| new_name
{
Node *c = treecopy(lastconst);
- walktype(c, Erv);
+ gettype(c);
dodclconst($1, c);
iota += 1;
| expr_list LCOLAS expr_list
{
$$ = nod(OAS, colas($1, $3), $3);
+ addtotop($$);
}
| LPRINT '(' oexpr_list ')'
{
popdcl();
$$ = $2;
$$->op = OSWITCH;
- //if($$->ninit != N && $$->ntest == N)
- // yyerror("switch expression should not be missing");
}
| LIF if_stmt
{
popdcl();
$$ = $2;
- //if($$->ninit != N && $$->ntest == N)
- // yyerror("if conditional should not be missing");
}
| LIF if_stmt LELSE else_stmt1
{
popdcl();
$$ = $2;
$$->nelse = $4;
- //if($$->ninit != N && $$->ntest == N)
- // yyerror("if conditional should not be missing");
}
| LSELECT select_stmt
{
popdcl();
$$ = $2;
$$->nelse = $4;
- //if($$->ninit != N && $$->ntest == N)
- // yyerror("if conditional should not be missing");
}
compound_stmt:
void
walk(Node *fn)
{
- if(debug['W'])
- dump("fn-before", fn->nbody);
+ char s[50];
+
curfn = fn;
+ if(debug['W']) {
+ snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
+ dump(s, fn->nbody);
+ }
walkstate(fn->nbody);
+ if(debug['W']) {
+ snprint(s, sizeof(s), "after %S", curfn->nname->sym);
+ dump(s, fn->nbody);
+ }
+}
+
+void
+addtotop(Node *n)
+{
+ Node *l;
+
+ while(addtop != N) {
+ l = addtop;
+ addtop = N;
+ walktype(l, Etop);
+ n->ninit = list(n->ninit, l);
+ }
+}
+
+void
+gettype(Node *n)
+{
if(debug['W'])
- dump("fn", fn->nbody);
+ dump("\nbefore gettype", n);
+ walktype(n, Erv);
+ addtotop(n);
+ if(debug['W'])
+ dump("after gettype", n);
}
void
walkstate(Node *n)
{
- Node *l, *more;
+ Node *more;
loop:
if(n == N)
break;
}
- while(addtop != N) {
- l = addtop;
- addtop = N;
- walktype(l, Etop);
- n->ninit = list(n->ninit, l);
- }
+ addtotop(n);
if(more != N) {
n = more;
goto nottop;
walkstate(n->ninit);
walkbool(n->ntest);
- walkstate(n->nelse);
walkstate(n->nbody);
+ walkstate(n->nelse);
goto ret;
case OPROC:
if(top != Etop)
goto nottop;
+ addtop = list(addtop, n->ninit);
+ n->ninit = N;
+
l = n->left;
r = n->right;
walktype(l, Elv);
walkbool(Node *n)
{
walktype(n, Erv);
+ addtotop(n);
if(n != N && n->type != T)
if(!eqtype(n->type, types[TBOOL], 0))
yyerror("IF and FOR require a boolean type");
w = whatis(l);
switch(w) {
default:
+ if(l->type == T)
+ goto out;
if(!isptr[l->type->etype]) {
badtype(n->op, l->type, T);
l = listnext(&save);
else
r = list(r, nod(OCALL, on, l));
+out:
l = listnext(&save);
goto loop;
}