home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / vbcc / statements.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-19  |  29.7 KB  |  880 lines

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