/* ** 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; int (*testfunc)(), dropval, endval, heir, lval[]; { /*13*/ int k, hits, droplab, endlab; hits=0; while(1) { k=plnge1(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 */ dropout(k, testfunc, exit1, lval) int k, (*testfunc)(), exit1, lval[]; { /*13*/ if(k) rvalue(lval); else if(lval[3]) const(lval[4]); (*testfunc)(exit1); /* jumps on false */ /*13*/ } /* ** plunge to a lower level */ plnge(opstr, opoff, heir, lval) char *opstr; int opoff, (*heir)(), lval[]; { /*13*/ int k, lval2[8]; k=plnge1(heir, lval); if(nextop(opstr)==0) return k; if(k) rvalue(lval); while(1) { if(nextop(opstr)) { bump(opsize); opindex=opindex+opoff; plnge2(op[opindex], op2[opindex], heir, lval, lval2); } else return 0; } } /* ** unary plunge to lower level */ plnge1(heir, lval) int (*heir)(), lval[]; { /*13*/ char *before, *start; int k; setstage(&before, &start); k= (*heir)(lval); /*13*/ if(lval[3]) clearstage(before,0); /* load constant later */ return k; } /* ** binary plunge to lower level */ plnge2(oper, oper2, heir, lval, lval2) int (*oper)(), (*oper2)(), (*heir)(), lval[], lval2[]; { /*13*/ 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(plnge1(heir, lval2)) rvalue(lval2); if(lval[4]==0) lval[7]=stagenext; const2(lval[4]<= right); else if(oper == fflt) return (left < right); else if(oper == ffgt) return (left > right); else if(oper == ffasr) return (left >> right); else if(oper == ffasl) return (left << right); else if(oper == ffadd) return (left + right); else if(oper == ffsub) return (left - right); else if(oper ==ffmult) return (left * right); else if(oper == ffdiv) return (left / right); else if(oper == ffmod) 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[]; { int k,lval2[8], oper; k=plnge1(heir3, lval); if(lval[3]) const(lval[4]); if(match("|=")) oper= ffor; else if(match("^=")) oper= ffxor; else if(match("&=")) oper= ffand; else if(match("+=")) oper= ffadd; else if(match("-=")) oper= ffsub; else if(match("*=")) oper= ffmult; else if(match("/=")) oper= ffdiv; else if(match("%=")) oper= ffmod; else if(match(">>=")) oper= ffasr; else if(match("<<=")) oper= ffasl; else if(match("=")) oper= 0; else return k; if(k==0) { needlval(); return 0; } if(lval[1]) { if(oper) { push(); rvalue(lval); } plnge2(oper, oper, heir1, lval, lval2); if(oper) pop(); } else { if(oper) { rvalue(lval); plnge2(oper, oper, heir1, lval, lval2); } else { if(heir1(lval2)) rvalue(lval2); lval[5]=lval2[5]; } } store(lval); return 0; } heir3(lval) int lval[]; { return skim("||", eq0, 1, 0, heir4, lval); } heir4(lval) int lval[]; { return skim("&&", ne0, 0, 1, heir5, lval); } heir5(lval) int lval[]; { return plnge("|", 0, heir6, lval); } heir6(lval) int lval[]; { return plnge("^", 1, heir7, lval); } heir7(lval) int lval[]; { return plnge("&", 2, heir8, lval); } heir8(lval) int lval[]; { return plnge("== !=", 3, heir9, lval); } heir9(lval) int lval[]; { return plnge("<= >= < >", 5, heir10, lval); } heir10(lval) int lval[]; { return plnge(">> <<", 9, heir11, lval); } heir11(lval) int lval[]; { return plnge("+ -", 11, heir12, lval); } heir12(lval) int lval[]; { return plnge("* / %", 13, heir13, lval); }