#include "ccg"/* start of cc7 */hie11(lval)int *lval;$(int k;char *ptr;k=primary(lval);ptr=lval[0];blanks();if((ch()=='[')|(ch()=='('))while(1)$(if(match("["))$(if(ptr==0)$(error("can't subscript");junk();needbrack("]");return 0;$)else if(ptr[ident]==pointer)rvalue(lval);else if(ptr[ident]!=array)$(error("can't subscript");k=0;$)push();expression();needbrack("]");if(ptr[type]==cint)doublereg();add();/* not in sym tab & not pointeror array */lval[0]=lval[2]=0;lval[1]=ptr[type];k=1;$)else if(match("("))$(if(ptr==0)callfunction(0);else if(ptr[ident]!=function)$(rvalue(lval);callfunction(0);$)else callfunction(ptr);k=lval[0]=0;$)else return k;$)if(ptr==0)return k;if(ptr[ident]==function)$(immed();outlab(ptr);return 0;$)return k;$)primary(lval)int *lval;$(char *ptr,sname[namesize];int num[1];int k;lval[2]=0; /* clear pointer/array type */if(match("("))$(k=hie1(lval);while(match(","))/* comma op */k=hie1(lval);needbrack(")");return k;$)if(symname(sname))$(if(ptr=findloc(sname))$(getloc(ptr);lval[0]=ptr;lval[1]=ptr[type];if(ptr[ident]==pointer)$(lval[1]=cint;lval[2]=ptr[type];$)if(ptr[ident]==array)$(lval[2]=ptr[type];return 0;$)else return 1;$)if(ptr=findglb(sname))if(ptr[ident]!=function)$(lval[0]=ptr;lval[1]=0;if(ptr[ident]!=array)$(if(ptr[ident]==pointer)lval[2]=ptr[type];return 1;$)immed();outlab(ptr);lval[1]=lval[2]=ptr[type];return 0;$)ptr=addglb(sname,function,cint,0,global);lval[0]=ptr;lval[1]=0;return 0;$)if(constant(num))return(lval[0]=lval[1]=0);else$(error("invalid expression");immed();outdec(0);junk();return 0;$)$)/* * true if val1 -> int pointer * or int array and * val2 not ptr or array */dbltest(val1,val2)int val1[],val2[];$(if(val1[2]!=cint)return 0;if(val2[2])return 0;return 1;$)/* * determine type of binary operation */result(lval,lval2)int lval[],lval2[];$(if(lval[2] & lval2[2]) /* both point or array */lval[2]=0;else if(lval2[2])$(lval[0]=lval2[0];lval[1]=lval2[1];lval[2]=lval2[2];$)$)store(lval)int *lval;$(if (lval[1]==0)putmem(lval[0]);else putstk(lval[1]);$)rvalue(lval)int *lval;$(if ((lval[0]!=0) & (lval[1]==0))getmem(lval[0]);else indirect(lval[1]);$)test(label)int label;$(needbrack("(");expression();needbrack(")");falsejump(label);$)constant(val)int val[];$(if (number(val))$(immed();outdec(val[0]);$)else if (pstr(val))$(immed();outdec(val[0]);$)else if (qstr(val))$(immed();outslt(val[0]);$)else return 0;return 1;$)number(val)int val[];$(int k,minus,base;char c;k=minus=1;base=10;/* start with base 10 */while(k)$(k=0;if(match("+"))k=1;if(match("-"))$(minus=(-minus);k=1;$)$)if(numeric(ch())==0)return 0;if(ch()=='0')$(gch(); /* gobble 0 */c=ch(); /* examine next char */if(c=='x' | c=='X')$(base=16;gch(); /* gobble "x" */$)else base=8;$)while(1)$(c=ch();if(numeric(c))k=k*base+(c-'0');else if(base==16)$(if(c>='A' & c <='F')c=c-55;else if(c>='a' & c <='f')c=c-87;else break; /* not hex */k=k*base+c;$)else break; /* not diget */inbyte(); /* gobble char */$)if (minus<0) k=(-k);val[0]=k;return 1;$)pstr(val)int val[];$(int k;char c;k=0;if (match("'")==0) return 0;while((c=gch())!=39 & c!=0)k=((k&255)<<8) + parsech(c);val[0]=k;return 1;$)qstr(val)int val[];$(if(match(quote)==0) return 0;val[0]=litptr;while (ch()!='"')$(if(ch()==0)break;if(litptr>=litmax)$(error("string space exhausted");while(match(quote)==0)if(gch()==0)break;return 1;$)litq[litptr++]=parsech(gch());$)gch();litq[litptr++]=0;return 1;$)/* Parse a character. * converts \n into EOL, etc. */parsech(chr)char chr;$(int oct,i;char c;/* pass through unless backslash */if(chr != 92)return chr;c=ch();if(c=='b')c=126; /* backspace */else if(c==34)c=34; /* " */else if(c==39)c=39; /* apostrophe */else if(c=='f')c=125; /* CLEAR */else if(c=='n')c=155; /* EOL */else if(c=='g')c=253; /* Bell */else if(c=='t')c=127; /* TAB */else if(c==92)c=92; /* backslash */else if(c >='0' & c <= '7')$(/* octal (yuk) constant */oct=c-'0';gch();i=1;while(i<=2)$(c=ch();if(c < '0' | c > '7')break;oct=(oct<<3)+c-'0';gch();++i;$)return oct;$)else c=ch(); /* ignore \ */gch(); /* skip code char */return c;$)/* end of cc7 */