home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
223_01
/
cc31.c
< prev
next >
Wrap
Text File
|
1979-12-31
|
8KB
|
296 lines
/*
** 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 (+ auxiliary uses)
** 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, hier, lval)
char *opstr;
int (*testfunc)(), dropval, endval, (*hier)(), lval[]; { /*13*/
int k, hits, droplab, endlab;
hits=0;
while(1) {
k=plnge1(hier, 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[4]=lval[7]=0; /*50*/
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, hier, lval)
char *opstr;
int opoff, (*hier)(), lval[]; { /*13*/
int k, lval2[8];
k=plnge1(hier, 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], hier, lval, lval2);
}
else return 0;
}
}
/*
** unary plunge to lower level
*/
plnge1(hier, lval) int (*hier)(), lval[]; { /*13*/
char *before, *start;
int k;
setstage(&before, &start);
k=(*hier)(lval); /*13*/
if(lval[3]) clearstage(before,0); /* load constant later */
return k;
}
/*
** binary plunge to lower level
*/
plnge2(oper, oper2, hier, lval, lval2)
int (*oper)(),(*oper2)(),(*hier)(),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(hier, lval2)) rvalue(lval2);
if(lval[4]==0) lval[7]=stagenext;
const2(lval[4]<<dbltest(oper, lval2, lval)); /*34*/
}
else { /* non-constant on left side */
push();
if(plnge1(hier, lval2)) rvalue(lval2);
if(lval2[3]) { /* constant on right side */
if(lval2[4]==0) lval[7]=start;
if(oper==ffadd) { /* may test other commutative operators */
csp=csp+2;
clearstage(before, 0);
const2(lval2[4]<<dbltest(oper, lval, lval2)); /*34*/
/* load secondary */
}
else {
const(lval2[4]<<dbltest(oper, lval, lval2)); /*34*/
/* load primary */
smartpop(lval2, start);
}
}
else { /* non-constants on both sides */
smartpop(lval2, start);
/*34*/
if(dbltest(oper, lval,lval2)) doublereg(); /*34*/
if(dbltest(oper, lval2,lval)) { /*34*/
swap();
doublereg();
if(oper==ffsub) swap();
}
/*34*/
}
}
if(oper) {
if(lval[3]=lval[3]&lval2[3]) {
lval[4]=calc(lval[4], oper, lval2[4]);
clearstage(before, 0);
lval[5]=0;
}
else {
if((lval[2]==0)&(lval2[2]==0)) {
(*oper)(); /*13*/
lval[6]=oper; /* identify the operator */
}
else {
(*oper2)(); /*13*/
lval[6]=oper2; /* identify the operator */
}
}
if(oper==ffsub) {
if((lval[2]==CINT)&(lval2[2]==CINT)) {
swap();
const(1);
ffasr(); /** div by 2 **/
}
}
if((oper==ffsub)|(oper==ffadd)) result(lval, lval2);
}
}
calc(left, oper, right) int left, (*oper)(), right; { /*13*/
if(oper == ffor) return (left | right);
else if(oper == ffxor) return (left ^ right);
else if(oper == ffand) return (left & right);
else if(oper == ffeq) return (left == right);
else if(oper == ffne) return (left != right);
else if(oper == ffle) return (left <= right);
else if(oper == ffge) return (left >= 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];
explevel = 0;
if(hier1(lval)) rvalue(lval);
if(lval[3]) {
*const=1;
*val=lval[4];
}
else *const=0;
}
hier1(lval) int lval[]; {
int k,lval2[8], lval3[2], oper, ducon1, ducon2; /* fas 2.2 */
k=plnge1(hier3, lval);
if(match("?")) ducond(); /* fas 2.2 */
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;
}
lval3[0] = lval[0];
lval3[1] = lval[1];
if(lval[1]) {
if(oper) {
push();
rvalue(lval);
}
plnge2(oper, oper, hier1, lval, lval2);
if(oper) pop();
}
else {
if(oper) {
rvalue(lval);
plnge2(oper, oper, hier1, lval, lval2);
}
else {
if(hier1(lval2)) rvalue(lval2);
lval[5]=lval2[5];
}
}
if(match("?")) { /* fas 2.2 */
ducon1 = lval[1];
ducon2 = lval;
ducond();
lval[1] = ducon1;
lval = ducon2;
}
store(lval3);
return 0;
}
ducond() { /* fas 2.2 */
int flab1, flab2, const, val;
flab1 = getlabel(); /* label for false branch */
flab2 = getlabel(); /* label for true exit */
testjump(flab1);
expression(&const,&val);
jump(flab2);
postlabel(flab1);
if(amatch(":",1) ==0) error("colon expected");
expression(&const,&val);
postlabel(flab2);
}
hier3(lval) int lval[]; {
return skim("||", eq0, 1, 0, hier4, lval);
}
hier4(lval) int lval[]; {
return skim("&&", ne0, 0, 1, hier5, lval);
}
hier5(lval) int lval[]; {
return plnge("|", 0, hier6, lval);
}
hier6(lval) int lval[]; {
return plnge("^", 1, hier7, lval);
}
hier7(lval) int lval[]; {
return plnge("&", 2, hier8, lval);
}
hier8(lval) int lval[]; {
return plnge("== !=", 3, hier9, lval);
}
hier9(lval) int lval[]; {
return plnge("<= >= < >", 5, hier10, lval);
}
hier10(lval) int lval[]; {
return plnge(">> <<", 9, hier11, lval);
}
hier11(lval) int lval[]; {
return plnge("+ -", 11, hier12, lval);
}
hier12(lval) int lval[]; {
level = 0;
return plnge("* / %", 13, hier13, lval);
}