home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / c-tools / vbcc / statements.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-24  |  27.6 KB  |  806 lines

  1. /*  $VER: vbcc (statements.c) V0.3  */
  2.  
  3. #include "vbc.h"
  4.  
  5. int cont_label=0;
  6. int test_assignment(struct Typ *,np);
  7.  
  8. void cr(void)
  9. /*  tested Registerbelegung */
  10. {
  11.     int i;
  12.     for(i=0;i<=MAXR;i++)
  13.         if(regs[i]!=regsa[i]) {error(149,regnames[i]);regs[i]=regsa[i];}
  14. }
  15. void statement(void)
  16. /*  bearbeitet ein statement                                    */
  17. {
  18.     char *merk;
  19.     cr();
  20.     killsp();
  21.     if(*s=='{'){
  22.         enter_block();
  23.         if(nesting>0) local_offset[nesting]=local_offset[nesting-1];
  24.         compound_statement();leave_block();return;}
  25.     merk=s;
  26.     cpbez(buff);
  27.     if(!strcmp("if",buff)){if_statement();return;}
  28.     if(!strcmp("switch",buff)){switch_statement();return;}
  29.     if(!strcmp("for",buff)){for_statement();return;}
  30.     if(!strcmp("while",buff)){while_statement();return;}
  31.     if(!strcmp("do",buff)){do_statement();return;}
  32.     if(!strcmp("goto",buff)){goto_statement();return;}
  33.     if(!strcmp("continue",buff)){continue_statement();return;}
  34.     if(!strcmp("break",buff)){break_statement();return;}
  35.     if(!strcmp("return",buff)){return_statement();return;}
  36.     if(!strcmp("case",buff)){labeled_statement();return;}
  37.     killsp();if(*s==':'){labeled_statement();return;}
  38.     /*  fehlt Aufruf der anderen statements */
  39.     s=merk;
  40.     expression_statement();
  41. }
  42. void labeled_statement(void)
  43. /*  bearbeitet labeled_statement                                */
  44. {
  45.     struct llist *lp;int def=0;
  46.     nocode=0;
  47.     if(*s==':'){
  48.         s++;
  49.         if(!*buff){error(130);return;}
  50.         if(!strcmp("default",buff)){def=1;lp=0;} else lp=find_label(buff);
  51.         if(lp&&lp->flags&LABELDEFINED){error(131,buff);return;}
  52.         if(!lp) lp=add_label(buff);
  53.         lp->flags|=LABELDEFINED;
  54.         lp->switch_count=0;
  55.         if(def){
  56.             if(switch_act==0) error(150);
  57.             lp->flags|=LABELDEFAULT;
  58.             lp->switch_count=switch_act;
  59.         }
  60.         gen_label(lp->label);
  61.         afterlabel=0;
  62.     }else{
  63.         /*  case    */
  64.         np tree;struct llist *lp;
  65.         tree=expression();
  66.         killsp();
  67.         if(*s==':'){s++;killsp();} else error(70);
  68.         if(!switch_count){
  69.             error(132);
  70.         }else{
  71.             if(!tree||!type_expression(tree)){
  72.             }else{
  73.                 if(tree->flags!=CEXPR||tree->sidefx){
  74.                     error(133);
  75.                 }else{
  76.                     if((tree->ntyp->flags&15)<CHAR||(tree->ntyp->flags&15)>LONG){
  77.                         error(134);
  78.                     }else{
  79.                         lp=add_label(empty);
  80.                         lp->flags=LABELDEFINED;
  81.                         lp->switch_count=switch_act;
  82.                         eval_constn(tree);
  83.                         if(switch_typ==CHAR) lp->val.vchar=vchar;
  84.                         if(switch_typ==(UNSIGNED|CHAR)) lp->val.vuchar=vuchar;
  85.                         if(switch_typ==SHORT) lp->val.vshort=vshort;
  86.                         if(switch_typ==(UNSIGNED|SHORT)) lp->val.vushort=vushort;
  87.                         if(switch_typ==INT) lp->val.vint=vint;
  88.                         if(switch_typ==(UNSIGNED|INT)) lp->val.vuint=vuint;
  89.                         if(switch_typ==LONG) lp->val.vlong=vlong;
  90.                         if(switch_typ==(UNSIGNED|LONG)) lp->val.vulong=vulong;
  91.                         if(switch_typ==POINTER) lp->val.vpointer=vpointer;
  92.                         gen_label(lp->label);
  93.                     }
  94.                 }
  95.             }
  96.         }
  97.         if(tree) free_expression(tree);
  98.     }
  99.     cr();
  100.     killsp();
  101.     if(*s!='}') statement();
  102. }
  103. void if_statement(void)
  104. /*  bearbeitet if_statement                                     */
  105. {
  106.     int ltrue,lfalse,lout,cexpr,cm;char *merk,buff[MAXI];
  107.     np tree;struct IC *new;
  108.     killsp(); if(*s=='(') s++; else error(151);
  109.     killsp();cm=nocode;
  110.     tree=expression();
  111.     if(!tree) {error(135);
  112.     }else{
  113.         ltrue=++label;lfalse=++label;
  114.         if(type_expression(tree)){
  115.             tree=makepointer(tree);
  116.             if(!arith(tree->ntyp->flags&15)&&(tree->ntyp->flags&15)!=POINTER)
  117.                 {error(136);
  118.             }else{
  119.                 if(tree->flags==ASSIGN) error(164);
  120.                 gen_IC(tree,ltrue,lfalse);
  121.                 if(tree->flags==CEXPR){
  122.                     eval_const(&tree->val,tree->ntyp->flags&31);
  123.                     if(zdeq(vdouble)) cexpr=2; else cexpr=1;
  124.                 }else cexpr=0;
  125.                 if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  126.                 if(tree->o.flags&&!cexpr){
  127.                     new=(struct IC *)mymalloc(ICS);
  128.                     new->code=TEST;
  129.                     new->q1=tree->o;
  130.                     new->q2.flags=new->z.flags=0;
  131.                     new->typf=tree->ntyp->flags;
  132.                     add_IC(new);
  133.                     new=(struct IC *)mymalloc(ICS);
  134.                     new->code=BEQ;
  135.                     new->typf=lfalse;
  136.                     add_IC(new);
  137.                 }
  138.             }
  139.         }
  140.         free_expression(tree);
  141.     }
  142.     killsp(); if(*s==')') s++; else error(59);
  143.     if(cexpr==2) nocode=1;
  144.     if(!cexpr&&!tree->o.flags) gen_label(ltrue);
  145.     statement();
  146.     killsp();
  147.     merk=s;
  148.     cpbez(buff);
  149.     if(strcmp("else",buff)) {s=merk;nocode=cm;if(!cexpr) gen_label(lfalse);return;}
  150.     lout=++label;
  151.     if(!cexpr){
  152.         new=(struct IC *)mymalloc(ICS);
  153.         new->code=BRA;
  154.         new->typf=lout;
  155.         add_IC(new);
  156.         gen_label(lfalse);
  157.     }
  158.     if(cexpr==1) nocode=1; else nocode=cm;
  159.     statement();
  160.     if(!cexpr) gen_label(lout);
  161.     nocode=cm;
  162.     cr();
  163. }
  164. void switch_statement(void)
  165. /*  bearbeitet switch_statement                                 */
  166. {
  167.     np tree;int merk_typ,merk_count,merk_break;
  168.     struct IC *merk_fic,*merk_lic,*new;struct llist *lp,*l1,*l2;
  169.     killsp();
  170.     if(*s=='('){s++;killsp();} else error(151);
  171.     tree=expression(); killsp();
  172.     if(*s==')'){s++;killsp();} else error(59);
  173.     merk_typ=switch_typ;merk_count=switch_act;merk_break=break_label;
  174.     if(!tree){
  175.         error(137);
  176.     }else{
  177.         if(!type_expression(tree)){
  178.         }else{
  179.             if((tree->ntyp->flags&15)<CHAR||(tree->ntyp->flags&15)>LONG){
  180.                 error(138);
  181.             }else{
  182.                 int m1,m2,m3,def=0,rm,minflag;
  183.                 zlong l,ml,s;zulong ul,mul,us;
  184.                 if(tree->flags==ASSIGN) error(164);
  185.                 m3=break_label=++label;m1=switch_act=++switch_count;
  186.                 m2=switch_typ=tree->ntyp->flags&31;
  187.                 gen_IC(tree,0,0);
  188.                 if((tree->o.flags&(DREFOBJ|SCRATCH))!=SCRATCH){
  189.                     new=(struct IC *)mymalloc(ICS);
  190.                     new->code=ASSIGN;
  191.                     new->q1=tree->o;
  192.                     new->q2.flags=0;
  193.                     new->q2.reg=sizetab[m2&15];
  194.                     get_scratch(&new->z,m2,0);
  195.                     new->typf=m2;
  196.                     tree->o=new->z;
  197.                     add_IC(new);
  198.                 }
  199.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){
  200.                     int r=tree->o.reg;
  201.                     rm=regs[r];
  202.                     regs[r]=regsa[r];
  203.                 }
  204.                 merk_fic=first_ic;merk_lic=last_ic;
  205.                 first_ic=last_ic=0;
  206.                 statement();
  207.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)) regs[tree->o.reg]=rm;
  208.                 minflag=0;s=l2zl(0L);us=ul2zul(0UL);
  209.                 for(l1=first_llist;l1;l1=l1->next){
  210.                     if(l1->switch_count!=m1) continue;
  211.                     if(l1->flags&LABELDEFAULT){
  212.                         if(def) error(139);
  213.                         def=l1->label;
  214.                         continue;
  215.                     }
  216.                     lp=0;minflag&=~1;
  217.                     for(l2=first_llist;l2;l2=l2->next){
  218.                         if(l2->switch_count!=m1) continue;
  219.                         if(l2->flags&LABELDEFAULT) continue;
  220.                         eval_const(&l2->val,m2);
  221.                         if(minflag&2){
  222.                             if(m2&UNSIGNED){
  223.                                 if(zulleq(vulong,mul)||zuleqto(vulong,mul)) continue;
  224.                             }else{
  225.                                 if(zlleq(vlong,ml)||zleqto(vlong,ml)) continue;
  226.                             }
  227.                         }
  228.                         if(minflag&1){
  229.                             if(m2&UNSIGNED){
  230.                                 if(!(minflag&4)&&zuleqto(vulong,ul)){ error(201);minflag|=4;}
  231.                                 if(zulleq(vulong,ul)){lp=l2;ul=vulong;}
  232.                             }else{
  233.                                 if(!(minflag&4)&&zleqto(vlong,l)){ error(201);minflag|=4;}
  234.                                 if(zlleq(vlong,l)){lp=l2;l=vlong;}
  235.                             }
  236.                         }else{
  237.                             minflag|=1;
  238.                             l=vlong;
  239.                             ul=vulong;
  240.                             lp=l2;
  241.                         }
  242.                     }
  243.                     if(!lp) continue;
  244.                     ml=l;mul=ul;minflag|=2;
  245.                     if(SWITCHSUBS){
  246.                         new=mymalloc(ICS);
  247.                         new->typf=m2;
  248.                         new->code=SUB;
  249.                         new->q1=tree->o;
  250.                         new->z=tree->o;
  251.                         new->q2.flags=KONST;
  252.                         eval_const(&lp->val,m2);
  253.                         vlong=zlsub(vlong,s);
  254.                         vulong=zulsub(vulong,us);
  255.                         vint=zl2zi(vlong);
  256.                         vshort=zl2zs(vlong);
  257.                         vchar=zl2zc(vlong);
  258.                         vuint=zul2zui(vulong);
  259.                         vushort=zul2zus(vulong);
  260.                         vuchar=zul2zuc(vulong);
  261.                         insert_const2(&new->q2.val,m2);
  262.                         new->q1.am=new->q2.am=new->z.am=0;
  263.                         s=l;us=ul;
  264.                         new->prev=merk_lic;
  265.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  266.                         merk_lic=new;
  267.                         new=mymalloc(ICS);
  268.                         new->typf=m2;
  269.                         new->code=TEST;
  270.                         new->q1=tree->o;
  271.                         new->q2.flags=new->z.flags=0;
  272.                         new->prev=merk_lic;
  273.                         new->q1.am=new->q2.am=new->z.am=0;
  274.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  275.                         merk_lic=new;
  276.                     }else{
  277.                         new=(struct IC *)mymalloc(ICS);
  278.                         new->code=COMPARE;
  279.                         new->typf=m2;
  280.                         new->q1=tree->o;
  281.                         new->q2.flags=KONST;
  282.                         new->q2.val=lp->val;
  283.                         new->z.flags=0;
  284.                         new->prev=merk_lic;
  285.                         new->q1.am=new->q2.am=new->z.am=0;
  286.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  287.                         merk_lic=new;
  288.                     }
  289.                     new=(struct IC *)mymalloc(ICS);
  290.                     new->code=BEQ;
  291.                     new->typf=lp->label;
  292.                     new->q1.flags=new->q2.flags=new->z.flags=0;
  293.                     new->prev=merk_lic;
  294.                     new->q1.am=new->q2.am=new->z.am=0;
  295.                     merk_lic->next=new;
  296.                     merk_lic=new;
  297.                 }
  298.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){   /* free_reg(tree->o.reg); */
  299.                     new=(struct IC *)mymalloc(ICS);
  300.                     new->code=FREEREG;new->typf=0;
  301.                     new->q2.flags=new->z.flags=0;
  302.                     new->q1.flags=REG;
  303.                     new->q1.reg=tree->o.reg;
  304.                     new->prev=merk_lic;
  305.                     new->q1.am=new->q2.am=new->z.am=0;
  306.                     if(merk_lic) merk_lic->next=new; else merk_fic=new;
  307.                     merk_lic=new;
  308.                     regs[tree->o.reg]=regsa[tree->o.reg];
  309.                 }
  310.                 new=(struct IC *)mymalloc(ICS);
  311.                 new->code=BRA;
  312.                 if(def) new->typf=def; else new->typf=m3;
  313.                 new->q1.flags=new->q2.flags=new->z.flags=0;
  314.                 if(merk_lic) merk_lic->next=new; else merk_fic=new;
  315.                 new->prev=merk_lic;
  316.                 first_ic->prev=new;
  317.                 new->next=first_ic;
  318.                 new->q1.am=new->q2.am=new->z.am=0;
  319.                 first_ic=merk_fic;
  320.                 gen_label(m3);
  321.             }
  322.         }
  323.     }
  324.     switch_typ=merk_typ;switch_act=merk_count;break_label=merk_break;
  325.     if(tree) free_expression(tree);
  326.     cr();
  327. }
  328. void while_statement(void)
  329. /*  bearbeitet while_statement                                  */
  330. {
  331.     np tree;int lloop,lin,lout,cm,cexpr,contm,breakm;
  332.     struct IC *new;
  333.     killsp();
  334.     if(*s=='(') {s++;killsp();} else error(151);
  335.     tree=expression();killsp();
  336.     if(*s==')') {s++;killsp();} else error(59);
  337.     cexpr=0;
  338.     if(tree){
  339.         if(type_expression(tree)){
  340.             tree=makepointer(tree);
  341.             if(!arith(tree->ntyp->flags&15)&&(tree->ntyp->flags&15)!=POINTER){
  342.                 error(140);
  343.                 cexpr=-1;
  344.             }else{
  345.                 if(tree->flags==ASSIGN) error(164);
  346.                 if(tree->flags==CEXPR){
  347.                     eval_const(&tree->val,tree->ntyp->flags&31);
  348.                     if(zdeq(vdouble)) cexpr=1; else cexpr=2;
  349.                     if(cexpr==1) error(152);
  350.                 }
  351.             }
  352.         }else cexpr=-1;
  353.     } else error(141);
  354.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  355.     contm=cont_label;breakm=break_label;
  356.     if(!cexpr||tree->sidefx) cont_label=lin; else cont_label=lloop;
  357.     if(!cexpr||tree->sidefx){
  358.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  359.             gen_IC(tree,lloop,lout);
  360.             if(tree->o.flags){
  361.                 new=(struct IC *)mymalloc(ICS);
  362.                 new->code=TEST;
  363.                 new->typf=tree->ntyp->flags&31;
  364.                 new->q1=tree->o;
  365.                 new->q2.flags=new->z.flags=0;
  366.                 add_IC(new);
  367.                 new=(struct IC *)mymalloc(ICS);
  368.                 new->code=BEQ;
  369.                 new->typf=lout;
  370.                 add_IC(new);
  371.             }
  372.         }else{
  373.             new=(struct IC *)mymalloc(ICS);
  374.             new->code=BRA;
  375.             new->typf=lin;
  376.             add_IC(new);
  377.         }
  378.     }
  379.     if(cexpr!=1) gen_label(lloop);
  380.     cm=nocode;break_label=lout;
  381.     if(cexpr==1) nocode=1;
  382.     currentpri*=looppri;
  383.     statement();
  384.     nocode=cm;cont_label=contm;break_label=breakm;
  385.     if(!cexpr||tree->sidefx) gen_label(lin);
  386.     if(tree&&cexpr>=0){
  387.         if(cexpr!=1||tree->sidefx){
  388.             gen_IC(tree,lloop,lout);
  389.             if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  390.         }
  391.         if(tree->o.flags&&!cexpr){
  392.             new=(struct IC *)mymalloc(ICS);
  393.             new->code=TEST;
  394.             new->typf=tree->ntyp->flags&31;
  395.             new->q1=tree->o;
  396.             new->q2.flags=new->z.flags=0;
  397.             add_IC(new);
  398.             new=(struct IC *)mymalloc(ICS);
  399.             new->code=BNE;
  400.             new->typf=lloop;
  401.             add_IC(new);
  402.         }
  403.         if(cexpr==2){
  404.             new=(struct IC *)mymalloc(ICS);
  405.             new->code=BRA;
  406.             new->typf=lloop;
  407.             add_IC(new);
  408.         }
  409.     }
  410.     if(tree) free_expression(tree);
  411.     gen_label(lout);
  412.     currentpri/=looppri;
  413.     cr();
  414. }
  415. void for_statement(void)
  416. /*  bearbeitet for_statement                                    */
  417. {
  418.     np tree1=0,tree2=0,tree3=0;int lloop,lin,lout,cm,cexpr,contm,breakm;
  419.     struct IC *new;
  420.     killsp();
  421.     if(*s=='(') {s++;killsp();} else error(59);
  422.     if(*s!=';'){tree1=expression();killsp();}
  423.     if(tree1){
  424.         if(tree1->flags==POSTINC) tree1->flags=PREINC;
  425.         if(tree1->flags==POSTDEC) tree1->flags=PREDEC;
  426.         if(type_expression(tree1)){
  427.             if(tree1->sidefx){
  428.                 gen_IC(tree1,0,0);
  429.                 if(tree1&&(tree1->o.flags&SCRATCH)) free_reg(tree1->o.reg);
  430.             }else{error(153);}
  431.         }
  432.         free_expression(tree1);
  433.     }
  434.     cexpr=0;
  435.     if(*s==';') {s++;killsp();} else error(54);
  436.     if(*s!=';') {tree2=expression();killsp();} else {cexpr=2;}
  437.     if(*s==';') {s++;killsp();} else error(54);
  438.     if(*s!=')') {tree3=expression();killsp();}
  439.     if(*s==')') {s++;killsp();} else error(59);
  440.     if(tree3){
  441.         if(!type_expression(tree3)){
  442.             free_expression(tree3);
  443.             tree3=0;
  444.         }
  445.     }
  446.     if(tree2){
  447.         if(type_expression(tree2)){
  448.             tree2=makepointer(tree2);
  449.             if(!arith(tree2->ntyp->flags&15)&&(tree2->ntyp->flags&15)!=POINTER){
  450.                 error(142);
  451.                 cexpr=-1;
  452.             }else{
  453.                 if(tree2->flags==ASSIGN) error(164);
  454.                 if(tree2->flags==CEXPR){
  455.                     eval_const(&tree2->val,tree2->ntyp->flags&31);
  456.                     if(zdeq(vdouble)) cexpr=1; else cexpr=2;
  457.                     if(cexpr==1) error(152);
  458.                 }
  459.             }
  460.         }else cexpr=-1;
  461.     }
  462.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  463.     contm=cont_label;breakm=break_label;
  464.     cont_label=++label;break_label=lout;
  465.     if(!cexpr||(tree2&&tree2->sidefx)){
  466.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  467.             gen_IC(tree2,lloop,lout);
  468.             if(tree2->o.flags){
  469.                 new=(struct IC *)mymalloc(ICS);
  470.                 new->code=TEST;
  471.                 new->typf=tree2->ntyp->flags&31;
  472.                 new->q1=tree2->o;
  473.                 new->q2.flags=new->z.flags=0;
  474.                 add_IC(new);
  475.                 new=(struct IC *)mymalloc(ICS);
  476.                 new->code=BEQ;
  477.                 new->typf=lout;
  478.                 add_IC(new);
  479.             }
  480.         }else{
  481.             new=(struct IC *)mymalloc(ICS);
  482.             new->code=BRA;
  483.             new->typf=lin;
  484.             add_IC(new);
  485.         }
  486.     }
  487.     if(cexpr!=1) gen_label(lloop);
  488.     cm=nocode;
  489.     if(cexpr==1) nocode=1;
  490.     currentpri*=looppri;
  491.     statement();
  492.     nocode=cm;
  493.     gen_label(cont_label);
  494.     cont_label=contm;break_label=breakm;
  495.     if(tree3){
  496.         if(tree3->flags==POSTINC) tree3->flags=PREINC;
  497.         if(tree3->flags==POSTDEC) tree3->flags=PREDEC;
  498.         if(tree3->sidefx){
  499.             gen_IC(tree3,0,0);
  500.             if(tree3&&(tree3->o.flags&SCRATCH)) free_reg(tree3->o.reg);
  501.         }else error(153);
  502.         free_expression(tree3);
  503.     }
  504.     if(!cexpr||(tree2&&tree2->sidefx)) gen_label(lin);
  505.     if(tree2&&cexpr>=0){
  506.         if(cexpr!=1||tree2->sidefx){
  507.             gen_IC(tree2,lloop,lout);
  508.             if((tree2->o.flags&SCRATCH)&&cexpr) free_reg(tree2->o.reg);
  509.         }
  510.         if(tree2->o.flags&&!cexpr){
  511.             new=(struct IC *)mymalloc(ICS);
  512.             new->code=TEST;
  513.             new->typf=tree2->ntyp->flags&31;
  514.             new->q1=tree2->o;
  515.             new->q2.flags=new->z.flags=0;
  516.             add_IC(new);
  517.             new=(struct IC *)mymalloc(ICS);
  518.             new->code=BNE;
  519.             new->typf=lloop;
  520.             add_IC(new);
  521.         }
  522.         if(cexpr==2){
  523.             new=(struct IC *)mymalloc(ICS);
  524.             new->code=BRA;
  525.             new->typf=lloop;
  526.             add_IC(new);
  527.         }
  528.     }
  529.     if(!tree2&&cexpr==2){
  530.         new=(struct IC *)mymalloc(ICS);
  531.         new->code=BRA;
  532.         new->typf=lloop;
  533.         add_IC(new);
  534.     }
  535.     if(tree2) free_expression(tree2);
  536.     gen_label(lout);
  537.     currentpri/=looppri;
  538.     cr();
  539. }
  540. void do_statement(void)
  541. /*  bearbeitet do_statement                                     */
  542. {
  543.     np tree;int lloop,lout,contm,breakm;
  544.     struct IC *new;
  545.     lloop=++label;lout=++label;currentpri*=looppri;
  546.     gen_label(lloop);
  547.     breakm=break_label;contm=cont_label;cont_label=++label;break_label=lout;
  548.     statement();
  549.     killsp();
  550.     gen_label(cont_label);cont_label=contm;break_label=breakm;
  551.     cpbez(buff);killsp();
  552.     if(strcmp("while",buff)) error(154);
  553.     if(*s=='(') {s++;killsp();} else error(151);
  554.     tree=expression();
  555.     if(tree){
  556.         if(type_expression(tree)){
  557.             tree=makepointer(tree);
  558.             if(arith(tree->ntyp->flags&15)||(tree->ntyp->flags&15)==POINTER){
  559.                 if(tree->flags==ASSIGN) error(164);
  560.                 if(tree->flags==CEXPR){
  561.                     eval_const(&tree->val,tree->ntyp->flags&31);
  562.                     if(tree->sidefx) gen_IC(tree,0,0);
  563.                     if(!zdeq(vdouble)){
  564.                         new=(struct IC *)mymalloc(ICS);
  565.                         new->code=BRA;
  566.                         new->typf=lloop;
  567.                         add_IC(new);
  568.                     }
  569.                 }else{
  570.                     gen_IC(tree,lloop,lout);
  571.                     if(tree->o.flags){
  572.                         new=(struct IC *)mymalloc(ICS);
  573.                         new->code=TEST;
  574.                         new->typf=tree->ntyp->flags&31;
  575.                         new->q1=tree->o;
  576.                         new->q2.flags=new->z.flags=0;
  577.                         add_IC(new);
  578.                         new=(struct IC *)mymalloc(ICS);
  579.                         new->code=BNE;
  580.                         new->typf=lloop;
  581.                         add_IC(new);
  582.                     }
  583.                 }
  584.             }else error(143);
  585.         }
  586.         free_expression(tree);
  587.     }
  588.     killsp();
  589.     if(*s==')') {s++;killsp();} else error(59);
  590.     if(*s==';') {s++;killsp();} else error(54);
  591.     gen_label(lout);
  592.     currentpri/=looppri;
  593.     cr();
  594. }
  595. void goto_statement(void)
  596. /*  bearbeitet goto_statement                                   */
  597. {
  598.     struct llist *lp;
  599.     struct IC *new;
  600.     killsp();cpbez(buff);
  601.     if(!*buff) error(144);
  602.     killsp();
  603.     if(*s==';'){s++;killsp();} else error(54);
  604.     lp=find_label(buff);
  605.     if(!lp) lp=add_label(buff);
  606.     lp->flags|=LABELUSED;
  607.     new=(struct IC *)mymalloc(ICS);
  608.     new->typf=lp->label;
  609.     new->code=BRA;
  610.     new->typf=lp->label;
  611.     add_IC(new);
  612.     cr();
  613.     goto_used=1;
  614. }
  615. void continue_statement(void)
  616. /*  bearbeitet continue_statement                               */
  617. {
  618.     struct IC *new;
  619.     killsp();
  620.     if(*s==';') {s++;killsp();} else error(54);
  621.     if(cont_label==0){error(145);return;}
  622.     new=(struct IC *)mymalloc(ICS);
  623.     new->code=BRA;
  624.     new->typf=cont_label;
  625.     add_IC(new);
  626.     cr();
  627. }
  628. void break_statement(void)
  629. /*  bearbeitet break_statement                                  */
  630. {
  631.     struct IC *new;
  632.     killsp();
  633.     if(*s==';') {s++;killsp();} else error(54);
  634.     if(break_label==0){error(146);return;}
  635.     new=(struct IC *)mymalloc(ICS);
  636.     new->code=BRA;
  637.     new->typf=break_label;
  638.     add_IC(new);
  639.     cr();
  640. }
  641. extern int has_return;
  642. void return_statement(void)
  643. /*  bearbeitet return_statement                                 */
  644. /*  SETRETURN hat Groesse in q2.reg und z.reg==freturn(rtyp)    */
  645. {
  646.     np tree;
  647.     struct IC *new;
  648.     has_return=1;
  649.     killsp();
  650.     if(*s!=';'){
  651.         if(tree=expression()){
  652.             killsp();
  653.             if(*s==';') {s++;killsp();} else error(54);
  654.             if(!return_typ){
  655.                 if(type_expression(tree)){
  656.                     tree=makepointer(tree);
  657.                     if((tree->ntyp->flags&15)!=VOID)
  658.                         error(155);
  659.                     gen_IC(tree,0,0);
  660.                     if(tree->o.flags&SCRATCH) free_reg(tree->o.reg);
  661.                 }
  662.             }else{
  663.                 if(type_expression(tree)){
  664.                     tree=makepointer(tree);
  665.                     if(!test_assignment(return_typ,tree)){free_expression(tree);return;}
  666.                     gen_IC(tree,0,0);
  667.                     convert(tree,return_typ->flags&31);
  668. #ifdef OLDPARMS   /*  alte CALL/RETURN-Methode    */
  669.                     new=(struct IC *)mymalloc(ICS);
  670.                     new->code=ASSIGN;
  671.                     new->typf=return_typ->flags&31;
  672.                     new->q1=tree->o;
  673.                     new->q2.flags=0;
  674.                     new->q2.reg=szof(return_typ);
  675.                     if(freturn(return_typ)){
  676.                         new->z.flags=SCRATCH|REG;
  677.                         new->z.reg=freturn(return_typ);
  678.                         if(!regs[new->z.reg]){
  679.                             struct IC *alloc=mymalloc(ICS);
  680.                             alloc->code=ALLOCREG;
  681.                             alloc->q1.flags=REG;
  682.                             alloc->q2.flags=alloc->z.flags=0;
  683.                             alloc->q1.reg=new->z.reg;
  684.                             regs[new->z.reg]=1;
  685.                             add_IC(alloc);
  686.                         }
  687.                     }else{
  688.                         new->z.reg=0;
  689.                         new->z.v=return_var;
  690.                         new->z.flags=SCRATCH|VAR;
  691.                         new->z.val.vlong=l2zl(0L);
  692.                     }
  693.                     add_IC(new);
  694.                     /*  das hier ist nicht sehr schoen, aber wie sonst? */
  695.                     if(new->z.flags&SCRATCH&®s[new->z.reg]) free_reg(new->z.reg);
  696. #else
  697.                     new=mymalloc(ICS);
  698.                     if(return_var){ /*  Returnwert ueber Zeiger */
  699.                         new->code=ASSIGN;
  700.                         new->z.flags=VAR|DREFOBJ;
  701.                         new->z.val.vlong=l2zl(0L);
  702.                         new->z.v=return_var;
  703.                     }else{
  704.                         new->code=SETRETURN;
  705.                         new->z.reg=freturn(return_typ);
  706.                         new->z.flags=0;
  707.                     }
  708.                     new->typf=return_typ->flags&31;
  709.                     new->q1=tree->o;
  710.                     new->q2.flags=0;
  711.                     new->q2.reg=szof(return_typ);
  712.                     add_IC(new);
  713. #endif
  714.                 }
  715.             }
  716.             free_expression(tree);
  717.         }else{
  718.             if(return_typ) error(156);
  719.         }
  720.     }else{ s++; if(return_typ) error(156);}
  721.  
  722.     new=(struct IC *)mymalloc(ICS);
  723.     new->code=BRA;
  724.     new->typf=return_label;
  725.     add_IC(new);
  726.     cr();
  727. }
  728.  
  729. void expression_statement(void)
  730. /*  bearbeitet expression_statement                             */
  731. {
  732.     np tree;
  733.     killsp();
  734.     if(*s==';') {s++;return;}
  735.     if(tree=expression()){
  736.         if(tree->flags==POSTINC) tree->flags=PREINC;
  737.         if(tree->flags==POSTDEC) tree->flags=PREDEC;
  738.         if(type_expression(tree)){
  739.             if(DEBUG&2){pre(stdout,tree);printf("\n");}
  740.             if(tree->sidefx){
  741.                 gen_IC(tree,0,0);
  742.                 if((tree->o.flags&(SCRATCH|REG))==REG) ierror(0);
  743.                 if(tree&&(tree->o.flags&SCRATCH)) free_reg(tree->o.reg);
  744.             }else{error(153);if(DEBUG&2) prd(stdout,tree->ntyp);}
  745.         }
  746.         free_expression(tree);
  747.     }
  748.     killsp();
  749.     if(*s==';') s++; else error(54);
  750.     cr();
  751. }
  752. void compound_statement(void)
  753. /*  bearbeitet compound_statement (block)                       */
  754. {
  755.     killsp();
  756.     if(*s=='{') s++; else error(157);
  757.     killsp();
  758.     while(declaration(0)){
  759.         var_declaration();
  760.         killsp();
  761.     }
  762.     while(*s!='}'){
  763.         statement();
  764.         killsp();
  765.     }
  766.     s++;killsp();
  767. }
  768. struct llist *add_label(char *identifier)
  769. /*  Fuegt label in Liste                                        */
  770. {
  771.     struct llist *new;
  772.     new=(struct llist *)mymalloc(LSIZE);
  773.     new->next=0;new->label=++label;new->flags=0;
  774.     new->identifier=add_identifier(identifier,strlen(identifier));
  775.     if(first_llist==0){
  776.         first_llist=last_llist=new;
  777.     }else{
  778.         last_llist->next=new;
  779.         last_llist=new;
  780.     }
  781.     return(last_llist); /* return(new) sollte aequiv. sein */
  782. }
  783. struct llist *find_label(char *identifier)
  784. /*  Sucht Label, gibt Zeiger auf llist oder 0 beu Fehler zurueck    */
  785. {
  786.     struct llist *p;
  787.     p=first_llist;
  788.     while(p){
  789.         if(!strcmp(p->identifier,identifier)) return(p);
  790.         p=p->next;
  791.     }
  792.     return(0);
  793. }
  794. void free_llist(struct llist *p)
  795. /*  Gibt llist frei                                             */
  796. {
  797.     struct llist *merk;
  798.     while(p){
  799.         merk=p->next;
  800.         if(!(p->flags&LABELDEFINED)) error(147,p->identifier);
  801.         if(!(p->flags&LABELUSED)&&!p->switch_count) error(148,p->identifier);
  802.         free(p);
  803.         p=merk;
  804.     }
  805. }
  806.