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