913 lines · 18.8 KB · C
RawDownload
#include "minicomp.h" #define clone_type clone_typ#define free_type freetyp#define new_icode new_IC#define add_icode add_IC#define free_all_icode() free_IC(first_ic)#define get_first_icode() first_ictypedef struct IC icode; static int errors;var *store_locals; struct rpair rp; char *copyright="minicomp/vbcc (c) in 2002 Volker Barthelmann";char *inname,*outname;struct struct_declaration *first_sd;struct Var *first_ext,*merk_varf;char **target_macros; FILE *out; void raus(void){  var *v;  for(v=first_var[0];v;v=v->next)    if(v->type->flags!=FUNCTION){      gen_align(out,falign(v->type));      gen_var_head(out,v->vbccvar);      gen_ds(out,szof(v->type),v->type);    }   cleanup_cg(out);   if(errors>0)    exit(EXIT_FAILURE);  else    exit(EXIT_SUCCESS);} main(int argc,char **argv){  int i,j,flag;  type *nt;   for(i=1;i<argc;i++){    if(*argv[i]!='-'){      if(inname)	error(18,"multiple input files");      inname=argv[i];    }else{      flag=0;      if((!strcmp("-o",argv[i]))&&i<argc-1){	flag=1;	outname=argv[++i];	continue;      }      if(!strncmp("-debug=",argv[i],7)){	flag=1;	sscanf(argv[i]+7,"%d",&j);	DEBUG=j;	continue;      }      if(!strncmp("-unroll-size=",argv[i],13)){	flag=1;	sscanf(argv[i]+13,"%d",&j);	unroll_size=j;	continue;      }      if(!strncmp("-inline-size=",argv[i],13)){	flag=1;	sscanf(argv[i]+13,"%d",&j);	inline_size=j;	continue;      }      if(!strncmp("-maxoptpasses=",argv[i],14)){	flag=1;	sscanf(argv[i]+14,"%d",&j);	maxoptpasses=j;	continue;      }      for(j=0;j<MAXGF&&flag==0;j++){        size_t l;        if(!g_flags_name[j]) continue;        l=strlen(g_flags_name[j]);        if(l>0&&!strncmp(argv[i]+1,g_flags_name[j],l)){          flag=1;          if((g_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(19,"multiple option");break;}	  g_flags[j]|=USEDFLAG;          if(g_flags[j]&STRINGFLAG){            if(argv[i][l+1]!='='){error(21,"string expected");}            if(argv[i][l+2]||i>=argc-1)              g_flags_val[j].p=&argv[i][l+2];            else              g_flags_val[j].p=&argv[++i][0];          }          if(g_flags[j]&VALFLAG){            if(argv[i][l+1]!='='){error(20,"value expected");}            if(argv[i][l+2]||i>=argc-1)              g_flags_val[j].l=atol(&argv[i][l+2]);            else              g_flags_val[j].l=atol(&argv[++i][0]);          }          if(g_flags[j]&FUNCFLAG) g_flags_val[j].f(&argv[i][l+1]);	}      }      if(!flag) error(23,"unknown option");    }  }   if(!inname)    error(22,"no input file");  infile=fopen(inname,"r");  if(!infile)    error(18,"could not open output file");  if(!outname)    error(23,"no output file");  out=fopen(outname,"w");  if(!out){    error(24,"could not open input file");  }  nt=new_type(FUNCTION);  nt->next=new_type(INT);  add_var("readInt",clone_type(nt));  add_var("writeInt",clone_type(nt));  add_var("writeChar",clone_type(nt));  add_var("readChar",clone_type(nt));  add_var("writeReal",nt);  nt=new_type(FUNCTION);  nt->next=new_type(REAL);  add_var("readReal",nt);   stackalign=l2zm(0L);  if(!init_cg()) exit(EXIT_FAILURE);  if(zmeqto(stackalign,l2zm(0L)))    stackalign=maxalign;   for(i=0;i<EMIT_BUF_DEPTH;i++)    emit_buffer[i]=mymalloc(EMIT_BUF_LEN);  emit_p=emit_buffer[0];   multiple_ccs=0;  optflags=-1;  maxoptpasses=100;   yyparse();   raus();} yyerror(char *s){  error(1,s);} void error(int n,...){  if(n==170||n==172) return;  errors++;  fprintf(stderr,"error %d\n",n);  raus();} void *getmem(size_t s){  void *p=malloc(s);  if(!p){    error(2,"out of memory");  }  return p;} #define LABELNESTING 1024static int labelstack[LABELNESTING],labelidx; void push_int(int l){  labelstack[labelidx++]=l;} int pop_int(){  return labelstack[--labelidx];} #define NAMENESTING 1024static char *namestack[NAMENESTING],nameidx; void push_ptr(void *ptr){  namestack[nameidx++]=ptr;} void *pop_ptr(){  return namestack[--nameidx];}  char *typename[]={"    ","int","real","array","function"};  type *new_type(int t){  type *new=new_typ();  new->flags=t;  new->next=0;  return new;} type *new_array(type *t,node *p){  type *new=new_typ();  simplify_tree(p);  if(p->flags!=NNUMBER)    error(3,"array size not a constant");  if(p->type->flags!=INT)    error(4,"array size not an integer");  new->flags=ARRAY;  new->next=t;  new->size=l2zm((long)p->ivalue);  free_tree(p);  return new;} int nesting;int local_offset,parm_offset,framesize; #define MAXNESTING 128var *first_var[128]; void free_varlist(var *v){  var *m;  while(v){    free_var(v->vbccvar);    m=v->next;    free(v);    v=m;  }} void enter_block(){  nesting++;  first_var[nesting]=0;  push_int(local_offset);} void leave_block(){  if(first_var[nesting]){    var *p=first_var[nesting];    while(p->next)      p=p->next;    p->next=store_locals;    p->vbccvar->next=merk_varf;    store_locals=first_var[nesting];    merk_varf=store_locals->vbccvar;  }  nesting--;  local_offset=pop_int();} void gen_func(var *v,icode *first,int framesize){  pric(stdout,get_first_icode());  vl1=first_var[0]?first_var[0]->vbccvar:0;  vl2=first_var[1]?first_var[1]->vbccvar:0;  vl3=merk_varf;  optimize(optflags,v->vbccvar);  memset(regs_modified,0,RSIZE);  pric(stdout,get_first_icode());  gen_code(out,get_first_icode(),v->vbccvar,max_offset);} void enter_func(char *name,type *p){  type *t=new_type(FUNCTION);  var *v;  t->next=p;  t->exact=getmem(sizeof(*t->exact));  t->exact->count=0;  v=add_var(name,t);  local_offset=parm_offset=framesize=0;  push_ptr(v);  enter_block();} void leave_func(){  icode *p,*merk;  leave_block();  gen_func(pop_ptr(),get_first_icode(),framesize);  free_all_icode();  first_ic=last_ic=0;  free_varlist(store_locals);  merk_varf=0;  store_locals=0;} var *find_var(char *p,int minnest){  var *v;  int i;   for(i=nesting;i>=minnest;i--){    for(v=first_var[i];v;v=v->next)      if(!strcmp(v->name,p))	return v;  }  return 0;} var *add_var(char *name,type *t){  var *new=getmem(sizeof(*new));  struct Var *vv;  /*FIXME: add vbccvar */    if(find_var(name,nesting))    error(5,"var %s already defined",name);  new->nesting=nesting;  new->name=add_string(name);  new->type=t;  if(*name==0){    new->next=store_locals;  }else{    new->next=first_var[nesting];  }  if(nesting==1){    /* parameter */    new->offset=parm_offset;    parm_offset+=szof(t);  }  if(nesting>1){    /* local variable */    new->offset=local_offset;    local_offset+=szof(t);    if(local_offset>framesize)      framesize=local_offset;  }      /* attach vbcc variable */  vv=new_var();  vv->vtyp=clone_typ(new->type);  vv->identifier=add_string(name);  vv->nesting=(*name!=0?nesting:2);  vv->storage_class=(vv->nesting==0?EXTERN:AUTO);  if(nesting==1)    vv->offset=zmsub(l2zm(0L),zmadd(maxalign,l2zm(new->offset)));  else    vv->offset=l2zm((long)local_offset);  new->vbccvar=vv;   if(*name==0){    store_locals=new;    vv->next=merk_varf;    merk_varf=vv;  }else{    vv->next=first_var[nesting]?first_var[nesting]->vbccvar:0;    first_var[nesting]=new;  }  return new;} var *new_temp(int tflags){  char tname[16];  static int itmps,rtmps,ptmps;  if(tflags==INT)    sprintf(tname,"\0 itmp%d",++itmps);  else if(tflags==REAL)    sprintf(tname,"\0 rtmp%d",++rtmps);  else if(tflags==POINTER)    sprintf(tname,"\0 rtmp%d",++ptmps);  else    error(16,"internal");  return add_var(tname,new_type(tflags));} struct Var *add_tmp_var(struct Typ *t){    return new_temp(t->flags)->vbccvar;} char *add_string(char *s){  char *new=getmem(strlen(s)+1);  strcpy(new,s);  return new;} char *nodename[]={  "var","number","add","mul","sub","div","index","equals",  "lt","gt","leq","geq","neq","and","or",  "int2real","real2int","assign","call","argument"}; node *number_node(void){  node *new=getmem(sizeof(*new));  new->flags=NNUMBER;  if(strstr(tkname,".")){    double rval;    sscanf(tkname,"%lf",&rval);    new->rvalue=rval;    new->type=new_type(REAL);    new->left=new->right=0;  }else{    new->ivalue=atoi(tkname);    new->type=new_type(INT);    new->left=new->right=0;  }  return new;} node *var_node(void){  var *v=find_var(tkname,0);  node *new;  if(!v){    error(6,"unknown identifier: %s",tkname);  }  new=getmem(sizeof(*new));  new->flags=NVARIABLE;  new->var=v;  new->type=clone_type(v->type);  new->left=new->right=0;  return new;}  node *binary_node(enum nodeflags flags,node *left,node *right){  node *new=getmem(sizeof(*new));  new->flags=flags;  new->left=left;  new->right=right;  new->type=0;  if(!left||(flags!=NCALL&&!right))    error(7,"internal error");  if(flags==NINDEX){    if(left->type->flags!=ARRAY)      error(8,"operand of [] must be array");    new->type=clone_type(left->type->next);  }else if(flags==NARG){    /* nothing to do? */  }else if(flags==NCALL){    if(left->type->flags!=FUNCTION)      error(9,"only functions can be called");    new->type=clone_type(left->type->next);  }else{    if(left->type->flags==ARRAY||right->type->flags==ARRAY)      error(10,"both operands must be real or int");    if(left->type->flags==REAL||right->type->flags==REAL){      new->type=new_type(REAL);      if(left->type->flags==INT){	new->left=conv_tree(left,REAL);      }      if(right->type->flags==INT){	new->right=conv_tree(right,REAL);      }          }else      new->type=new_type(INT);  }  return new;} void print_tree(node *p){  printf("%s(",nodename[p->flags]);  if(p->left)    print_tree(p->left);  if(p->right){    printf(",");    print_tree(p->right);  }  if(p->flags==NNUMBER){    if(p->type->flags==INT)      printf("%d[int]",p->ivalue);    else      printf("%g[real]",p->rvalue);  }  if(p->flags==NVARIABLE)    printf("%s[%s]",p->var->name,typename[p->var->type->flags]);  printf(")");} node *conv_tree(node *p,int tflags){  node *new;  if(p->type->flags==tflags)    return p;  new=getmem(sizeof(*new));  if(tflags==REAL)    new->flags=NI2R;  else    new->flags=NR2I;  new->type=new_type(p->type->flags);  new->left=p;

Lines 1–500 of 913.