Mercurial > hg > CbC > old > device
changeset 293:5bf2c3070d36
sort case value
author | kono |
---|---|
date | Sat, 05 Jun 2004 13:01:08 +0900 |
parents | 6d4231b6f9fe |
children | ab715ae6b468 |
files | mc-codegen.c mc-parse.c mc.h test/code-gen.c |
diffstat | 4 files changed, 91 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-codegen.c Sat Jun 05 00:08:09 2004 +0900 +++ b/mc-codegen.c Sat Jun 05 13:01:08 2004 +0900 @@ -1772,12 +1772,17 @@ #if CASE_CODE +/* + cslist = list3(value,next,label) label==0 means skip + */ + void cascade_compare(int cslist,int cslabel,int dlabel) { fwddef(cslabel); for(;cslist; cslist=cadr(cslist)) { - cmpdimm(car(cslist),csvalue1,caddr(cslist),0); + if (caddr(cslist)) + cmpdimm(car(cslist),csvalue1,caddr(cslist),0); } if (dlabel) jmp(dlabel); }
--- a/mc-parse.c Sat Jun 05 00:08:09 2004 +0900 +++ b/mc-parse.c Sat Jun 05 13:01:08 2004 +0900 @@ -1859,6 +1859,7 @@ checkret(); slist = cslist; + cslist = 0; sbreak=blabel; /* save parents break label */ blabel=fwdlabel(); sdefault=dlabel; /* save parents default label */ @@ -1870,6 +1871,7 @@ slfree=lfree; svalue=csvalue1; /* save parents switch value */ gexpr(expr(0),1); + if (!scalar(type)) error(EXERR); csvalue1=csvalue() ; lfree=slfree; checksym(RPAR); @@ -1907,15 +1909,22 @@ } static void +docase_eq() +{ + error(-1); // duplicate case value +} + +static void docase(void) { #if CASE_CODE - int l; + int l,clist=0,c; l = fwdlabel(); while(sym==CASE) { conv->case_begin_(0,0); getsym(0); - cslist=list3(cexpr(expr(1)),cslist,l); + // temorary put into a list + clist=list3(cexpr(expr(1)),clist,l); conv->case_(0,0); checksym(COLON); } @@ -1923,9 +1932,26 @@ if (!cslabel) { if (!control) { // immiediate after switch(i) (ususal case) - cmpdimm(car(cslist),csvalue1,cslabel=fwdlabel(),1); - cslist = cadr(cslist); - } else error(-1); // checkret() sequence inconsistent + // use it for jump to table lookup + + cmpdimm(car(clist),csvalue1,cslabel=fwdlabel(),1); + + // Insert anyway to check duplicate case value. + // Mark it already used. + + caddr(clist)=0; + + } else { + // checkret() sequence inconsistent + // This can't happen, because checkret() force teble lookup jump + // before any executable instruction in switch such as siwth-for. + error(-1); + } + } + // Make ascend order list of case value + while(clist) { + clist = cadr(c=clist); cadr(c) = 0; // insert destroy cadr of clist + cslist=insert_ascend(cslist,c,docase_eq); } fwddef(l); control=1; @@ -4996,23 +5022,30 @@ } } -/* we can use cadr(e) = n; now. int -rplacad(int e, int n) +insert_ascend(int p,int e,void eq()) { - heap[e+1]=n; - return e; + int p1,p2; + if(!p) return e; + if (car(p)>car(e)) { + cadr(e) = p; + return e; + } + p1=p; + while(cadr(p)) { + p = cadr(p2=p); + if (car(p)==car(e)) eq(); + if (car(p)>=car(e)) { + cadr(e) = cadr(p2); + cadr(p2) = e; + return p1; + } + } + cadr(p) = e; + return p1; } int -rplacadd(int e, int n) -{ - heap[e+2]=n; - return e; -} - */ - -int append4(int p,int a1,int a2,int a3) { int p1;
--- a/mc.h Sat Jun 05 00:08:09 2004 +0900 +++ b/mc.h Sat Jun 05 13:01:08 2004 +0900 @@ -477,7 +477,7 @@ extern int assign_expr0(int e1,int e2,int t,int type) ; extern int assign_expr(int e1,int e2,int t,int type) ; extern int append4(int p,int a1,int a2,int a3); - +extern int insert_ascend(int p,int e,void eq()); #define car(e) (heap[(int)(e)])
--- a/test/code-gen.c Sat Jun 05 00:08:09 2004 +0900 +++ b/test/code-gen.c Sat Jun 05 13:01:08 2004 +0900 @@ -2635,6 +2635,40 @@ default: printf("code_switch d %d\n",i); } } + for(i=0;i<10;i++) { + switch(i) { + case 1: printf("code_switch 1 %d\n",i); break; + case 2: + i = i* 100; + switch(i) { + case 100: printf("code_switch n 1 %d\n",i); break; + case 200: + for(i=-100;i<10;i++) { + switch(i) { + case 1234: printf("code_switch 1 nn %d\n",i); break; + case 2233: printf("code_switch 2 nn %d\n",i); break; + case 3333: printf("code_switch 3 nn %d\n",i); + case -4: printf("code_switch 4 nn %d\n",i); break; + case 733: + case -5: printf("code_switch 5 nn %d\n",i); break; + case -326: printf("code_switch 6 nn %d\n",i); + } + } + case 300: printf("code_switch n 3 %d\n",i); + case 400: printf("code_switch n 4 %d\n",i); break; + case 700: + case 500: printf("code_switch n 5 %d\n",i); break; + case 600: printf("code_switch n 6 %d\n",i); break; + default: printf("code_switch n d %d\n",i); + } + case 3: printf("code_switch 3 %d\n",i); + case 4: printf("code_switch 4 %d\n",i); break; + case 7: + case 5: printf("code_switch 5 %d\n",i); break; + case 6: printf("code_switch 6 %d\n",i); break; + default: printf("code_switch d %d\n",i); + } + } }