#include "bem.h" /* Here you find all routines to evaluate expressions and generate code for assignment statements */ exprtype(ltype,rtype) int ltype,rtype; { /* determine the result type of an expression */ if( ltype== STRINGTYPE || rtype==STRINGTYPE) { if( ltype!=rtype) error("type conflict, string expected"); return( STRINGTYPE); } /* take maximum */ if( ltype': genbool("zgt"); break; case '=': genbool("zeq"); break; case NESYM: genbool("zne"); break; case LESYM: genbool("zle"); break; case GESYM: genbool("zge"); break; default: error("relop:unexpected operator"); } return(INTTYPE); } plusmin(ltype,rtype,operator) int ltype,rtype,operator; { int result; result= exprtype(ltype,rtype); if( result== STRINGTYPE) { if( operator== '+') { emcode("cal","$_concat"); emcode("asp",EMPTRSIZE); emcode("asp",EMPTRSIZE); emcode("lfr",EMPTRSIZE); } else error("illegal operator"); } else { extraconvert(ltype,result,rtype); conversion(rtype,result); if( result== INTTYPE) { if( operator=='+') emcode("adi",EMINTSIZE); else emcode("sbi",EMINTSIZE); } else{ if( operator=='+') emcode("adf",EMFLTSIZE); else emcode("sbf",EMFLTSIZE); } } return(result); } muldiv(ltype,rtype,operator) int ltype,rtype,operator; { int result; result= exprtype(ltype,rtype); if(operator==MODSYM || operator== '\\') result=INTTYPE; extraconvert(ltype,result,rtype); conversion(rtype,result); if( result== INTTYPE) { if( operator=='/') { result= DOUBLETYPE; extraconvert(ltype,result,rtype); conversion(rtype,result); emcode("dvf",EMFLTSIZE); } else if( operator=='\\') emcode("dvi",EMINTSIZE); else if( operator=='*') emcode("mli",EMINTSIZE); else if( operator==MODSYM) emcode("rmi",EMINTSIZE); else error("illegal operator"); } else{ if( operator=='/') emcode("dvf",EMFLTSIZE); else if( operator=='*') emcode("mlf",EMFLTSIZE); else error("illegal operator"); } return(result); } negate(type) int type; { switch(type) { case INTTYPE: emcode("ngi",EMINTSIZE); break; case DOUBLETYPE: case FLOATTYPE: emcode("ngf",EMFLTSIZE); break; default: error("Illegal operator"); } return(type); } power(ltype,rtype) int ltype,rtype; { extraconvert(ltype,DOUBLETYPE,rtype); conversion(rtype,DOUBLETYPE); emcode("cal","$_power"); emcode("asp",EMFLTSIZE); emcode("asp",EMFLTSIZE); emcode("lfr",EMFLTSIZE); return(DOUBLETYPE); } char *typesize(ltype) int ltype; { switch( ltype) { case INTTYPE: return(EMINTSIZE); case FLOATTYPE: case DOUBLETYPE: return(EMFLTSIZE); case STRINGTYPE: return(EMPTRSIZE); default: error("typesize:unexpected"); if(debug) printf("type received %d\n",ltype); } return(EMINTSIZE); } /* loadptr(s) Symbol *s; { if( POINTERSIZE==WORDSIZE) fprintf(tmpfile," loe l%d\n",s->symalias); else if( POINTERSIZE== 2*WORDSIZE) fprintf(tmpfile," lde l%d\n",s->symalias); else error("loadptr:unexpected pointersize"); } */ char *typestring(type) int type; { switch(type) { case INTTYPE: return(EMINTSIZE); case FLOATTYPE: case DOUBLETYPE: return(EMFLTSIZE); case STRINGTYPE: return(EMPTRSIZE); default: error("typestring: unexpected type"); } return("0"); } loadvar(type) int type; { /* load a simple variable its address is on the stack*/ emcode("loi",typestring(type)); return(type); } loadint(value) int value; { emcode("loc",itoa(value)); return(INTTYPE); } loaddbl(value) double value; { int index; index= genlabel(); fprintf(emfile,"l%d\n bss 8,%fF8,1\n",index,value); emcode("lae",datalabel(index)); emcode("loi",EMFLTSIZE); return(DOUBLETYPE); } loadstr(value) int value; { emcode("lae",datalabel(value)); return(STRINGTYPE); } loadaddr(s) Symbol *s; { extern Symbol *fcn; int i,j; if(debug) printf("load %s %d\n",s->symname,s->symtype); if( s->symalias>0) emcode("lae",datalabel(s->symalias)); else{ j= -s->symalias; if(debug) printf("load parm %d\n",j); fprintf(tmpfile," lal "); for(i=fcn->dimensions;i>j;i--) fprintf(tmpfile,"%s+",typesize(fcn->dimlimit[i-1])); fprintf(tmpfile,"0\n"); emlinecount++; /* emcode("lal",datalabel(fcn->dimalias[-s->symalias])); */ } return(s->symtype); } assign(type,lt) int type,lt; { extern int e1,e2; conversion(lt,type); exchange(e1,e2); /* address is on stack already */ emcode("sti",typestring(type) ); } storevar(lab,type) int lab,type; { /*store value back */ emcode("lae",datalabel(lab)); emcode("sti",typestring(type)); } /* maintain a stack of array references */ int dimstk[MAXDIMENSIONS], dimtop= -1; Symbol *arraystk[MAXDIMENSIONS]; newarrayload(s) Symbol *s; { if( dimtopdimensions==0) { s->dimensions=1; defarray(s); } dimstk[dimtop]= s->dimensions; arraystk[dimtop]= s; emcode("lae",datalabel(s->symalias)); } endarrayload() { return(arraystk[dimtop--]->symtype); } loadarray(type) int type; { int dim; Symbol *s; if( dimtop<0 || dimtop>=MAXDIMENSIONS) fatal("too many nested array references"); /* index expression is on top of stack */ s=arraystk[dimtop]; dim= dimstk[dimtop]; if( dim==0) { error("too many indices"); dimstk[dim--]=0; return; } conversion(type,INTTYPE); dim--; /* first check index range */ fprintf(tmpfile," lae r%d\n",s->dimalias[dim]); emlinecount++; emcode("rck",EMINTSIZE); emcode("lae",datalabel(s->dimalias[dim])); emcode("aar",EMINTSIZE); dimstk[dimtop]--; } storearray(type) { /* used only in let statement */ extern int e1,e2; exchange(e1,e2); emcode("sti",typestring(type)); }