diff options
Diffstat (limited to 'src/cmd/gc/swt.c')
-rw-r--r-- | src/cmd/gc/swt.c | 104 |
1 files changed, 45 insertions, 59 deletions
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c index 318427636..486e181b1 100644 --- a/src/cmd/gc/swt.c +++ b/src/cmd/gc/swt.c @@ -348,8 +348,8 @@ newlabel() void casebody(Node *sw) { - Iter save; - Node *os, *oc, *n, *c; + Iter save, save1; + Node *os, *oc, *n, *n1, *c; Node *cas, *stat, *def; Node *go, *br; int32 lno; @@ -368,70 +368,56 @@ casebody(Node *sw) oc = N; // last case br = nod(OBREAK, N, N); -loop: - if(n == N) { - if(oc == N && os != N) - yyerror("first switch statement must be a case"); - - stat = list(stat, br); - cas = list(cas, def); - - sw->nbody = nod(OLIST, rev(cas), rev(stat)); -//dump("case", sw->nbody->left); -//dump("stat", sw->nbody->right); - lineno = lno; - return; - } - - lno = setlineno(n); - - if(n->op != OXCASE) { - stat = list(stat, n); - os = n; - goto next; - } - - n->op = OCASE; - if(oc == N && os != N) - yyerror("first switch statement must be a case"); + for(; n != N; n = listnext(&save)) { + lno = setlineno(n); + if(n->op != OXCASE) + fatal("casebody %O", n->op); + n->op = OCASE; + + go = nod(OGOTO, newlabel(), N); + c = n->left; + if(c == N) { + if(def != N) + yyerror("more than one default case"); + // reuse original default case + n->right = go; + def = n; + } - // botch - shouldnt fall thru declaration - if(os != N && os->op == OXFALL) - os->op = OFALL; - else - stat = list(stat, br); + // expand multi-valued cases + for(; c!=N; c=c->right) { + if(c->op != OLIST) { + // reuse original case + n->left = c; + n->right = go; + cas = list(cas, n); + break; + } + cas = list(cas, nod(OCASE, c->left, go)); + } - go = nod(OGOTO, newlabel(), N); + stat = list(stat, nod(OLABEL, go->left, N)); - c = n->left; - if(c == N) { - if(def != N) - yyerror("more than one default case"); + os = N; + for(n1 = listfirst(&save1, &n->nbody); n1 != N; n1 = listnext(&save1)) { + os = n1; + stat = list(stat, n1); + } - // reuse original default case - n->right = go; - def = n; + // botch - shouldnt fall thru declaration + if(os != N && os->op == OXFALL) + os->op = OFALL; + else + stat = list(stat, br); } - // expand multi-valued cases - for(; c!=N; c=c->right) { - if(c->op != OLIST) { - // reuse original case - n->left = c; - n->right = go; - cas = list(cas, n); - break; - } - cas = list(cas, nod(OCASE, c->left, go)); - } - stat = list(stat, nod(OLABEL, go->left, N)); - oc = n; - os = N; - goto next; + stat = list(stat, br); + cas = list(cas, def); -next: - n = listnext(&save); - goto loop; + sw->nbody = nod(OLIST, rev(cas), rev(stat)); +//dump("case", sw->nbody->left); +//dump("stat", sw->nbody->right); + lineno = lno; } Case* |