c01.c (3314B)
1 build(op) { 2 extern cp[], error, block, opdope[], maprel[], chklval; 3 extern chkw, cvtab, lintyp, dcalc; 4 auto p1[], t1, d1, p2[], t2, d2, p3[], t3, d3, t; 5 auto d, dope, lr, cvn; 6 char cvtab[]; 7 8 if (op==4) { /* [] */ 9 build(40); /* + */ 10 op = 36; 11 } 12 dope = opdope[op]; 13 if ((dope&01)!=0) { 14 p2 = *--cp; 15 t2 = p2[1]; 16 d2 = p2[2]; 17 } 18 p1 = *--cp; 19 t1 = p1[1]; 20 d1 = p1[2]; 21 switch (op) { 22 23 /* , */ 24 case 9: 25 *cp++ = block(2, 9, 0, 0, p1, p2); 26 return; 27 28 /* ? */ 29 case 90: 30 if (*p2!=8) 31 error("Illegal conditional"); 32 goto goon; 33 34 /* call */ 35 case 100: 36 *cp++ = block(2,100,t1,24,p1,p2); 37 return; 38 39 /* * */ 40 case 36: 41 if ((t1 =- 16)<0) { 42 error("Illegal indirection"); 43 t1 =+ 16; 44 } 45 if (*p1!=20 & d1==0) 46 d1 = 1; 47 *cp++ = block(1,36,t1,d1,p1); 48 return; 49 50 /* & unary */ 51 case 35: 52 if (*p1 == 36) { /* * */ 53 *cp++ = p1[3]; 54 return; 55 } 56 if (*p1 == 20) { 57 *cp++ = block(1,p1[3]==5?29:35,t1+16,1,p1); 58 return; 59 } 60 error("Illegal lvalue"); 61 } 62 goon: 63 if ((dope&02)!=0) /* lvalue needed on left? */ 64 chklval(p1); 65 if ((dope&020)!=0) /* word operand on left? */ 66 chkw(p1); 67 if ((dope&040)!=0) /* word operand on right? */ 68 chkw(p2); 69 if ((dope&01)!=0) { /* binary op? */ 70 cvn = cvtab[9*lintyp(t1)+lintyp(t2)]; 71 if ((dope&010)!=0) { /* assignment? */ 72 t = t1; 73 lr = 1; 74 cvn =& 07; 75 } else { 76 t = (cvn&0100)!=0? t2:t1; 77 lr = cvn&0200; 78 cvn = (cvn>>3)&07; 79 } 80 if (cvn) { 81 if (cvn==07) { 82 error("Illegal conversion"); 83 goto nocv; 84 } 85 cvn =+ (dope&010)!=0? 83:93; 86 if (lr) { 87 t2 = t; 88 d2 = (p2=convert(p2, t, d2, cvn))[2]; 89 } else { 90 t1 = t; 91 d1 = (p1=convert(p1, t, d1, cvn))[2]; 92 } 93 nocv:; } 94 if (d2>d1 & (dope&0100)!=0) { /* flip commutative? */ 95 if ((dope&04)!=0) /* relational? */ 96 op = maprel[op-60]; 97 d = d1; 98 d1 = d2; 99 d2 = d; 100 d = p1; 101 p1 = p2; 102 p2 = d; 103 d = t1; 104 t1 = t2; 105 t2 = d; 106 } 107 if (d1==d2) 108 d = d1+1; else 109 d = max(d1,d2); 110 if ((dope&04)!=0) 111 t = 0; /* relational is integer */ 112 *cp++ = block(2,op,t,d,p1,p2); 113 return; 114 } 115 *cp++ = block(1,op,t1,d1==0?1:d1,p1); 116 } 117 118 convert(p, t, d, cvn) 119 int p[]; 120 { 121 auto c; 122 if (*p==21) { /* constant */ 123 c = p[3]; 124 switch(cvn) { 125 126 case 99: /* c18 */ 127 c =<< 1; 128 129 case 98: /* c14 */ 130 c =<< 1; 131 132 case 97: /* c12 */ 133 c =<< 1; 134 135 p[3] = c; 136 return(p); 137 } 138 } 139 return(block(1, cvn, t, max(1,d), p)); 140 } 141 142 chkw(p) 143 int p[]; { 144 extern error; 145 auto t; 146 147 if ((t=p[1])>1 & t<16) 148 error("Integer operand required"); 149 return; 150 } 151 152 lintyp(t) { 153 return(t<16? t:(t<32? t-12: 8)); 154 } 155 156 error(s, p1, p2) { 157 extern printf, line, fout, flush, putchar, nerror; 158 int f; 159 160 nerror++; 161 flush(); 162 f = fout; 163 fout = 1; 164 printf("%d: ", line); 165 printf(s, p1, p2); 166 putchar('\n'); 167 fout = f; 168 } 169 170 block(n, op, t, d, p1,p2,p3) 171 int p1[],p2[],p3[]; { 172 extern space[], error, exit, ossiz, ospace[]; 173 auto p[], ap[]; 174 175 p = space; 176 ap = &op; 177 n =+ 3; 178 if(space+n >= ospace+ossiz) { 179 error("Expression overflow"); 180 exit(1); 181 } 182 while(n--) 183 *space++ = *ap++; 184 return(p); 185 } 186 187 chklval(p) 188 int p[]; { 189 extern error; 190 if (*p!=20) 191 if (*p!=36) 192 error("Lvalue required"); 193 } 194 195 notcompat(at, st) { 196 197 if (st==0) /* word, byte */ 198 return(at>1 & at<16); 199 if (st==1) /* word */ 200 return(at>0 & at<16); 201 return((st-2) != at); 202 } 203 204 max(a, b) 205 { 206 if (a>b) 207 return(a); 208 return(b); 209 } 210