1267 lines · 28.6 KB · C
RawDownload
/*  $VER: vbcc (statements.c) V0.8  */ #include "vbcc_cpp.h"#include "vbc.h" static char FILE_[]=__FILE__; int cont_label=0;int test_assignment(struct Typ *,np); static int switchbreak; #ifdef HAVE_MISRA/* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed */#endif #define cr()#ifndef crvoid cr(void)/*  tested Registerbelegung */{  int i;  for(i=0;i<=MAXR;i++)    if(regs[i]!=regsa[i]) {error(149,regnames[i]);regs[i]=regsa[i];}}#endif  #ifdef HAVE_MISRA/* removed *//* removed */#endif void statement(void)/*  bearbeitet ein statement                                    */{  struct token mtok;#ifdef HAVE_MISRA/* removed */#endif  cr();  killsp();  if(ctok->type==LBRA){    enter_block();    if(nesting>0) local_offset[nesting]=local_offset[nesting-1];    compound_statement();    leave_block();    return;  }  if(ctok->type==NAME){#ifdef HAVE_MISRA/* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed */#endif#ifndef HAVE_MISRA    if(!strcmp("if",ctok->name)){next_token();if_statement(); return;}    if(!strcmp("switch",ctok->name)){next_token();switch_statement(); return;}    if(!strcmp("for",ctok->name)){next_token();for_statement(); return;}    if(!strcmp("while",ctok->name)){next_token();while_statement(); return;}    if(!strcmp("do",ctok->name)){next_token();do_statement(); return;}    if(!strcmp("goto",ctok->name)){next_token();goto_statement(); return;}    if(!strcmp("continue",ctok->name)){next_token();continue_statement(); return;}    if(!strcmp("break",ctok->name)){next_token();break_statement(); return;}    if(!strcmp("return",ctok->name)){next_token();return_statement(); return;}    if(!strcmp("case",ctok->name)){next_token(); labeled_statement(); return;}    if(!strcmp("default",ctok->name)){cpbez(buff,0);next_token();labeled_statement(); return;}#endif	}  cpbez(buff,1);  copy_token(&mtok,ctok);  next_token();killsp();  if(ctok->type==T_COLON){labeled_statement();return;}  push_token(&mtok);  free(mtok.name);  expression_statement(); /* if there is an expression statement set misra_last_break to false */}void labeled_statement(void)/*  bearbeitet labeled_statement                                */{  struct llist *lp;int def=0;  nocode=0;  if(ctok->type==T_COLON){    next_token();    if(!*buff){      error(130);      return;    }    if(!strcmp("default",buff)){      def=1;      lp=0;    } else lp=find_label(buff);    if(lp&&lp->flags&LABELDEFINED){      error(131,buff);      return;    }    if(!lp) lp=add_label(buff);    lp->flags|=LABELDEFINED;    lp->switch_count=0;    if(def){#ifdef HAVE_MISRA/* removed *//* removed *//* removed */#endif      if(switch_act==0) error(150);      lp->flags|=LABELDEFAULT;      lp->switch_count=switch_act;    }else {#ifdef HAVE_MISRA/* removed */#endif		}    gen_label(lp->label);    afterlabel=0;  }else{    /*  case    */    np tree;struct llist *lp;#ifdef HAVE_MISRA/* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed */#endif    tree=expression();    killsp();    if(ctok->type==T_COLON){      next_token();      killsp();    } else error(70);    if(!switch_count){      error(132);    } else {      if(!tree||!type_expression(tree))	{	} else {	if(tree->flags!=CEXPR||tree->sidefx){	  error(133);	} else {	  if(!ISINT(tree->ntyp->flags)){	    error(134);	  } else {	    lp=add_label(empty);	    lp->flags=LABELDEFINED;	    lp->switch_count=switch_act;	    eval_constn(tree);	    insert_const(&lp->val,switch_typ);	    gen_label(lp->label);	  }	}      }    }    if(tree) free_expression(tree);  }  cr();  killsp();  if(ctok->type!=RBRA) statement();}void if_statement(void)/*  bearbeitet if_statement                                     */{  int ltrue,lfalse,lout,cexpr=0,cm,tm,merk_elseneed;  np tree;struct IC *new;  static int elseneed;  merk_elseneed=elseneed;  elseneed=0;  killsp();  if(ctok->type==LPAR) next_token(); else error(151);  killsp();cm=nocode;  tree=expression();  if(!tree){    error(135);  }else{#ifdef HAVE_MISRA/* removed */#endif    ltrue=++label;lfalse=++label;    if(type_expression(tree)){      tree=makepointer(tree);      if(!ISARITH(tree->ntyp->flags)&&!ISPOINTER(tree->ntyp->flags)){	error(136);      }else{	if(tree->flags==ASSIGN&&tree->right->flags!=CALL) error(164);	gen_IC(tree,ltrue,lfalse);	if(tree->flags==CEXPR){	  eval_const(&tree->val,tree->ntyp->flags&NU);	  if(zldeqto(vldouble,d2zld(0.0))&&zmeqto(vmax,l2zm(0L))&&zumeqto(vumax,ul2zum(0UL))) cexpr=2; else cexpr=1;	}else	  cexpr=0;	if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)&&cexpr) free_reg(tree->o.reg);	if(tree->o.flags&&!cexpr){	  gen_test(&tree->o,tree->ntyp->flags,BEQ,lfalse);#if 0	  new=new_IC();	  new->code=TEST;	  new->q1=tree->o;	  new->q2.flags=new->z.flags=0;	  new->typf=tree->ntyp->flags;	  add_IC(new);	  new=new_IC();	  new->code=BEQ;	  new->typf=lfalse;	  add_IC(new);#endif	}	if(cexpr==2){	  new=new_IC();	  new->code=BRA;	  new->typf=lfalse;	  add_IC(new);	}      }    }    tm=tree->o.flags;    free_expression(tree);  }  killsp(); if(ctok->type==RPAR) next_token(); else error(59);  if(cexpr==2) nocode=1;  if(!cexpr&&!tm) gen_label(ltrue);#ifdef HAVE_MISRA/* removed */#endif  statement();  killsp();  if(ctok->type!=NAME||strcmp("else",ctok->name)){#ifdef HAVE_MISRA/* removed */#endif    nocode=cm;    if(cexpr!=1) gen_label(lfalse);    elseneed=merk_elseneed;    return;  }  next_token();  lout=++label;  if(cexpr!=2){    new=new_IC();    new->code=BRA;    new->typf=lout;    add_IC(new);  }  if(cexpr!=1) {nocode=cm;gen_label(lfalse);}  if(cexpr==1) nocode=1; else nocode=cm;  if(ctok->type!=LBRA){	  if(ctok->type!=NAME||strcmp("if",ctok->name)) {#ifdef HAVE_MISRA/* removed */#endif	  }    else      elseneed=1;  }  statement();  elseneed=merk_elseneed;  nocode=cm;  if(cexpr!=2) gen_label(lout);  cr();}  void switch_statement(void)/*  bearbeitet switch_statement                                 */{  np tree;int merk_typ,merk_count,merk_break,num_cases;	struct IC *merk_fic,*merk_lic,*new;struct llist *lp,*l1,*l2;#ifdef HAVE_MISRA/* removed *//* removed *//* removed *//* removed *//* removed *//* removed *//* removed */#endif  nocode=0;  killsp();  if(ctok->type==LPAR){		next_token();killsp();	} else error(151);  tree=expression(); killsp();  if(ctok->type==RPAR){		next_token();killsp();	} else error(59);  merk_typ=switch_typ;merk_count=switch_act;merk_break=break_label;  if(!tree){    error(137);  } else {    if(!type_expression(tree)){    }else{      if(!ISINT(tree->ntyp->flags)){	error(138);      } else {	int m1,m2,m3,def=0,rm,minflag;	zmax l,ml,s;zumax ul,mul,us;	if(tree->flags==ASSIGN&&tree->right->flags!=CALL) error(164);#ifdef HAVE_MISRA/* removed *//* removed */#endif 	m3=break_label=++label;m1=switch_act=++switch_count;	m2=switch_typ=tree->ntyp->flags&NU;	gen_IC(tree,0,0);	if((SWITCHSUBS&&!shortcut(SUB,m2))||(!SWITCHSUBS&&!shortcut(COMPARE,m2))){	  switch_typ=m2=int_erw(m2);	  convert(tree,m2);	}	if((tree->o.flags&(DREFOBJ|SCRATCH))!=SCRATCH){	  new=new_IC();	  new->code=ASSIGN;	  new->q1=tree->o;	  new->q2.flags=0;	  new->q2.val.vmax=sizetab[m2&NQ];	  get_scratch(&new->z,m2,0,0);	  new->typf=m2;	  tree->o=new->z;	  add_IC(new);	}	if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){	  int r=tree->o.reg;	  rm=regs[r];	  regs[r]=regsa[r];	}	merk_fic=first_ic;merk_lic=last_ic;		first_ic=last_ic=0;	{	  int merk_sb=switchbreak;	  switchbreak=1;	  statement();	  switchbreak=merk_sb;	}		if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)) regs[tree->o.reg]=rm;	minflag=0;s=l2zm(0L);us=ul2zum(0UL);	num_cases=0;#ifdef HAVE_MISRA/* removed *//* removed *//* removed *//* removed *//* removed *//* removed */#endif	for(l1=first_llist;l1;l1=l1->next)	  if(l1->switch_count==m1) num_cases++;	for(l1=first_llist;l1;l1=l1->next){	  if(l1->switch_count!=m1) continue;	  if(l1->flags&LABELDEFAULT){	    if(def) error(139);	    def=l1->label;	    continue;	  }	  lp=0;minflag&=~1;	  for(l2=first_llist;l2;l2=l2->next){	    if(l2->switch_count!=m1) continue;	    if(l2->flags&LABELDEFAULT) continue;	    eval_const(&l2->val,m2);	    if(minflag&2){	      if(m2&UNSIGNED){		if(zumleq(vumax,mul)||zumeqto(vumax,mul)) continue;	      }else{		if(zmleq(vmax,ml)||zmeqto(vmax,ml)) continue;	      }	    }	    if(minflag&1){	      if(m2&UNSIGNED){		if(!(minflag&4)&&zumeqto(vumax,ul)){ 		  error(201);		  minflag|=4;		}		if(zumleq(vumax,ul)){		  lp=l2;		  ul=vumax;		}	      }else{		if(!(minflag&4)&&zmeqto(vmax,l)){ error(201);minflag|=4;}		if(zmleq(vmax,l)){lp=l2;l=vmax;}	      }	    }else{	      minflag|=1;	      l=vmax;	      ul=vumax;	      lp=l2;	    }	  }	  if(!lp) continue;	  ml=l;mul=ul;minflag|=2;	  if(SWITCHSUBS&&num_cases<JUMP_TABLE_LENGTH){	    new=new_IC();	    new->line=0;	    new->file=0;	    new->typf=m2;	    new->code=SUB;	    new->q1=tree->o;	    new->z=tree->o;	    new->q2.flags=KONST;	    eval_const(&lp->val,m2);	    if(m2&UNSIGNED){	      gval.vumax=zumsub(vumax,us);	      eval_const(&gval,UNSIGNED|MAXINT);	    }else{	      gval.vmax=zmsub(vmax,s);	      eval_const(&gval,MAXINT);	    }	    insert_const(&new->q2.val,m2);	    new->q1.am=new->q2.am=new->z.am=0;	    s=l;us=ul;	    new->prev=merk_lic;	    if(merk_lic) merk_lic->next=new; else merk_fic=new;	    merk_lic=new;	    new=new_IC();	    new->line=0;	    new->file=0;	    new->typf=m2;	    new->code=TEST;	    new->q1=tree->o;	    new->q2.flags=new->z.flags=0;	    new->prev=merk_lic;	    new->q1.am=new->q2.am=new->z.am=0;	    if(merk_lic) merk_lic->next=new; else merk_fic=new;	    merk_lic=new;	  }else{	    new=new_IC();	    new->line=0;	    new->file=0;	    new->code=COMPARE;	    new->typf=m2;	    new->q1=tree->o;	    new->q2.flags=KONST;	    new->q2.val=lp->val;	    new->z.flags=0;	    new->prev=merk_lic;	    new->q1.am=new->q2.am=new->z.am=0;	    if(merk_lic) merk_lic->next=new; else merk_fic=new;	    merk_lic=new;	  }	  new=new_IC();	  new->line=0;	  new->file=0;	  new->code=BEQ;	  new->typf=lp->label;	  new->q1.flags=new->q2.flags=new->z.flags=0;	  new->prev=merk_lic;	  new->q1.am=new->q2.am=new->z.am=0;	  merk_lic->next=new;	  merk_lic=new;	}	if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){   /* free_reg(tree->o.reg); */	  new=new_IC();	  new->line=0;	  new->file=0;	  new->code=FREEREG;new->typf=0;	  new->q2.flags=new->z.flags=0;	  new->q1.flags=REG;	  new->q1.reg=tree->o.reg;

Lines 1–500 of 1267.