c02.c (7052B)
1 function() { 2 extern declare, blkhed, blkend; 3 extern printf, statement, peeksym, cval, symbol, retseq; 4 extern paraml; 5 auto o; 6 7 printf(".text; 1:mov r5,-(sp); mov sp,r5\n"); 8 declare(8); 9 declist(); 10 statement(1); 11 retseq(); 12 } 13 14 extdef() { 15 extern eof, function, cval; 16 extern symbol, block, printf, pname, errflush, csym[]; 17 extern error; 18 auto o, c, cs[]; 19 char s[]; 20 21 if(((o=symbol())==0) | o==1) /* EOF */ 22 return; 23 if(o!=20) 24 goto syntax; 25 csym[0] = 6; 26 cs = &csym[4]; 27 printf(".globl %p\n", cs); 28 s = ".data; %p:1f\n"; 29 switch(o=symbol()) { 30 31 case 6: /* ( */ 32 printf(s, cs); 33 function(); 34 return; 35 36 case 21: /* const */ 37 printf(".data; %p: %o\n", cs, cval); 38 if((o=symbol())!=1) /* ; */ 39 goto syntax; 40 return; 41 42 case 1: /* ; */ 43 printf(".bss; %p: .=.+2\n", cs); 44 return; 45 46 case 4: /* [ */ 47 c = 0; 48 if((o=symbol())==21) { /* const */ 49 c = cval<<1; 50 o = symbol(); 51 } 52 if(o!=5) /* ] */ 53 goto syntax; 54 printf(s, cs); 55 if((o=symbol())==1) { /* ; */ 56 printf(".bss; 1:.=.+%o\n", c); 57 return; 58 } 59 printf("1:"); 60 while(o==21) { /* const */ 61 printf("%o\n", cval); 62 c =- 2; 63 if((o=symbol())==1) /* ; */ 64 goto done; 65 if(o!=9) /* , */ 66 goto syntax; 67 else 68 o = symbol(); 69 } 70 goto syntax; 71 done: 72 if(c>0) 73 printf(".=.+%o\n", c); 74 return; 75 76 case 0: /* EOF */ 77 return; 78 } 79 80 syntax: 81 error("External definition syntax"); 82 errflush(o); 83 statement(0); 84 } 85 86 statement(d) { 87 extern symbol, error, blkhed, eof, peeksym; 88 extern blkend, csym[], rcexpr, block[], tree[], regtab[]; 89 extern retseq, jumpc, jump, label, contlab, brklab, cval; 90 extern swp[], isn, pswitch, peekc, slabel; 91 extern efftab[], declare, deflab, errflush, swtab[], swsiz, branch; 92 93 int o, o1, o2, o3, np[]; 94 95 stmt: 96 switch(o=symbol()) { 97 98 /* EOF */ 99 case 0: 100 error("Unexpected EOF"); 101 /* ; */ 102 case 1: 103 /* } */ 104 case 3: 105 return; 106 107 /* { */ 108 case 2: { 109 if(d) 110 blkhed(); 111 while (!eof) { 112 if ((o=symbol())==3) /* } */ 113 goto bend; 114 peeksym = o; 115 statement(0); 116 } 117 error("Missing '}'"); 118 bend: 119 return; 120 } 121 122 /* keyword */ 123 case 19: 124 switch(cval) { 125 126 /* goto */ 127 case 10: 128 o1 = block(1,102,0,0,tree()); 129 rcexpr(o1, regtab); 130 goto semi; 131 132 /* return */ 133 case 11: 134 if((peeksym=symbol())==6) /* ( */ 135 rcexpr(pexpr(), regtab); 136 retseq(); 137 goto semi; 138 139 /* if */ 140 case 12: 141 jumpc(pexpr(), o1=isn++, 0); 142 statement(0); 143 if ((o=symbol())==19 & cval==14) { /* else */ 144 o2 = isn++; 145 (easystmt()?branch:jump)(o2); 146 label(o1); 147 statement(0); 148 label(o2); 149 return; 150 } 151 peeksym = o; 152 label(o1); 153 return; 154 155 /* while */ 156 case 13: 157 o1 = contlab; 158 o2 = brklab; 159 label(contlab = isn++); 160 jumpc(pexpr(), brklab=isn++, 0); 161 o3 = easystmt(); 162 statement(0); 163 (o3?branch:jump)(contlab); 164 label(brklab); 165 contlab = o1; 166 brklab = o2; 167 return; 168 169 /* break */ 170 case 17: 171 if(brklab==0) 172 error("Nothing to break from"); 173 jump(brklab); 174 goto semi; 175 176 /* continue */ 177 case 18: 178 if(contlab==0) 179 error("Nothing to continue"); 180 jump(contlab); 181 goto semi; 182 183 /* do */ 184 case 19: 185 o1 = contlab; 186 o2 = brklab; 187 contlab = isn++; 188 brklab = isn++; 189 label(o3 = isn++); 190 statement(0); 191 label(contlab); 192 contlab = o1; 193 if ((o=symbol())==19 & cval==13) { /* while */ 194 jumpc(tree(), o3, 1); 195 label(brklab); 196 brklab = o2; 197 goto semi; 198 } 199 goto syntax; 200 201 /* case */ 202 case 16: 203 if ((o=symbol())!=21) /* constant */ 204 goto syntax; 205 if ((o=symbol())!=8) /* : */ 206 goto syntax; 207 if (swp==0) { 208 error("Case not in switch"); 209 goto stmt; 210 } 211 if(swp>=swtab+swsiz) { 212 error("Switch table overflow"); 213 } else { 214 *swp++ = isn; 215 *swp++ = cval; 216 label(isn++); 217 } 218 goto stmt; 219 220 /* switch */ 221 case 15: 222 o1 = brklab; 223 brklab = isn++; 224 np = pexpr(); 225 if (np[1]>1 & np[1]<16) 226 error("Integer required"); 227 rcexpr(np, regtab); 228 pswitch(); 229 brklab = o1; 230 return; 231 232 /* default */ 233 case 20: 234 if (swp==0) 235 error("Default not in switch"); 236 if ((o=symbol())!=8) /* : */ 237 goto syntax; 238 deflab = isn++; 239 label(deflab); 240 goto stmt; 241 } 242 243 error("Unknown keyword"); 244 goto syntax; 245 246 /* name */ 247 case 20: 248 if (peekc==':') { 249 peekc = 0; 250 if (csym[0]>0) { 251 error("Redefinition"); 252 goto stmt; 253 } 254 csym[0] = 2; 255 csym[1] = 020; /* int[] */ 256 if (csym[2]==0) 257 csym[2] = isn++; 258 slabel(); 259 goto stmt; 260 } 261 } 262 263 peeksym = o; 264 rcexpr(tree(), efftab); 265 goto semi; 266 267 semi: 268 if ((o=symbol())!=1) /* ; */ 269 goto syntax; 270 return; 271 272 syntax: 273 error("Statement syntax"); 274 errflush(o); 275 goto stmt; 276 } 277 278 pexpr() 279 { 280 auto o, t; 281 282 if ((o=symbol())!=6) /* ( */ 283 goto syntax; 284 t = tree(); 285 if ((o=symbol())!=7) /* ) */ 286 goto syntax; 287 return(t); 288 syntax: 289 error("Statement syntax"); 290 errflush(o); 291 return(0); 292 } 293 294 pswitch() { 295 extern swp[], isn, swtab[], printf, deflab, statement, brklab; 296 extern label; 297 int sswp[], dl, cv, swlab; 298 299 sswp = swp; 300 if (swp==0) 301 swp = swtab; 302 swlab = isn++; 303 printf("jsr pc,bswitch; l%d\n", swlab); 304 dl = deflab; 305 deflab = 0; 306 statement(0); 307 if (!deflab) { 308 deflab = isn++; 309 label(deflab); 310 } 311 printf("L%d:.data;L%d:", brklab, swlab); 312 while(swp>sswp & swp>swtab) { 313 cv = *--swp; 314 printf("%o; l%d\n", cv, *--swp); 315 } 316 printf("L%d; 0\n.text\n", deflab); 317 deflab = dl; 318 swp = sswp; 319 } 320 321 blkhed() 322 { 323 extern symbol, cval, declare, peeksym, paraml[], parame[]; 324 extern error, length, rlength, setstk, defvec, isn, defstat; 325 extern stack, hshtab[], hshsiz, pssiz; 326 int o, al, pl, cs[], hl; 327 328 declist(); 329 stack = al = -2; 330 pl = 4; 331 while(paraml) { 332 *parame = 0; 333 paraml = *(cs = paraml); 334 cs[2] = pl; 335 *cs = 10; 336 pl =+ rlength(cs[1]); 337 } 338 cs = hshtab; 339 hl = hshsiz; 340 while(hl--) { 341 if (cs[4]) 342 switch(cs[0]) { 343 344 /* sort unmentioned */ 345 case 0177776: /* -2 */ 346 cs[0] = 5; /* auto */ 347 348 /* auto */ 349 case 5: 350 if (cs[3]) { /* vector */ 351 al =- (cs[3]*length(cs[1]-020)+1) & 077776; 352 setstk(al); 353 defvec(al); 354 } 355 cs[2] = al; 356 al =- rlength(cs[1]); 357 goto loop; 358 359 /* parameter */ 360 case 10: 361 cs[0] = 5; 362 goto loop; 363 364 /* static */ 365 case 7: 366 cs[2] = isn++; 367 defstat(cs); 368 goto loop; 369 370 loop:; 371 } 372 cs = cs+pssiz; 373 } 374 setstk(al); 375 } 376 377 blkend() { 378 extern hshtab[], hshsiz, pssiz, hshused; 379 auto i, hl; 380 381 i = 0; 382 hl = hshsiz; 383 while(hl--) { 384 if(hshtab[i+4]) 385 if (hshtab[i]==0) 386 error("%p undefined", &hshtab[i+4]); 387 if(hshtab[i]!=1) { /* not keyword */ 388 hshused--; 389 hshtab[i+4] = 0; 390 } 391 i =+ pssiz; 392 } 393 } 394 395 errflush(o) { 396 extern symbol, peeksym, eof; 397 398 while(o>3) /* ; { } */ 399 o = symbol(); 400 peeksym = o; 401 } 402 403 declist() 404 { 405 extern peeksym, peekc, csym[], cval; 406 auto o; 407 408 while((o=symbol())==19 & cval<10) 409 declare(cval); 410 peeksym = o; 411 } 412 413 easystmt() 414 { 415 extern peeksym, peekc, cval; 416 417 if((peeksym=symbol())==20) /* name */ 418 return(peekc!=':'); /* not label */ 419 if (peeksym==19) { /* keyword */ 420 switch(cval) 421 422 case 10: /* goto */ 423 case 11: /* return */ 424 case 17: /* break */ 425 case 18: /* continue */ 426 return(1); 427 return(0); 428 } 429 return(peeksym!=2); /* { */ 430 } 431 432 branch(lab) 433 { 434 printf("br L%d\n", lab); 435 } 436