/* ** lval[0] - symbol table address, else 0 for constant ** lval[1] - type of indirect obj to fetch, else 0 for static ** lval[2] - type of pointer or array, else 0 for all other ** lval[3] - true if constant expression ** lval[4] - value of constant expression ** lval[5] - true if secondary register altered ** lval[6] - function address of highest/last binary operator ** lval[7] - stage address of "oper 0" code, else 0 */ /* ** skim over terms adjoining || and && operators */ skim(opstr, testfunc, dropval, endval, heir, lval) char *opstr; #ifdef FULLC int (*testfunc)(), dropval, endval, (*heir)(), lval[]; { #else /* FULLC */ int testfunc, dropval, endval, heir, lval[]; { #endif /* FULLC */ int k, hits, droplab, endlab; hits=0; while(1) { k=plung1(heir, lval); if(nextop(opstr)) { bump(opsize); if(hits==0) { hits=1; droplab=getlabel(); } dropout(k, testfunc, droplab, lval); } else if(hits) { dropout(k, testfunc, droplab, lval); const(endval); jump(endlab=getlabel()); postlabel(droplab); const(dropval); postlabel(endlab); lval[1]=lval[2]=lval[3]=lval[7]=0; return 0; } else return k; } } /* ** test for early dropout from || or && evaluations */ #ifdef FULLC dropout(k, testfunc, exit1, lval) int k, (*testfunc)(), exit1, lval[]; { #else /* FULLC */ dropout(k, testfunc, exit1, lval) int k, testfunc, exit1, lval[]; { #endif /* FULLC */ if(k) rvalue(lval); else if(lval[3]) const(lval[4]); #ifdef FULLC (*testfunc)(exit1); /* jumps on false */ #else /* FULLC */ testfunc(exit1); /* jumps on false */ #endif /* FULLC */ } /* ** plunge to a lower level */ plunge(opstr, opoff, heir, lval) char *opstr; #ifdef FULLC int opoff, (*heir)(), lval[]; { #else /* FULLC */ int opoff, heir, lval[]; { #endif /* FULLC */ int k, lval2[8]; k=plung1(heir, lval); if(nextop(opstr)==0) return k; if(k) rvalue(lval); while(1) { if(nextop(opstr)) { bump(opsize); opindex=opindex+opoff; plung2(op[opindex], op2[opindex], heir, lval, lval2); } else return 0; } } /* ** unary plunge to lower level ** renamed "plung1" (original was "plunge1") to have ** first 6 chars unique for M80 assembler. */ #ifdef FULLC plung1(heir, lval) int (*heir)(), lval[]; { #else /* FULLC */ plung1(heir, lval) int heir, lval[]; { #endif /* FULLC */ char *before, *start; int k; setstage(&before, &start); #ifdef FULLC k= (*heir)(lval); #else /* FULLC */ k= heir(lval); #endif /* FULLC */ if(lval[3]) clearstage(before,0); /* load constant later */ return k; } /* ** binary plunge to lower level ** renamed "plung2" (original was "plunge2") to have ** first 6 chars unique for M80 assembler. */ plung2(oper, oper2, heir, lval, lval2) #ifdef FULLC int (*oper)(), (*oper2)(), (*heir)(), lval[], lval2[]; { #else /* FULLC */ int oper, oper2, heir, lval[], lval2[]; { #endif /* FULLC */ char *before, *start; setstage(&before, &start); lval[5]=1; /* flag secondary register used */ lval[7]=0; /* flag as not "... oper 0" syntax */ if(lval[3]) { /* constant on left side not yet loaded */ if(plung1(heir, lval2)) rvalue(lval2); if(lval[4]==0) lval[7]=stagenext; const2(lval[4]<= right); else if(oper == zzlt) return (left < right); else if(oper == zzgt) return (left > right); else if(oper == zzasr) return (left >> right); else if(oper == zzasl) return (left << right); else if(oper == zzadd) return (left + right); else if(oper == zzsub) return (left - right); else if(oper ==zzmult) return (left * right); else if(oper == zzdiv) return (left / right); else if(oper == zzmod) return (left % right); else return 0; } expression(const, val) int *const, *val; { int lval[8]; if(heir1(lval)) rvalue(lval); if(lval[3]) { *const=1; *val=lval[4]; } else *const=0; } heir1(lval) int lval[]; { #ifdef FULLC int k,lval2[8], (*oper)(), heir3(); #else /* FULLC */ int k,lval2[8], oper, heir3(); #endif /* FULLC */ k=plung1(heir3, lval); if(lval[3]) const(lval[4]); if(match("|=")) oper= zzor; else if(match("^=")) oper= zzxor; else if(match("&=")) oper= zzand; else if(match("+=")) oper= zzadd; else if(match("-=")) oper= zzsub; else if(match("*=")) oper= zzmult; else if(match("/=")) oper= zzdiv; else if(match("%=")) oper= zzmod; else if(match(">>=")) oper= zzasr; else if(match("<<=")) oper= zzasl; else if(match("=")) oper= 0; else return k; if(k==0) { needlval(); return 0; } if(lval[1]) { if(oper) { zzpush(); rvalue(lval); } plung2(oper, oper, heir1, lval, lval2); if(oper) zzpop(); } else { if(oper) { rvalue(lval); plung2(oper, oper, heir1, lval, lval2); } else { if(heir1(lval2)) rvalue(lval2); lval[5]=lval2[5]; } } store(lval); return 0; } heir3(lval) int lval[]; { int heir4(); return skim("||", eq0, 1, 0, heir4, lval); } heir4(lval) int lval[]; { int heir5(); return skim("&&", ne0, 0, 1, heir5, lval); } heir5(lval) int lval[]; { int heir6(); return plunge("|", 0, heir6, lval); } heir6(lval) int lval[]; { int heir7(); return plunge("^", 1, heir7, lval); } heir7(lval) int lval[]; { int heir8(); return plunge("&", 2, heir8, lval); } heir8(lval) int lval[]; { int heir9(); return plunge("== !=", 3, heir9, lval); } heir9(lval) int lval[]; { int heir10(); return plunge("<= >= < >", 5, heir10, lval); } heir10(lval) int lval[]; { int heir11(); return plunge(">> <<", 9, heir11, lval); } heir11(lval) int lval[]; { int heir12(); return plunge("+ -", 11, heir12, lval); } heir12(lval) int lval[]; { int heir13(); return plunge("* / %", 13, heir13, lval); }