1 2 #define DEBUG error(-1) 3 4 /*#include "CCLIB.TXT" 5 */ 6 #include <stdio.h> 7 8 #define INT (-1) 9 #define CHAR (-2) 10 #define UNSIGNED (-3) 11 #define POINTER (-4) 12 #define ARRAY (-5) 13 #define STRUCT (-6) 14 #define UNION (-7) 15 #define FUNCTION (-8) 16 #define EMPTY (-9) 17 18 #define STATIC (-10) 19 #define GOTO (-11) 20 #define RETURN (-12) 21 #define BREAK (-13) 22 #define CONTINUE (-14) 23 #define IF (-15) 24 #define ELSE (-16) 25 #define FOR (-17) 26 #define DO (-18) 27 #define WHILE (-19) 28 #define SWITCH (-20) 29 #define CASE (-21) 30 #define DEFAULT (-22) 31 #define RESERVE (-23) 32 #define TAG (-24) 33 #define FIELD (-25) 34 #define IDENT (-26) 35 #define STRING (-27) 36 #define MACRO (-28) 37 #define BLABEL (-29) 38 #define FLABEL (-30) 39 #define TYPEDEF (-31) 40 #define SIZEOF (-32) 41 #define TYPE (-33) 42 #define LONG (-34) 43 #define SHORT (-35) 44 45 #define TOP 0 46 #define GDECL 1 47 #define GSDECL 2 48 #define GUDECL 3 49 #define ADECL 4 50 #define LDECL 5 51 #define LSDECL 6 52 #define LUDECL 7 53 #define STADECL 8 54 #define STAT 9 55 #define GTDECL 10 56 #define LTDECL 11 57 58 #define GVAR 1 59 #define RGVAR 2 60 #define CRGVAR 3 61 #define LVAR 4 62 #define RLVAR 5 63 #define CRLVAR 6 64 #define CONST 7 65 #define FNAME 8 66 #define INDIRECT 9 67 #define RINDIRECT 10 68 #define CRINDIRECT 11 69 #define ADDRESS 12 70 #define MINUS 13 71 #define LNOT 14 72 #define BNOT 15 73 #define INC 16 74 #define POSTINC 17 75 #define PREINC 18 76 #define CPOSTINC 19 77 #define CPREINC 20 78 #define DEC 21 79 #define CPOSTDEC 22 80 #define CPREDEC 23 81 #define MUL 24 82 #define UMUL 25 83 #define DIV 26 84 #define UDIV 27 85 #define MOD 28 86 #define UMOD 29 87 #define ADD 30 88 #define SUB 31 89 #define RSHIFT 32 90 #define URSHIFT 33 91 #define LSHIFT 34 92 #define ULSHIFT 35 93 #define GT 36 94 #define UGT 37 95 #define GE 38 96 #define UGE 39 97 #define LT 40 98 #define ULT 41 99 #define LE 42 100 #define ULE 43 101 #define EQ 44 102 #define NEQ 45 103 #define BAND 46 104 #define EOR 47 105 #define BOR 48 106 #define LAND 49 107 #define LOR 50 108 #define COND 51 109 #define ASS 52 110 #define CASS 53 111 #define ASSOP 54 112 #define CASSOP 55 113 #define COMMA 56 114 #define LPAR 57 115 #define RPAR 58 116 #define LBRA 59 117 #define RBRA 60 118 #define LC 61 119 #define RC 62 120 #define COLON 63 121 #define SM 64 122 #define PERIOD 65 123 #define ARROW 66 124 125 #define US 1 126 #define AS 100 127 128 #define FILERR 1 129 #define DCERR 2 130 #define STERR 3 131 #define EXERR 4 132 #define CNERR 5 133 #define CHERR 6 134 #define GSERR 7 135 #define LSERR 8 136 #define STRERR 9 137 #define LNERR 10 138 #define EOFERR 11 139 #define MCERR 12 140 #define INCERR 13 141 #define HPERR 14 142 #define TYERR 15 143 #define LVERR 16 144 #define UDERR 17 145 #define OPTION 18 146 147 #define GSYMS 450 148 #define LSYMS 50 149 150 #define HEAPSIZE 1000 151 #define CHEAPSIZE 3000 152 #define LBUFSIZE 256 153 154 #define FILES 3 155 156 int sym,ch,chsave,type,mode,gfree,lfree,mflag,lineno,glineno; 157 int labelno,gpc,lvar,disp; 158 int symval,args,heap[HEAPSIZE]; 159 int blabel,clabel,dlabel,cslabel,ilabel,control,ac,ac2,lsrc,chk,asmf; 160 161 unsigned hash; 162 163 char linebuf[LBUFSIZE],cheap[CHEAPSIZE],*chptr,*chptrsave; 164 char name[9],*cheapp,**av,/*obuf[320],*/*sptr,escape(); 165 166 FILE *obuf; 167 168 typedef struct nametable { 169 char nm[9]; 170 int sc,ty,dsp; } NMTBL; 171 172 NMTBL ntable[GSYMS+LSYMS],*nptr,*gnptr,*decl0(),*decl1(),*lsearch(),*gsearch(); 173 174 struct {int fd,ln;/*char fcb[320]*/FILE *fcb;} *filep,filestack[FILES]; 175 176 main(argc,argv) 177 int argc; 178 char **argv; 179 {NMTBL *nptr; 180 int i; 181 char *ccout; 182 if(argc==1) exit(1); 183 lsrc = chk = asmf = 0; 184 ccout = "c.out"; 185 ac=argc; 186 av=argv; 187 for (ac2=1; (ac2 < ac) && (*av[ac2] == '-'); ++ac2) 188 switch (*(av[ac2]+1)) 189 {case 'S': case 's': 190 lsrc = 1; 191 break; 192 case 'O': case 'o': 193 ccout = av[ac2]+2; 194 break; 195 case 'C': case 'c': 196 chk = 1; 197 break; 198 default: 199 error(OPTION); 200 exit(1); 201 } 202 fclose(stdout); 203 if (!chk) 204 if ( (obuf = fopen(ccout,"w")) == NULL ) error(FILERR); 205 init(); 206 while(1) 207 { for (nptr = &ntable[GSYMS],i=LSYMS; i--;) 208 (nptr++)->sc = EMPTY; 209 mode=TOP; 210 while(getsym()==SM); 211 mode=GDECL; 212 args=0; 213 decl(); 214 } 215 } 216 error(n) 217 int n; 218 { if(n == EOFERR) 219 if(filep!=filestack) 220 { lineno=filep->ln; 221 fclose(filep->fcb); 222 fprintf(stderr,"End of inclusion.\n"); 223 --filep; 224 return; 225 } 226 else if(ac2!=ac) 227 { fclose(filep->fcb); 228 newfile(); 229 return; 230 } 231 else if(mode == TOP) 232 { fprintf(stderr,"\nCompiled %u lines.\n",glineno-1); 233 if (!chk) fprintf(stderr, 234 "Total internal labels : %u.\n",labelno-1); 235 fprintf(stderr, 236 "Total global variables : %u bytes.\n\n",gpc); 237 printf("_%d\tRTS\n_INITIALIZE\tEQU\t_1\n",ilabel); 238 printf("_GLOBALS\tEQU\t%u\n\tEND\n",gpc); 239 exit(0); 240 } 241 fprintf(stderr,"%5d:%s.\n",lineno, 242 (n==FILERR) ? "Can't open specified file" : 243 (n==DCERR) ? "Declaration syntax" : 244 (n==STERR) ? "Statement syntax" : 245 (n==EXERR) ? "Expression syntax" : 246 (n==CNERR) ? "Constant required" : 247 (n==CHERR) ? "Illegal character" : 248 (n==GSERR) ? "Too many global symbols" : 249 (n==LSERR) ? "Too many local symbols" : 250 (n==STRERR) ? "Too many strings or macros" : 251 (n==LNERR) ? "Line too long" : 252 (n==EOFERR) ? "Unexpected end of file" : 253 (n==MCERR) ? "Macro syntax" : 254 (n==INCERR) ? "Include syntax" : 255 (n==HPERR) ? "Too long expression" : 256 (n==TYERR) ? "Type mismatch" : 257 (n==LVERR) ? "Lvalue required" : 258 (n==UDERR) ? "Undeclared identifier" : 259 (n==OPTION) ? "Illegal option" : 260 "Bug of compiler"); 261 errmsg(); 262 exit(1); 263 } 264 errmsg() 265 {char *p,*lim; 266 if(lineno==0) return; 267 fprintf(stderr,"%s",linebuf); 268 lim=(mflag?chptrsave:chptr); 269 for (p=linebuf; p < lim;) 270 fprintf(stderr,(*p++ == '\t') ? "\t" : " "); 271 fprintf (stderr,"^\n"); 272 } 273 checksym(s) 274 int s; 275 {char *p; 276 if (sym != s) 277 { p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'": 278 (s==LPAR) ? "'('": (s==WHILE) ? "'while'": 279 (s==COLON) ? "':'": "Identifier"; 280 fprintf(stderr,"%d:%s expected.\n",lineno,p); 281 errmsg(); 282 } 283 else getsym(); 284 } 285 init() 286 {NMTBL *nptr; 287 int i; 288 for(nptr = ntable,i = GSYMS; i--;) (nptr++)->sc = EMPTY; 289 reserve("int",INT); 290 reserve("void",INT); 291 reserve("char",CHAR); 292 reserve("struct",STRUCT); 293 reserve("union",UNION); 294 reserve("unsigned",UNSIGNED); 295 reserve("static",STATIC); 296 reserve("goto",GOTO); 297 reserve("return",RETURN); 298 reserve("break",BREAK); 299 reserve("continue",CONTINUE); 300 reserve("if",IF); 301 reserve("else",ELSE); 302 reserve("for",FOR); 303 reserve("do",DO); 304 reserve("while",WHILE); 305 reserve("switch",SWITCH); 306 reserve("case",CASE); 307 reserve("default",DEFAULT); 308 reserve("typedef",TYPEDEF); 309 reserve("sizeof",SIZEOF); 310 reserve("long",LONG); 311 reserve("short",SHORT); 312 gpc=glineno=mflag=0; 313 gfree=ilabel=1; 314 labelno=2; 315 cheapp=cheap; 316 lfree=HEAPSIZE; 317 filep=filestack; 318 newfile(); 319 getline(); 320 getch(); 321 } 322 newfile() 323 { lineno=0; 324 fprintf(stderr,"%s:\n",av[ac2]); 325 if ( (filep->fcb = fopen(av[ac2++],"r")) == NULL ) error(FILERR); 326 } 327 reserve(s,d) 328 char *s; 329 int d; 330 {NMTBL *nptr; 331 char *t; 332 hash=0; 333 t=name; 334 while(*t++ = *s) hash=7*(hash+*s++); 335 (nptr = gsearch())->sc = RESERVE; 336 nptr->dsp = d; 337 } 338 339 decl() 340 {NMTBL *n; 341 int t; 342 if(sym==STATIC) 343 if(mode==LDECL) 344 { getsym(); 345 mode=STADECL; 346 } 347 else error(DCERR); 348 else if(sym==TYPEDEF) 349 if(mode==GDECL) 350 { getsym(); 351 mode=GTDECL; 352 } 353 else if(mode==LDECL) 354 { getsym(); 355 mode=LTDECL; 356 } 357 else error(DCERR); 358 if((t=typespec())==0) return; 359 if(sym==SM) return; 360 type=t; 361 n=decl0(); 362 reverse(t); 363 if(args||sym==LC) {fdecl(n);return;} 364 def(n); 365 while(sym==COMMA) 366 { getsym(); 367 type=t; 368 n=decl0(); 369 reverse(t); 370 if(args) error(DCERR); 371 def(n); 372 } 373 if(sym!=SM) error(DCERR); 374 if(mode==GTDECL) mode=GDECL; 375 if(mode==STADECL||mode==LTDECL) mode=LDECL; 376 } 377 typespec() 378 {int t; 379 switch(sym) 380 {case INT: 381 case CHAR: 382 t= sym; 383 getsym(); 384 break; 385 case STRUCT: 386 case UNION: 387 t=sdecl(sym); 388 break; 389 case UNSIGNED: 390 t = UNSIGNED; 391 if(getsym()==INT) getsym(); 392 break; 393 case SHORT: 394 t=CHAR; 395 if(getsym()==INT) getsym(); 396 break; 397 case LONG: 398 t=INT; 399 if(getsym()==INT) getsym(); 400 break; 401 default: 402 if(sym==IDENT) 403 if(nptr->sc==TYPE) 404 { t=nptr->ty; 405 getsym(); 406 break; 407 } 408 else if(nptr->sc==EMPTY && gnptr->sc==TYPE) 409 { t=gnptr->ty; 410 getsym(); 411 break; 412 } 413 if(mode==LDECL) return 0; 414 t= INT; 415 } 416 return t; 417 } 418 struct nametable *decl0() 419 {NMTBL *n; 420 if(sym==MUL) 421 { getsym(); 422 n=decl0(); 423 type=list2(POINTER,type); 424 return n; 425 } 426 return decl1(); 427 } 428 NMTBL *decl1() 429 {NMTBL *n; 430 int i,t; 431 if(sym==LPAR) 432 { getsym(); 433 n=decl0(); 434 checksym(RPAR); 435 } 436 else if (sym == IDENT) 437 { n=nptr; 438 getsym(); 439 } 440 else error(DCERR); 441 while(1) 442 if(sym==LBRA) 443 if(getsym()==RBRA) 444 { getsym(); 445 if(mode!=ADECL) error(DCERR); 446 t=type; 447 type=list2(POINTER,type); 448 } 449 else 450 { t=type; 451 i=cexpr(expr()); 452 checksym(RBRA); 453 type=list3(ARRAY,t,i); 454 } 455 else if(sym==LPAR) 456 { if(mode==GDECL) {mode=ADECL;getsym();mode=GDECL;} 457 else getsym(); 458 if(sym==RPAR) getsym(); 459 else 460 { n->sc=FUNCTION; 461 adecl(); 462 n->sc=EMPTY; 463 } 464 type=list2(FUNCTION,type); 465 } 466 else return n; 467 } 468 adecl() 469 { if(mode!=GDECL) error(DCERR); 470 mode=ADECL; 471 args= 2; 472 while(1) 473 { if(sym!=IDENT) error(DCERR); 474 nptr->ty = INT; 475 nptr->sc = LVAR; 476 nptr->dsp = (args += 2); 477 if(getsym()!=COMMA) break; 478 getsym(); 479 } 480 checksym(RPAR); 481 mode=GDECL; 482 return; 483 } 484 reverse(t1) 485 int t1; 486 {int t2,t3; 487 t2=t1; 488 while(type!=t1) 489 { t3=cadr(type); 490 rplacad(type,t2); 491 t2=type; 492 type=t3; 493 } 494 type=t2; 495 } 496 size(t) 497 int t; 498 { if(t==CHAR) return 1; 499 if(scalar(t)) return 2; 500 if(car(t)==STRUCT||car(t)==UNION) 501 { if(cadr(t)==-1) error(DCERR); 502 return(cadr(t)); 503 } 504 if(car(t)==ARRAY) return(size(cadr(t))*caddr(t)); 505 else error(DCERR); 506 /*NOTREACHED*/ 507 } 508 def(n) 509 NMTBL *n; 510 {int sz,nsc,ndsp,slfree,l,t,e; 511 if(car(type)==FUNCTION) 512 { fcheck(n); 513 return; 514 } 515 if (n->sc!=EMPTY && 516 (mode!=ADECL || n->sc!=LVAR || n->ty!=INT) && 517 (mode!=GSDECL&&mode!=LSDECL || n->sc!=FIELD || n->dsp!=disp) && 518 (mode!=GUDECL&&mode!=LUDECL || n->sc!=FIELD || n->dsp!=0) ) 519 error(DCERR); 520 sz = size(n->ty = type); 521 switch(mode) 522 {case GDECL: 523 printf("%s\tEQU\t%u\n",n->nm,gpc); 524 case STADECL: 525 nsc = GVAR; 526 ndsp = gpc; 527 if(sym==ASS) 528 { t=type; 529 if(!scalar(t)) 530 error(TYERR); 531 if(mode==STADECL) printf("\tBRA\t_%d\n",l=fwdlabel()); 532 fwddef(ilabel); 533 getsym(); 534 slfree=lfree; 535 e=expr1(); 536 if(car(e)==CONST) 537 { lddim(cadr(e)); 538 indexy(t==CHAR?"STB":"STD",gpc); 539 } 540 else if(t!=CHAR) 541 { if(car(e)==ADDRESS&&car(cadr(e))==GVAR) 542 leaxy(cadr(cadr(e))); 543 else if(car(e)==FNAME) 544 leaxpcr((NMTBL *)cadr(e)); 545 else error(TYERR); 546 stxy(gpc); 547 } 548 else error(TYERR); 549 lfree=slfree; 550 jmp(ilabel=fwdlabel()); 551 if(mode==STADECL) fwddef(l); 552 type=t; 553 } 554 gpc +=sz; 555 break; 556 case GSDECL: 557 nsc = FIELD; 558 ndsp = disp; 559 disp += sz; 560 break; 561 case GUDECL: 562 nsc = FIELD; 563 ndsp = 0; 564 if (disp < sz) disp = sz; 565 break; 566 case GTDECL: 567 nsc = TYPE; 568 break; 569 case ADECL: 570 if(type==CHAR) ++(n->dsp); 571 else if (!scalar(type)) error(TYERR); 572 return; 573 case LDECL: 574 nsc = LVAR; 575 ndsp = (disp -= sz); 576 break; 577 case LSDECL: 578 nsc = FIELD; 579 ndsp = disp; 580 disp += sz; 581 break; 582 case LUDECL: 583 nsc = FIELD; 584 ndsp = 0; 585 if (disp < sz) disp = sz; 586 break; 587 case LTDECL: 588 nsc = TYPE; 589 break; 590 default: 591 error(DCERR); 592 } 593 n->sc = nsc; 594 n->dsp = ndsp; 595 } 596 sdecl(s) 597 int s; 598 {int smode,sdisp,type; 599 NMTBL *nptr0; 600 smode=mode; 601 if (mode==GDECL || mode==GSDECL || mode==GUDECL || mode==GTDECL) 602 mode=(s==STRUCT?GSDECL:GUDECL); 603 else mode=(s==STRUCT?LSDECL:LUDECL); 604 sdisp=disp; 605 disp=0; 606 if (getsym() == IDENT) 607 { nptr0 = nptr; 608 if (getsym() == LC) 609 { if (nptr0->sc != EMPTY) error(DCERR); 610 nptr0->sc = TAG; 611 nptr0->ty = list2(s,-1); 612 while (getsym() != RC) decl(); 613 getsym(); 614 rplacad(type = nptr0->ty,disp); 615 } 616 else 617 { if(nptr0->sc == EMPTY) nptr0=gnptr; 618 if(nptr0->sc == EMPTY) error(UDERR); 619 if(nptr0->sc != TAG) error(TYERR); 620 type = nptr0->ty; 621 } 622 } 623 else if(sym==LC) 624 { while(getsym() != RC) decl(); 625 getsym(); 626 type = list2(s,disp); 627 } 628 else error(DCERR); 629 disp=sdisp; 630 mode=smode; 631 return type; 632 } 633 fdecl(n) 634 NMTBL *n; 635 { args=0; 636 fcheck(n); 637 mode=ADECL; 638 lfree= HEAPSIZE; 639 while (sym!=LC) {decl(); getsym();} 640 disp=0; 641 mode=STAT; 642 while (typeid(getsym()) || sym==STATIC || sym==TYPEDEF) 643 { mode=LDECL; 644 decl(); 645 mode=STAT; 646 } 647 control=1; 648 printf("%s\n\tPSHS\tU\n\tLEAU\t,S\n",n->nm); 649 if(disp) printf("\tLEAS\t%d,S\n",disp); 650 lvar= -disp; 651 while(sym!=RC) statement(); 652 if (control) return2(); 653 } 654 fcheck(n) 655 NMTBL *n; 656 { if(mode!=GDECL||car(type)!=FUNCTION) error(DCERR); 657 if(n->sc==FUNCTION) compatible(n->ty,cadr(type)); 658 else if(n->sc!=EMPTY) error(DCERR); 659 n->sc=FUNCTION; 660 n->ty=cadr(type); 661 } 662 compatible(t1,t2) 663 int t1,t2; 664 { if(integral(t1)) 665 { if(t1!=t2) error(TYERR); 666 } 667 else if(car(t1)!=car(t2)) error(TYERR); 668 else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2)) 669 error(TYERR); 670 else if(car(t1)==POINTER || car(t1)==ARRAY ||car(t1)==FUNCTION) 671 compatible(cadr(t1),cadr(t2)); 672 } 673 scalar(t) 674 int t; 675 { return(integral(t)||car(t)==POINTER); 676 } 677 integral(t) 678 int t; 679 { return(t==INT||t==CHAR||t==UNSIGNED); 680 } 681 682 statement() 683 {int slfree; 684 switch(sym) 685 {case IF: 686 doif(); 687 return; 688 case WHILE: 689 dowhile(); 690 return; 691 case DO: 692 dodo(); 693 return; 694 case FOR: 695 dofor(); 696 return; 697 case SWITCH: 698 doswitch(); 699 return; 700 case LC: 701 docomp(); 702 return; 703 case BREAK: 704 jmp(blabel); 705 getsym(); 706 checksym(SM); 707 return; 708 case CONTINUE: 709 jmp(clabel); 710 getsym(); 711 checksym(SM); 712 return; 713 case CASE: 714 docase(); 715 statement(); 716 return; 717 case DEFAULT: 718 dodefault(); 719 statement(); 720 return; 721 case RETURN: 722 doreturn(); 723 return; 724 case GOTO: 725 dogoto(); 726 return; 727 case SM: 728 getsym(); 729 return; 730 default:if(sym==IDENT&&skipspc()==':') 731 { dolabel(); 732 statement(); 733 } 734 else 735 { slfree=lfree; 736 gexpr(expr()); 737 lfree=slfree; 738 checksym(SM); 739 } 740 } 741 } 742 doif() 743 {int l1,l2,slfree; 744 getsym(); 745 checksym(LPAR); 746 slfree=lfree; 747 bexpr(expr(),0,l1=fwdlabel()); 748 lfree=slfree; 749 checksym(RPAR); 750 statement(); 751 if(sym==ELSE) 752 { if (l2 = control) jmp(l2=fwdlabel()); 753 fwddef(l1); 754 getsym(); 755 statement(); 756 if (l2) fwddef(l2); 757 } 758 else fwddef(l1); 759 } 760 dowhile() 761 {int sbreak,scontinue,slfree,e; 762 sbreak=blabel; 763 scontinue=clabel; 764 blabel=fwdlabel(); 765 clabel=backdef(); 766 getsym(); 767 checksym(LPAR); 768 slfree=lfree; 769 e=expr(); 770 checksym(RPAR); 771 if(sym==SM) 772 { bexpr(e,1,clabel); 773 lfree=slfree; 774 getsym(); 775 } 776 else 777 { bexpr(e,0,blabel); 778 lfree=slfree; 779 statement(); 780 jmp(clabel); 781 } 782 fwddef(blabel); 783 clabel=scontinue; 784 blabel=sbreak; 785 } 786 dodo() 787 {int sbreak,scontinue,l,slfree; 788 sbreak=blabel; 789 scontinue=clabel; 790 blabel=fwdlabel(); 791 clabel=fwdlabel(); 792 l=backdef(); 793 getsym(); 794 statement(); 795 fwddef(clabel); 796 checksym(WHILE); 797 checksym(LPAR); 798 slfree=lfree; 799 bexpr(expr(),1,l); 800 lfree=slfree; 801 checksym(RPAR); 802 checksym(SM); 803 fwddef(blabel); 804 clabel=scontinue; 805 blabel=sbreak; 806 } 807 dofor() 808 {int sbreak,scontinue,l,e,slfree; 809 sbreak=blabel; 810 scontinue=clabel; 811 blabel=fwdlabel(); 812 getsym(); 813 checksym(LPAR); 814 slfree=lfree; 815 if(sym!=SM) 816 { gexpr(expr()); 817 checksym(SM); 818 } 819 else getsym(); 820 lfree=slfree; 821 l=backdef(); 822 if(sym!=SM) 823 { bexpr(expr(),0,blabel); 824 checksym(SM); 825 } 826 else getsym(); 827 lfree=slfree; 828 if(sym==RPAR) 829 { clabel=l; 830 getsym(); 831 statement(); 832 } 833 else 834 { clabel=fwdlabel(); 835 e=expr(); 836 checksym(RPAR); 837 statement(); 838 fwddef(clabel); 839 gexpr(e); 840 lfree=slfree; 841 } 842 jmp(l); 843 fwddef(blabel); 844 clabel=scontinue; 845 blabel=sbreak; 846 } 847 doswitch() 848 {int sbreak,scase,sdefault,slfree; 849 sbreak=blabel; 850 blabel=fwdlabel(); 851 sdefault=dlabel; 852 dlabel=0; 853 scase=cslabel; 854 getsym(); 855 checksym(LPAR); 856 slfree=lfree; 857 gexpr(expr()); 858 lfree=slfree; 859 checksym(RPAR); 860 cslabel = control = 0; 861 statement(); 862 if(dlabel) printf("_%d\tEQU\t_%d\n",cslabel,dlabel); 863 else fwddef(cslabel); 864 cslabel=scase; 865 dlabel=sdefault; 866 fwddef(blabel); 867 blabel=sbreak; 868 } 869 docomp() 870 { getsym(); 871 while(sym!=RC) statement(); 872 getsym(); 873 } 874 docase() 875 {int c,n,l,slfree; 876 c=0; 877 n=2; 878 slfree=lfree; 879 while(sym==CASE) 880 { getsym(); 881 c=list2(cexpr(expr()),c); 882 n+=6; 883 checksym(COLON); 884 } 885 l=fwdlabel(); 886 if (control) 887 { control=0; 888 if (n>127) jmp(l); 889 else printf("\tBRA\t_%d\n",l); 890 } 891 if (cslabel) fwddef(cslabel); 892 while(cadr(c)) 893 { cmpdimm(car(c)); 894 if((n-=6)>127) jcond(l,0); 895 else printf("\tBEQ\t_%d\n",l); 896 c=cadr(c); 897 } 898 lfree=slfree; 899 cmpdimm(car(c)); 900 jcond(cslabel=fwdlabel(),1); 901 fwddef(l); 902 } 903 dodefault() 904 { getsym(); 905 checksym(COLON); 906 if (dlabel) error(STERR); 907 if (!cslabel) jmp(cslabel = fwdlabel()); 908 dlabel = backdef(); 909 } 910 doreturn() 911 {int slfree; 912 if(getsym()==SM) 913 { getsym(); 914 return2(); 915 return; 916 } 917 slfree=lfree; 918 gexpr(expr()); 919 lfree=slfree; 920 checksym(SM); 921 control=0; 922 switch(lvar) 923 {case 0: 924 ret(""); 925 return; 926 case 2: 927 ret("X,"); 928 return; 929 default:unlink(); 930 return; 931 } 932 } 933 return2() 934 { control=0; 935 switch(lvar) 936 {case 0: 937 ret(""); 938 return; 939 case 1: 940 ret("A,"); 941 return; 942 case 2: 943 ret("D,"); 944 return; 945 case 3: 946 ret("A,X,"); 947 return; 948 case 4: 949 ret("D,X,"); 950 return; 951 default:unlink(); 952 return; 953 } 954 } 955 ret(reg) 956 char *reg; 957 { printf("\tPULS\t%sU,PC\n",reg); 958 } 959 unlink() 960 { printf("\tLEAS\t,U\n"); 961 ret(""); 962 } 963 dogoto() 964 {NMTBL *nptr0; 965 getsym(); 966 nptr0=nptr; 967 checksym(IDENT); 968 if(nptr0->sc == BLABEL || nptr0->sc == FLABEL) jmp(nptr0->dsp); 969 else if(nptr0->sc == EMPTY) 970 { nptr0->sc = FLABEL; 971 jmp(nptr0->dsp = fwdlabel()); 972 } 973 else error(STERR); 974 checksym(SM); 975 } 976 dolabel() 977 { if(nptr->sc == FLABEL) fwddef(nptr->dsp); 978 else if(nptr->sc != EMPTY) error(TYERR); 979 nptr->sc = BLABEL; 980 nptr->dsp = backdef(); 981 getsym(); 982 checksym(COLON); 983 } 984 985 expr() 986 { return(rvalue(expr0())); 987 } 988 expr0() 989 {int e; 990 e=expr1(); 991 while(sym==COMMA) {getsym();e=list3(COMMA,e,rvalue(expr1()));} 992 return e; 993 } 994 expr1() 995 {int e1,e2,t,op; 996 e1=expr2(); 997 switch (sym) 998 {case ASS: 999 lcheck(e1); 1000 t=type; 1001 getsym(); 1002 e2=rvalue(expr1()); 1003 if(t==CHAR) {type= INT;return(list3(CASS,e1,e2));} 1004 type=t; 1005 return(list3(ASS,e1,e2)); 1006 case ADD+AS: case SUB+AS: case MUL+AS: case DIV+AS: case MOD+AS: 1007 case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: case EOR+AS: case BOR+AS: 1008 op = sym-AS; 1009 lcheck(e1); 1010 t=type; 1011 getsym(); 1012 e2=rvalue(expr1()); 1013 if(!integral(type)) error(TYERR); 1014 if((t==UNSIGNED||type==UNSIGNED)&& 1015 (op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT)) 1016 op=op+US; 1017 if(t==CHAR) 1018 { type= INT; 1019 return(list4(CASSOP,e1,e2,op)); 1020 } 1021 type=t; 1022 if(integral(t)) return(list4(ASSOP,e1,e2,op)); 1023 if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR); 1024 e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED); 1025 type=t; 1026 return list4(ASSOP,e1,e2,op); 1027 default: 1028 return(e1); 1029 } 1030 } 1031 expr2() 1032 {int e1,e2,e3,t; 1033 e1=expr3(); 1034 if(sym==COND) 1035 { e1=rvalue(e1); 1036 getsym(); 1037 e2=rvalue(expr2()); 1038 t=type; 1039 checksym(COLON); 1040 e3=rvalue(expr2()); 1041 if(car(e1)==CONST) 1042 if(cadr(e1)) {type=t;return e2;} 1043 else return e3; 1044 if(type==INT||t!=INT&&type==UNSIGNED) type=t; 1045 return(list4(COND,e1,e2,e3)); 1046 } 1047 return(e1); 1048 } 1049 expr3() 1050 {int e; 1051 e=expr4(); 1052 while(sym==LOR) 1053 { e=rvalue(e); 1054 getsym(); 1055 e=list3(LOR,e,rvalue(expr4())); 1056 type= INT; 1057 } 1058 return(e); 1059 } 1060 expr4() 1061 {int e; 1062 e=expr5(); 1063 while(sym==LAND) 1064 { e=rvalue(e); 1065 getsym(); 1066 e=list3(LAND,e,rvalue(expr5())); 1067 type= INT; 1068 } 1069 return(e); 1070 } 1071 expr5() 1072 {int e1,e2,t; 1073 e1=expr6(); 1074 while(sym==BOR) 1075 { e1=rvalue(e1); 1076 t=type; 1077 getsym(); 1078 e2=rvalue(expr6()); 1079 e1=binop(BOR,e1,e2,t,type); 1080 } 1081 return(e1); 1082 } 1083 expr6() 1084 {int e1,e2,t; 1085 e1=expr7(); 1086 while(sym==EOR) 1087 { e1=rvalue(e1); 1088 t=type; 1089 getsym(); 1090 e2=rvalue(expr7()); 1091 e1=binop(EOR,e1,e2,t,type); 1092 } 1093 return(e1); 1094 } 1095 expr7() 1096 {int e1,e2,t; 1097 e1=expr8(); 1098 while(sym==BAND) 1099 { e1=rvalue(e1); 1100 t=type; 1101 getsym(); 1102 e2=rvalue(expr8()); 1103 e1=binop(BAND,e1,e2,t,type); 1104 } 1105 return(e1); 1106 } 1107 expr8() 1108 {int e,op; 1109 e=expr9(); 1110 while((op=sym)==EQ||op==NEQ) 1111 { e=rvalue(e); 1112 getsym(); 1113 e=list3(op,e,rvalue(expr9())); 1114 type= INT; 1115 } 1116 return e; 1117 } 1118 expr9() 1119 {int e1,e2,t,op; 1120 e1=expr10(); 1121 while((op=sym)==GT||op==GE||op==LT||op==LE) 1122 { e1=rvalue(e1); 1123 t=type; 1124 getsym(); 1125 e2=rvalue(expr10()); 1126 if(t==INT&&type==INT) e1=list3(op,e1,e2); 1127 else e1=list3(op+US,e1,e2); 1128 type= INT; 1129 } 1130 return e1; 1131 } 1132 expr10() 1133 {int e1,e2,t,op; 1134 e1=expr11(); 1135 while((op=sym)==RSHIFT||op==LSHIFT) 1136 { e1=rvalue(e1); 1137 t=type; 1138 getsym(); 1139 e2=rvalue(expr11()); 1140 e1=binop(op,e1,e2,t,type); 1141 } 1142 return e1; 1143 } 1144 expr11() 1145 {int e1,e2,t,op; 1146 e1=expr12(); 1147 while((op=sym)==ADD||op==SUB) 1148 { e1=rvalue(e1); 1149 t=type; 1150 getsym(); 1151 e2=rvalue(expr12()); 1152 e1=binop(op,e1,e2,t,type); 1153 } 1154 return e1; 1155 } 1156 expr12() 1157 {int e1,e2,t,op; 1158 e1=expr13(); 1159 while((op=sym)==MUL||op==DIV||op==MOD) 1160 { e1=rvalue(e1); 1161 t=type; 1162 getsym(); 1163 e2=rvalue(expr13()); 1164 e1=binop(op,e1,e2,t,type); 1165 } 1166 return e1; 1167 } 1168 expr13() 1169 {int e,op; 1170 switch (op = sym) 1171 {case INC: case DEC: 1172 getsym(); 1173 lcheck(e=expr13()); 1174 if(type==CHAR) 1175 { type= INT; 1176 return(list2(op==INC?CPREINC:CPREDEC,e)); 1177 } 1178 if(integral(type)) 1179 return(list3(PREINC,e,op==INC?1:-1)); 1180 if(car(type)!=POINTER) error(TYERR); 1181 return(list3(PREINC,e, 1182 op==INC?size(cadr(type)):-size(cadr(type)) )); 1183 case MUL: 1184 getsym(); 1185 e=rvalue(expr13()); 1186 return(indop(e)); 1187 case BAND: 1188 getsym(); 1189 switch(car(e=expr13())) 1190 {case INDIRECT: 1191 e=cadr(e); 1192 break; 1193 case GVAR: 1194 case LVAR: 1195 e=list2(ADDRESS,e); 1196 break; 1197 case FNAME: 1198 return e; 1199 default:error(LVERR); 1200 } 1201 type=list2(POINTER,type); 1202 return e; 1203 case SUB: 1204 getsym(); 1205 e=rvalue(expr13()); 1206 if(!integral(type)) error(TYERR); 1207 return(car(e)==CONST?list2(CONST,-cadr(e)):list2(MINUS,e)); 1208 case BNOT: 1209 getsym(); 1210 e=rvalue(expr13()); 1211 if(!integral(type)) error(TYERR); 1212 return(car(e)==CONST?list2(CONST,~cadr(e)):list2(BNOT,e)); 1213 case LNOT: 1214 getsym(); 1215 return(list2(LNOT,rvalue(expr13()))); 1216 case SIZEOF: 1217 if(getsym()==LPAR) 1218 if(typeid(getsym())) 1219 { e=list2(CONST,size(typename())); 1220 type=INT; 1221 checksym(RPAR); 1222 return e; 1223 } 1224 else 1225 { e=expr0(); 1226 checksym(RPAR); 1227 expr16(e); 1228 if(sym==INC||sym==DEC) 1229 { getsym(); 1230 if(type==CHAR) type=INT; 1231 else if(!scalar(type)) 1232 error(TYERR); 1233 } 1234 } 1235 else expr13(); 1236 e=list2(CONST,size(type)); 1237 type=INT; 1238 return e; 1239 } 1240 e=expr14(); 1241 if((op=sym)==INC||op==DEC) 1242 { lcheck(e); 1243 getsym(); 1244 if(type==CHAR) 1245 { type= INT; 1246 return(list2(op==INC?CPOSTINC:CPOSTDEC,e)); 1247 } 1248 if(integral(type)) 1249 return(list3(POSTINC,e,op==INC?1:-1)); 1250 if(car(type)!=POINTER) error(TYERR); 1251 return (list3(POSTINC,e, 1252 op == INC ? size(cadr(type)): -size(cadr(type)) )); 1253 } 1254 return e; 1255 } 1256 expr14() 1257 {int e1,t; 1258 switch(sym) 1259 {case IDENT: 1260 switch(nptr->sc) 1261 {case GVAR: 1262 e1=list2(GVAR,nptr->dsp); 1263 type=nptr->ty; 1264 getsym(); 1265 break; 1266 case LVAR: 1267 e1=list2(LVAR,nptr->dsp); 1268 type=nptr->ty; 1269 getsym(); 1270 break; 1271 case FUNCTION: 1272 e1=list2(FNAME,(int)nptr); 1273 type=list2(FUNCTION,nptr->ty); 1274 getsym(); 1275 break; 1276 case EMPTY: 1277 if(getsym()==LPAR) 1278 { nptr->sc = FUNCTION; 1279 nptr->ty= INT; 1280 type= list2(FUNCTION,INT); 1281 e1=expr15(list2(FNAME,(int)nptr)); 1282 break; 1283 } 1284 default:error(UDERR); 1285 } 1286 break; 1287 case STRING: 1288 e1=list3(STRING,(int)sptr,symval); 1289 type=list3(ARRAY,CHAR,symval); 1290 getsym(); 1291 break; 1292 case CONST: 1293 type= INT; 1294 e1=list2(CONST,symval); 1295 getsym(); 1296 break; 1297 case LPAR: 1298 if(typeid(getsym())) 1299 { t=typename(); 1300 checksym(RPAR); 1301 e1=expr13(); 1302 type=t; 1303 return e1; 1304 } 1305 e1=expr0(); 1306 checksym(RPAR); 1307 break; 1308 default:error(EXERR); 1309 } 1310 return expr16(e1); 1311 } 1312 expr16(e1) 1313 int e1; 1314 {int e2,t; 1315 while(1) 1316 if(sym==LBRA) 1317 { e1=rvalue(e1); 1318 t=type; 1319 getsym(); 1320 e2=rvalue(expr0()); 1321 checksym(RBRA); 1322 e1=binop(ADD,e1,e2,t,type); 1323 e1=indop(e1); 1324 } 1325 else if(sym==LPAR) e1=expr15(e1); 1326 else if(sym==PERIOD) e1=strop(e1); 1327 else if(sym==ARROW) e1=strop(indop(rvalue(e1))); 1328 else break; 1329 if(car(e1)==FNAME) type=list2(POINTER,type); 1330 return e1; 1331 } 1332 rvalue(e) 1333 int e; 1334 { if(type==CHAR) 1335 { type= INT; 1336 switch(car(e)) 1337 {case GVAR: 1338 return(list2(CRGVAR,cadr(e))); 1339 case LVAR: 1340 return(list2(CRLVAR,cadr(e))); 1341 case INDIRECT: 1342 return(list2(CRINDIRECT,cadr(e))); 1343 default:return(e); 1344 } 1345 } 1346 if(!integral(type)) 1347 if(car(type)==ARRAY) 1348 { type=list2(POINTER,cadr(type)); 1349 if(car(e)==INDIRECT) return cadr(e); 1350 return list2(ADDRESS,e); 1351 } 1352 else if(car(type)!=POINTER) error(TYERR); 1353 switch(car(e)) 1354 {case GVAR: 1355 return(list2(RGVAR,cadr(e))); 1356 case LVAR: 1357 return(list2(RLVAR,cadr(e))); 1358 case INDIRECT: 1359 return(list2(RINDIRECT,cadr(e))); 1360 default:return(e); 1361 } 1362 } 1363 lcheck(e) 1364 int e; 1365 { if(!scalar(type)||car(e)!=GVAR&&car(e)!=LVAR&&car(e)!=INDIRECT) 1366 error(LVERR); 1367 } 1368 indop(e) 1369 int e; 1370 { if(type!=INT&&type!=UNSIGNED) 1371 if(car(type)==POINTER) type=cadr(type); 1372 else error(TYERR); 1373 else type= CHAR; 1374 if(car(e)==ADDRESS) return(cadr(e)); 1375 return(list2(INDIRECT,e)); 1376 } 1377 strop(e) 1378 { getsym(); 1379 if (sym!=IDENT||nptr->sc!=FIELD) error(TYERR); 1380 if (integral(type)||car(type)!=STRUCT && car(type)!=UNION) 1381 e=rvalue(e); 1382 type = nptr->ty; 1383 switch(car(e)) 1384 {case GVAR: 1385 case LVAR: 1386 e=list2(car(e),cadr(e) + nptr->dsp); 1387 break; 1388 case INDIRECT: 1389 if(!nptr->dsp) break; 1390 e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,nptr->dsp))); 1391 break; 1392 default: 1393 e=list2(INDIRECT,list3(ADD,e,list2(CONST,nptr->dsp))); 1394 } 1395 getsym(); 1396 return e; 1397 } 1398 binop(op,e1,e2,t1,t2) 1399 int op,e1,e2,t1,t2; 1400 {int e; 1401 if(car(e1)==CONST&&car(e2)==CONST) 1402 { e1=cadr(e1); 1403 e2=cadr(e2); 1404 type= INT; 1405 switch(op) 1406 {case BOR: 1407 e=e1|e2;break; 1408 case EOR: 1409 e=e1^e2;break; 1410 case BAND: 1411 e=e1&e2;break; 1412 case ADD: 1413 if(integral(t1)) 1414 { if(integral(t2)) 1415 e=e1+e2; 1416 else 1417 { if(car(t2)!=POINTER) error(TYERR); 1418 e=size(cadr(t2))*e1+e2; 1419 type=t2; 1420 } 1421 } 1422 else 1423 { if(car(t1)!=POINTER) error(TYERR); 1424 e=e1+size(cadr(t1))*e2; 1425 type=t1; 1426 } 1427 break; 1428 case SUB: 1429 if(integral(t1)) 1430 e=e1-e2; 1431 else 1432 { if(car(t1)!=POINTER) error(TYERR); 1433 e=e1-size(cadr(t1))*e2; 1434 type=t1; 1435 } 1436 break; 1437 case MUL: 1438 e=e1*e2;break; 1439 case DIV: 1440 if(!e2) error(EXERR);e=e1/e2;break; 1441 case MOD: 1442 if(!e2) error(EXERR);e=e1%e2;break; 1443 case RSHIFT: 1444 e=e1>>e2;break; 1445 case LSHIFT: 1446 e=e1<<e2; 1447 } 1448 return list2(CONST,e); 1449 } 1450 if((op==ADD||op==MUL||op==BOR||op==EOR||op==BAND)&& 1451 (car(e1)==CONST||car(e2)!=CONST&& 1452 (car(e1)==RGVAR||car(e1)==RLVAR))) 1453 {e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e;} 1454 if(op==ADD) 1455 { if(integral(t1)) 1456 { if(integral(t2)) 1457 { if(t1==INT) type=t2;else type=t1; 1458 return(list3(ADD,e1,e2)); 1459 } 1460 if(car(t2)!=POINTER) error(TYERR); 1461 e=binop(MUL,e1,list2(CONST,size(cadr(t2))),t1,INT); 1462 type=t2; 1463 return(list3(ADD,e,e2)); 1464 } 1465 if(car(t1)!=POINTER||!integral(t2)) error(TYERR); 1466 e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT); 1467 type=t1; 1468 if(car(e1)==ADDRESS&&car(e)==CONST) 1469 return(list2(ADDRESS,list2(car(cadr(e1)), 1470 cadr(cadr(e1))+cadr(e)))); 1471 return(list3(ADD,e1,e)); 1472 } 1473 if(op==SUB) 1474 { if(integral(t1)) 1475 { if(!integral(t2)) error(TYERR); 1476 if(t1==INT) type=t2;else type=t1; 1477 return(list3(SUB,e1,e2)); 1478 } 1479 if(car(t1)!=POINTER) error(TYERR); 1480 if(integral(t2)) 1481 { e=binop(MUL,e2,list2(CONST,size(cadr(t1))),t2,INT); 1482 type=t1; 1483 return(list3(SUB,e1,e)); 1484 } 1485 if(car(t2)!=POINTER) 1486 error(TYERR); 1487 compatible(t1,t2); 1488 e=list3(SUB,e1,e2); 1489 e=binop(DIV,e,list2(CONST,size(cadr(t1))),UNSIGNED,INT); 1490 type= INT; 1491 return e; 1492 } 1493 if(!integral(t1)||!integral(t2)) error(TYERR); 1494 if(t1==INT) type=t2;else type=t1; 1495 if((op==MUL||op==DIV)&&car(e2)==CONST&&cadr(e2)==1) return e1; 1496 if(op==BOR||op==EOR||op==BAND) return(list3(op,e1,e2)); 1497 return(list3(type==UNSIGNED?op+US:op,e1,e2)); 1498 } 1499 expr15(e1) 1500 int e1; 1501 {int t,args; 1502 t=type; 1503 if(integral(t)||car(t)!=FUNCTION) 1504 error(TYERR); 1505 t=cadr(t); 1506 getsym(); 1507 args=0; 1508 while(sym!=RPAR) 1509 { args=list2(rvalue(expr1()),args); 1510 if(sym!=COMMA) break; 1511 getsym(); 1512 } 1513 checksym(RPAR); 1514 if(t==CHAR) type= INT;else type=t; 1515 return list3(FUNCTION,e1,args); 1516 } 1517 typeid(s) 1518 int s; 1519 { return (integral(s) || s==SHORT || s==LONG || s==STRUCT || s==UNION || 1520 (s==IDENT && nptr->sc==TYPE)); 1521 } 1522 typename() 1523 {int t; 1524 type=t=typespec(); 1525 ndecl0(); 1526 reverse(t); 1527 return type; 1528 } 1529 ndecl0() 1530 { if(sym==MUL) 1531 { getsym(); 1532 return type=list2(POINTER,ndecl0()); 1533 } 1534 return ndecl1(); 1535 } 1536 ndecl1() 1537 {int i,t; 1538 if(sym==LPAR) 1539 if(getsym()==RPAR) {type=list2(FUNCTION,type); getsym();} 1540 else 1541 { ndecl0(); 1542 checksym(RPAR); 1543 } 1544 while(1) 1545 if(sym==LBRA) 1546 { getsym(); 1547 t=type; 1548 i=cexpr(expr()); 1549 checksym(RBRA); 1550 type=list3(ARRAY,t,i); 1551 } 1552 else if(sym==LPAR) 1553 { getsym(); 1554 checksym(RPAR); 1555 type=list2(FUNCTION,type); 1556 } 1557 else return type; 1558 } 1559 1560 bexpr(e1,cond,l1) 1561 int e1,l1; 1562 char cond; 1563 {int e2,l2; 1564 if (chk) return; 1565 e2=cadr(e1); 1566 switch(car(e1)) 1567 {case LNOT: 1568 bexpr(e2,!cond,l1); 1569 return; 1570 case GT: 1571 rexpr(e1,l1,cond?"GT":"LE"); 1572 return; 1573 case UGT: 1574 rexpr(e1,l1,cond?"HI":"LS"); 1575 return; 1576 case GE: 1577 rexpr(e1,l1,cond?"GE":"LT"); 1578 return; 1579 case UGE: 1580 rexpr(e1,l1,cond?"HS":"LO"); 1581 return; 1582 case LT: 1583 rexpr(e1,l1,cond?"LT":"GE"); 1584 return; 1585 case ULT: 1586 rexpr(e1,l1,cond?"LO":"HS"); 1587 return; 1588 case LE: 1589 rexpr(e1,l1,cond?"LE":"GT"); 1590 return; 1591 case ULE: 1592 rexpr(e1,l1,cond?"LS":"HI"); 1593 return; 1594 case EQ: 1595 rexpr(e1,l1,cond?"EQ":"NE"); 1596 return; 1597 case NEQ: 1598 rexpr(e1,l1,cond?"NE":"EQ"); 1599 return; 1600 case LAND: 1601 bexpr(e2,0,cond?(l2=fwdlabel()):l1); 1602 bexpr(caddr(e1),cond,l1); 1603 if(cond) fwddef(l2); 1604 return; 1605 case LOR: 1606 bexpr(e2,1,cond?l1:(l2=fwdlabel())); 1607 bexpr(caddr(e1),cond,l1); 1608 if(!cond) fwddef(l2); 1609 return; 1610 case CRGVAR: 1611 ldby(e2); 1612 jcond(l1,cond); 1613 return; 1614 case CRLVAR: 1615 ldbu(e2); 1616 jcond(l1,cond); 1617 return; 1618 case CONST: 1619 if(cond&&e2||!cond&&!e2) jmp(l1); 1620 return; 1621 case RGVAR: 1622 case RLVAR: 1623 case CRINDIRECT: 1624 gexpr(e1); 1625 jcond(l1,cond); 1626 return; 1627 default:gexpr(e1); 1628 subdim(0); 1629 jcond(l1,cond); 1630 return; 1631 } 1632 } 1633 rexpr(e1,l1,s) 1634 int e1,l1; 1635 char *s; 1636 { gexpr(list3(SUB,cadr(e1),caddr(e1))); 1637 printf("\tLB%s\t_%d\n",s,l1); 1638 } 1639 jcond(l,cond) 1640 int l; 1641 char cond; 1642 { printf("\tLB%s\t_%d\n",cond?"NE":"EQ",l); 1643 } 1644 jmp(l) 1645 int l; 1646 { control=0; 1647 printf("\tLBRA\t_%d\n",l); 1648 } 1649 fwdlabel() 1650 { return labelno++; 1651 } 1652 fwddef(l) 1653 int l; 1654 { control=1; 1655 printf("_%d\n",l); 1656 } 1657 backdef() 1658 { control=1; 1659 printf("_%d\n",labelno); 1660 return labelno++; 1661 } 1662 1663 gexpr(e1) 1664 int e1; 1665 {int e2,e3; 1666 if (chk) return; 1667 e2 = cadr(e1); 1668 switch (car(e1)) 1669 {case GVAR: 1670 leaxy(e2); 1671 return; 1672 case RGVAR: 1673 lddy(e2); 1674 return; 1675 case CRGVAR: 1676 ldby(e2); 1677 sex(); 1678 return; 1679 case LVAR: 1680 leaxu(e2); 1681 return; 1682 case RLVAR: 1683 lddu(e2); 1684 return; 1685 case CRLVAR: 1686 ldbu(e2); 1687 sex(); 1688 return; 1689 case FNAME: 1690 leaxpcr((NMTBL *)e2); 1691 tfrxd(); 1692 return; 1693 case CONST: 1694 if (e2) lddim(e2); 1695 else clrd(); 1696 return; 1697 case STRING: 1698 string(e1); 1699 return; 1700 case FUNCTION: 1701 function(e1); 1702 return; 1703 case INDIRECT: 1704 indirect(e1); 1705 return; 1706 case RINDIRECT: case CRINDIRECT: 1707 rindirect(e1); 1708 return; 1709 case ADDRESS: 1710 gexpr(e2); 1711 tfrxd(); 1712 return; 1713 case MINUS: 1714 gexpr(e2); 1715 printf("\tNEGA\n\tNEGB\n\tSBCA\t#0\n"); 1716 return; 1717 case BNOT: 1718 gexpr(e2); 1719 printf("\tCOMA\n\tCOMB\n"); 1720 return; 1721 case PREINC: 1722 switch (car(e2)) 1723 {case GVAR: case LVAR: 1724 ldd(e2); 1725 adddim(caddr(e1)); 1726 std(e2); 1727 return; 1728 default: 1729 gexpr(e2); 1730 lddx(); 1731 adddim(caddr(e1)); 1732 stdx(); 1733 return; 1734 } 1735 case POSTINC: 1736 switch (car(e2)) 1737 {case GVAR: case LVAR: 1738 ldd(e2); 1739 adddim(e3 = caddr(e1)); 1740 std(e2); 1741 subdim(e3); 1742 return; 1743 default: 1744 gexpr(e2); 1745 lddx(); 1746 adddim(e3=caddr(e1)); 1747 stdx(); 1748 subdim(e3); 1749 return; 1750 } 1751 case CPOSTINC: 1752 gexpr(e2); 1753 ldbx(); 1754 incx(); 1755 sex(); 1756 return; 1757 case CPREINC: 1758 gexpr(e2); 1759 incx(); 1760 ldbx(); 1761 sex(); 1762 return; 1763 case CPOSTDEC: 1764 gexpr(e2); 1765 ldbx(); 1766 decx(); 1767 sex(); 1768 return; 1769 case CPREDEC: 1770 gexpr(e2); 1771 decx(); 1772 ldbx(); 1773 sex(); 1774 return; 1775 case MUL: case UMUL: 1776 if (car(e3=caddr(e1)) == CONST) 1777 { if (0 < (e3 = cadr(e3)) && e3 <= 10) 1778 { gexpr(e2); 1779 switch (e3) 1780 {case 8: 1781 asld(); 1782 case 4: 1783 asld(); 1784 case 2: 1785 asld(); 1786 case 1: 1787 return; 1788 case 10: 1789 asld(); 1790 case 5: 1791 pushd(); 1792 asld(); 1793 asld(); 1794 addds(); 1795 return; 1796 case 6: 1797 asld(); 1798 case 3: 1799 pushd(); 1800 asld(); 1801 addds(); 1802 return; 1803 case 9: case 7: 1804 pushd(); 1805 asld(); 1806 asld(); 1807 asld(); 1808 if (e3 == 9) addds(); else subds(); 1809 return; 1810 } 1811 } 1812 } 1813 case DIV: case UDIV: case MOD: case UMOD: 1814 case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: 1815 binexpr(e1); 1816 return; 1817 case ADD: case SUB: case BAND: case EOR: case BOR: 1818 machinop(e1); 1819 return; 1820 case COND: 1821 e2=fwdlabel(); 1822 bexpr(cadr(e1),0,e2); 1823 gexpr(caddr(e1)); 1824 jmp(e3=fwdlabel()); 1825 fwddef(e2); 1826 gexpr(cadddr(e1)); 1827 fwddef(e3); 1828 return; 1829 case ASS: case CASS: 1830 assign(e1); 1831 return; 1832 case ASSOP: case CASSOP: 1833 assop(e1); 1834 return; 1835 case COMMA: 1836 gexpr(e2); 1837 gexpr(caddr(e1)); 1838 return; 1839 default: 1840 bexpr(e1,1,e2=fwdlabel()); 1841 clrd(); 1842 printf("\tBRA\t*+5\n"); 1843 fwddef(e2); 1844 lddim(1); 1845 } 1846 } 1847 string(e1) 1848 int e1; 1849 {char *s; 1850 int i,l,lb; 1851 s=(char *)cadr(e1); 1852 lb=fwdlabel(); 1853 if ((l = caddr(e1)) < 128) 1854 printf("\tLEAX\t2,PC\n\tBRA\t_%d\n",lb); 1855 else 1856 printf("\tLEAX\t3,PC\n\tLBRA\t_%d\n",lb); 1857 do 1858 { printf("\tFCB\t%d",*s++); 1859 for (i=8; --l && --i;) printf(",%d",*s++); 1860 printf("\n"); 1861 } 1862 while (l); 1863 fwddef(lb); 1864 } 1865 function(e1) 1866 int e1; 1867 {int e2,e3,e4,e5,nargs; 1868 NMTBL *n; 1869 e2 = cadr(e1); 1870 nargs = 0; 1871 for (e3 = caddr(e1); e3; e3 = cadr(e3)) 1872 { n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); 1873 switch(car(e4)) 1874 {case FNAME: 1875 leaxpcr(n); 1876 pushx(); 1877 break; 1878 case ADDRESS: 1879 gexpr(e5); 1880 pushx(); 1881 break; 1882 default:gexpr(e4); 1883 pushd(); 1884 } 1885 ++nargs; 1886 } 1887 if (car(e2) == FNAME) 1888 { n=(NMTBL *)cadr(e2); 1889 printf("\tLBSR\t%s\n",n->nm); 1890 } 1891 else 1892 { gexpr(e2); 1893 printf("\tJSR\t,X\n"); 1894 } 1895 if (nargs) printf("\tLEAS\t%d,S\n",2*nargs); 1896 } 1897 indirect(e1) 1898 int e1; 1899 {int e2,e3,e4; 1900 e3 = cadr(e2 = cadr(e1)); 1901 switch(car(e2)) 1902 {case RGVAR: case RLVAR: 1903 ldx(e2); 1904 return; 1905 case ADD: 1906 if(car(e3)==ADDRESS) 1907 { gexpr(caddr(e2)); 1908 gexpr(cadr(e3)); 1909 opdx("LEAX"); 1910 return; 1911 } 1912 switch(car(e4 = caddr(e2))) 1913 {case RGVAR: case RLVAR: 1914 gexpr(e3); 1915 ldx(e4); 1916 opdx("LEAX"); 1917 return; 1918 } 1919 default: 1920 gexpr(e2); 1921 tfrdx(); 1922 } 1923 } 1924 1925 machinop(e1) 1926 int e1; 1927 {int e2,e3; 1928 e2 = cadr(e1); 1929 switch (car(e3 = caddr(e1))) 1930 {case RGVAR: case RLVAR: case CONST: 1931 gexpr(e2); 1932 oprt(car(e1),e3); 1933 return; 1934 default: 1935 gexpr(e3); 1936 pushd(); 1937 gexpr(e2); 1938 tosop(car(e1)); 1939 return; 1940 } 1941 } 1942 1943 rindirect(e1) 1944 int e1; 1945 {char *op; 1946 int e2,e3,e4,byte,l; 1947 op = ((byte = (car(e1) == CRINDIRECT)) ? "LDB" : "LDD"); 1948 e3 = cadr(e2 = cadr(e1)); 1949 switch (car(e2)) 1950 {case RGVAR: case RLVAR: 1951 indir(op,e2); 1952 sextend(byte); 1953 return; 1954 case ADD: 1955 if(car(e3)==ADDRESS) 1956 { gexpr(caddr(e2)); 1957 gexpr(cadr(e3)); 1958 opdx(op); 1959 sextend(byte); 1960 return; 1961 } 1962 switch(car(e4=caddr(e2))) 1963 {case RGVAR: case RLVAR: 1964 gexpr(e3); 1965 ldx(e4); 1966 opdx(op); 1967 sextend(byte); 1968 return; 1969 case CONST: 1970 switch (car(e3)) 1971 {case RGVAR: case RLVAR: 1972 ldx(e3); 1973 indexx(op,cadr(e4)); 1974 sextend(byte); 1975 return; 1976 } 1977 default: 1978 gexpr(e3); 1979 pushd(); 1980 gexpr(e4); 1981 pulx(); 1982 opdx(op); 1983 sextend(byte); 1984 return; 1985 } 1986 case PREINC: 1987 if ((l = caddr(e2)) == -1 || l == -2) 1988 switch (car(e3)) 1989 {case GVAR: case LVAR: 1990 ldx(e3); 1991 predecx(op,l); 1992 stx(e3); 1993 sextend(byte); 1994 return; 1995 } 1996 break; 1997 case POSTINC: 1998 if ((l = caddr(e2)) == 1 || l == 2) 1999 switch (car(e3)) 2000 {case GVAR: case LVAR: 2001 ldx(e3); 2002 postincx(op,l); 2003 stx(e3); 2004 sextend(byte); 2005 return; 2006 } 2007 break; 2008 } 2009 gexpr(e2); 2010 tfrdx(); 2011 indexx(op,0); 2012 sextend(byte); 2013 } 2014 assign(e1) 2015 int e1; 2016 {char *op; 2017 int e2,e3,e4,e5,l; 2018 op = (car(e1) == CASS ? "STB" : "STD"); 2019 e3 = cadr(e2 = cadr(e1)); 2020 e4 = caddr(e1); 2021 switch(car(e2)) 2022 {case GVAR: case LVAR: 2023 gexpr(e4); 2024 index(op,e2); 2025 return; 2026 case INDIRECT: 2027 switch(car(e3)) 2028 {case RGVAR: case RLVAR: 2029 gexpr(e4); 2030 indir(op,e3); 2031 return; 2032 case ADD: 2033 if (car(caddr(e3)) == CONST) 2034 switch (car(e5=cadr(e3))) 2035 {case RGVAR: case RLVAR: 2036 gexpr(e4); 2037 ldx(e5); 2038 indexx(op,cadr(caddr(e3))); 2039 return; 2040 } 2041 break; 2042 case PREINC: 2043 if ((l = caddr(e3)) == -1 || l == -2) 2044 switch (car(e5=cadr(e3))) 2045 {case GVAR: case LVAR: 2046 gexpr(e4); 2047 ldx(e5); 2048 predecx(op,l); 2049 stx(e5); 2050 return; 2051 } 2052 break; 2053 case POSTINC: 2054 if ((l = caddr(e3)) == 1 || l == 2) 2055 switch (car(e5=cadr(e3))) 2056 {case GVAR: case LVAR: 2057 gexpr(e4); 2058 ldx(e5); 2059 postincx(op,l); 2060 stx(e5); 2061 return; 2062 } 2063 break; 2064 } 2065 } 2066 switch (car(e4)) 2067 {case RGVAR: case CRGVAR: case RLVAR: case CRLVAR: case CONST: 2068 gexpr(e2); 2069 gexpr(e4); 2070 break; 2071 default: 2072 gexpr(e4); 2073 pushd(); 2074 gexpr(e2); 2075 pulld(); 2076 } 2077 indexx(op,0); 2078 return; 2079 } 2080 assop(e1) 2081 int e1; 2082 {int e2,e3,byte,op; 2083 char *ldop,*stop; 2084 ldop = ((byte = (car(e1) == CASSOP)) ? "LDB" : "LDD"); 2085 stop = (byte ? "STB" : "STD"); 2086 e2 = cadr(e1); 2087 e3 = caddr(e1); 2088 op = cadddr(e1); 2089 switch (car(e2)) 2090 {case GVAR: case LVAR: 2091 switch (car(e3)) 2092 {case RGVAR: case RLVAR: case CONST: 2093 if (simpop(op)) 2094 { index(ldop,e2); 2095 sextend(byte); 2096 oprt(op,e3); 2097 index(stop,e2); 2098 return; 2099 } 2100 default: 2101 gexpr(e3); 2102 pushd(); 2103 index(ldop,e2); 2104 sextend(byte); 2105 tosop(op); 2106 index(stop,e2); 2107 return; 2108 } 2109 default: 2110 switch (car(e3)) 2111 {case RGVAR: case RLVAR: case CONST: 2112 if (simpop(op)) 2113 { gexpr(e2); 2114 indexx(ldop,0); 2115 sextend(byte); 2116 oprt(op,e3); 2117 indexx(stop,0); 2118 return; 2119 } 2120 default: 2121 gexpr(e3); 2122 pushd(); 2123 gexpr(e2); 2124 indexx(ldop,0); 2125 sextend(byte); 2126 tosop(op); 2127 indexx(stop,0); 2128 return; 2129 } 2130 } 2131 } 2132 simpop(op) 2133 int op; 2134 { return (op == ADD || op == SUB || 2135 op == BAND || op == EOR || op == BOR); 2136 } 2137 oprt(op,e1) 2138 int op,e1; 2139 {int e2; 2140 e2 = cadr(e1); 2141 switch (car(e1)) 2142 {case RGVAR: 2143 oprt1(op,"Y",e2); 2144 return; 2145 case RLVAR: 2146 oprt1(op,"U",e2); 2147 return; 2148 case CONST: 2149 oprtc(op,e2); 2150 return; 2151 } 2152 } 2153 oprt1(op,index,n) 2154 int op,n; 2155 char *index; 2156 { switch (op) 2157 {case ADD: 2158 printf("\tADDD\t%d,%s\n",n,index); 2159 return; 2160 case SUB: 2161 printf("\tSUBD\t%d,%s\n",n,index); 2162 return; 2163 case BAND: case EOR: case BOR: 2164 dualop(op,index,n); 2165 return; 2166 } 2167 } 2168 dualop(op,index,n) 2169 int op; 2170 char *index; 2171 int n; 2172 {char *ops; 2173 ops = ((op == BAND) ? "AND" : 2174 (op == EOR) ? "EOR" : 2175 (op == BOR) ? "OR" : (char *)DEBUG); 2176 printf("\t%sA\t%d,%s\n\t%sB\t%d+1,%s\n",ops,n,index,ops,n,index); 2177 } 2178 2179 oprtc(op,n) 2180 int op,n; 2181 { switch (op) 2182 {case ADD: 2183 adddim(n); 2184 return; 2185 case SUB: 2186 subdim(n); 2187 return; 2188 case BAND: case EOR: case BOR: 2189 dualc(op,n); 2190 return; 2191 } 2192 } 2193 dualc(op,n) 2194 int op; 2195 int n; 2196 {char *ops; 2197 ops = ((op == BAND) ? "AND" : 2198 (op == EOR) ? "EOR" : 2199 (op == BOR) ? "OR" : (char *)DEBUG); 2200 printf("\t%sA\t#%d\n\t%sB\t#%d\n",ops,(n >> 8) & 0xff,ops,n & 0xff); 2201 } 2202 tosop(op) 2203 int op; 2204 { switch (op) 2205 {case ADD: 2206 addds(); 2207 return; 2208 case SUB: 2209 subds(); 2210 return; 2211 case BAND: case EOR: case BOR: 2212 dualtosop(op); 2213 return; 2214 default: 2215 pulx(); 2216 library(op); 2217 } 2218 } 2219 dualtosop(op) 2220 int op; 2221 {char *ops; 2222 ops = ((op == BAND) ? "AND" : 2223 (op == EOR) ? "EOR" : 2224 (op == BOR) ? "OR" : (char *)DEBUG); 2225 printf("\t%sA\t,S+\n\t%sB\t,S+\n",ops,ops); 2226 } 2227 pushd() 2228 { printf("\tPSHS\tD\n"); 2229 } 2230 pushx() 2231 { printf("\tPSHS\tX\n"); 2232 } 2233 pulld() 2234 { printf("\tPULS\tD\n"); 2235 } 2236 pulx() 2237 { printf("\tPULS\tX\n"); 2238 } 2239 tfrdx() 2240 { printf("\tTFR\tD,X\n"); 2241 } 2242 tfrxd() 2243 { printf("\tTFR\tX,D\n"); 2244 } 2245 /* 2246 exgdx() 2247 { printf("\tEXG\tD,X\n"); 2248 } 2249 */ 2250 asld() 2251 { printf("\tASLB\n\tROLA\n"); 2252 } 2253 adddim(n) 2254 { printf("\tADDD\t#%d\n",n); 2255 } 2256 subdim(n) 2257 { printf("\tSUBD\t#%d\n",n); 2258 } 2259 cmpdimm(n) 2260 int n; 2261 { printf("\tCMPD\t#%d\n",n); 2262 } 2263 addds() 2264 { printf("\tADDD\t,S++\n"); 2265 } 2266 subds() 2267 { printf("\tSUBD\t,S++\n"); 2268 } 2269 clrd() 2270 { printf("\tCLRA\n\tCLRB\n"); 2271 } 2272 lddim(n) 2273 int n; 2274 { printf("\tLDD\t#%d\n",n); 2275 } 2276 2277 ldd(e) 2278 int e; 2279 { switch (car(e)) 2280 {case GVAR: 2281 lddy(cadr(e)); 2282 return; 2283 case LVAR: 2284 lddu(cadr(e)); 2285 return; 2286 default: 2287 DEBUG; 2288 } 2289 } 2290 2291 lddx() 2292 { printf("\tLDD\t,X\n"); 2293 } 2294 lddy(n) 2295 int n; 2296 { printf("\tLDD\t%d,Y\n",n); 2297 } 2298 lddu(n) 2299 int n; 2300 { printf("\tLDD\t%d,U\n",n); 2301 } 2302 2303 std(e) 2304 int e; 2305 { switch (car(e)) 2306 {case GVAR: 2307 stdy(cadr(e)); 2308 return; 2309 case LVAR: 2310 stdu(cadr(e)); 2311 return; 2312 default: 2313 DEBUG; 2314 } 2315 } 2316 stdx() 2317 { printf("\tSTD\t,X\n"); 2318 } 2319 stdy(n) 2320 int n; 2321 { printf("\tSTD\t%d,Y\n",n); 2322 } 2323 stdu(n) 2324 int n; 2325 { printf("\tSTD\t%d,U\n",n); 2326 } 2327 2328 ldbx() 2329 { printf("\tLDB\t,X\n"); 2330 } 2331 /* 2332 stbx() 2333 { printf("\tSTB\t,X\n"); 2334 } 2335 */ 2336 ldby(n) 2337 int n; 2338 { printf("\tLDB\t%d,Y\n",n); 2339 } 2340 ldbu(n) 2341 int n; 2342 { printf("\tLDB\t%d,U\n",n); 2343 } 2344 predecx(op,l) 2345 char *op; 2346 int l; 2347 { printf("\t%s\t,%sX\n",op,(l == -1 ? "-" : "--")); 2348 } 2349 postincx(op,l) 2350 char *op; 2351 int l; 2352 { printf("\t%s\t,X%s\n",op,(l == 1 ? "+" : "++")); 2353 } 2354 leaxy(n) 2355 int n; 2356 { printf("\tLEAX\t%d,Y\n",n); 2357 } 2358 leaxu(n) 2359 int n; 2360 { printf("\tLEAX\t%d,U\n",n); 2361 } 2362 leaxpcr(n) 2363 NMTBL *n; 2364 { printf("\tLEAX\t%s,PCR\n",n->nm); 2365 } 2366 2367 ldx(e) 2368 int e; 2369 { switch (car(e)) 2370 {case GVAR: case RGVAR: 2371 ldxy(cadr(e)); 2372 return; 2373 case LVAR: case RLVAR: 2374 ldxu(cadr(e)); 2375 return; 2376 default: 2377 DEBUG; 2378 } 2379 } 2380 2381 ldxy(n) 2382 int n; 2383 { printf("\tLDX\t%d,Y\n",n); 2384 } 2385 ldxu(n) 2386 int n; 2387 { printf("\tLDX\t%d,U\n",n); 2388 } 2389 /* 2390 ldxi(n) 2391 int n; 2392 { printf("\tLDX\t#%d\n",n); 2393 } 2394 */ 2395 stx(e) 2396 int e; 2397 { switch (car(e)) 2398 {case GVAR: 2399 stxy(cadr(e)); 2400 return; 2401 case LVAR: 2402 stxu(cadr(e)); 2403 return; 2404 default: 2405 DEBUG; 2406 } 2407 } 2408 2409 stxy(n) 2410 int n; 2411 { printf("\tSTX\t%d,Y\n",n); 2412 } 2413 stxu(n) 2414 int n; 2415 { printf("\tSTX\t%d,U\n",n); 2416 } 2417 2418 sex() 2419 { printf("\tSEX\n"); 2420 } 2421 incx() 2422 { printf("\tINC\t,X\n"); 2423 } 2424 decx() 2425 { printf("\tDEC\t,X\n"); 2426 } 2427 opdx(op) 2428 char *op; 2429 { printf("\t%s\tD,X\n",op); 2430 } 2431 indexx(op,n) 2432 char *op; 2433 int n; 2434 { printf("\t%s\t%d,X\n",op,n); 2435 } 2436 2437 index(op,e) 2438 char *op; 2439 int e; 2440 { switch (car(e)) 2441 {case GVAR: 2442 indexy(op,cadr(e)); 2443 return; 2444 case LVAR: 2445 indexu(op,cadr(e)); 2446 return; 2447 default: 2448 DEBUG; 2449 } 2450 } 2451 2452 indexy(op,n) 2453 char *op; 2454 int n; 2455 { printf("\t%s\t%d,Y\n",op,n); 2456 } 2457 indexu(op,n) 2458 char *op; 2459 int n; 2460 { printf("\t%s\t%d,U\n",op,n); 2461 } 2462 2463 2464 indir(op,e) 2465 char *op; 2466 int e; 2467 { switch (car(e)) 2468 {case RGVAR: 2469 indiry(op,cadr(e)); 2470 return; 2471 case RLVAR: 2472 indiru(op,cadr(e)); 2473 return; 2474 default: 2475 DEBUG; 2476 } 2477 } 2478 2479 indiry(op,n) 2480 char *op; 2481 int n; 2482 { printf("\t%s\t[%d,Y]\n",op,n); 2483 } 2484 indiru(op,n) 2485 char *op; 2486 int n; 2487 { printf("\t%s\t[%d,U]\n",op,n); 2488 } 2489 sextend(byte) 2490 int byte; 2491 { if (byte) sex(); 2492 } 2493 binexpr(e1) 2494 int e1; 2495 { gexpr(caddr(e1)); 2496 pushd(); 2497 gexpr(cadr(e1)); 2498 pulx(); 2499 library(car(e1)); 2500 } 2501 library(op) 2502 int op; 2503 { printf("\tLBSR\t_0000%d\n", 2504 ((op == MUL || op == UMUL) ? 1 : 2505 (op == DIV) ? 2 : 2506 (op == UDIV) ? 3 : 2507 (op == MOD) ? 4 : 2508 (op == UMOD) ? 5 : 2509 (op == LSHIFT) ? 6 : 2510 (op == ULSHIFT) ? 7 : 2511 (op == RSHIFT) ? 8 : 2512 (op == URSHIFT) ? 9 : DEBUG)); 2513 } 2514 cexpr(e) 2515 int e; 2516 { if (car(e) != CONST) error(CNERR); 2517 return (cadr(e)); 2518 } 2519 2520 getsym() 2521 {NMTBL *nptr0,*nptr1; 2522 int i; 2523 char c; 2524 if (alpha(skipspc())) 2525 { i = hash = 0; 2526 while (alpha(ch) || digit(ch)) 2527 { if (i <= 7) hash=7*(hash+(name[i++]=ch)); 2528 getch(); 2529 } 2530 name[i] = '\0'; 2531 nptr0 = gsearch(); 2532 if (nptr0->sc == RESERVE) return sym = nptr0->dsp; 2533 if (nptr0->sc == MACRO && !mflag) 2534 { mflag++; 2535 chsave = ch; 2536 chptrsave = chptr; 2537 chptr = (char *)nptr0->dsp; 2538 getch(); 2539 return getsym(); 2540 } 2541 sym = IDENT; 2542 gnptr=nptr=nptr0; 2543 if (mode==GDECL || mode==GSDECL || mode==GUDECL || 2544 mode==GTDECL || mode==TOP) 2545 return sym; 2546 nptr1=lsearch(); 2547 if (mode==STAT) 2548 if (nptr1->sc == EMPTY) return sym; 2549 else { nptr=nptr1; return sym;} 2550 nptr=nptr1; 2551 return sym; 2552 } 2553 else if (digit(ch)) 2554 { symval=0; 2555 if (ch == '0') 2556 { if (getch() == 'x' || ch == 'X') 2557 while(1) 2558 if(digit(getch())) 2559 symval=symval*16+ch-'0'; 2560 else if('a'<=ch&&ch<='f') 2561 symval=symval*16+ch-'a'+10; 2562 else if('A'<=ch&&ch<='F') 2563 symval=symval*16+ch-'A'+10; 2564 else break; 2565 else while (digit(ch)) {symval=symval*8+ch-'0';getch();} 2566 } 2567 else while(digit(ch)) {symval=symval*10+ch-'0';getch();} 2568 return sym=CONST; 2569 } 2570 else if(ch=='\'') 2571 { getch(); 2572 symval=escape(); 2573 if(ch!='\'') error(CHERR); 2574 getch(); 2575 return sym=CONST; 2576 } 2577 else if(ch=='"') 2578 { getstring(); 2579 return sym= STRING; 2580 } 2581 c=ch; 2582 getch(); 2583 switch(c) 2584 {case '*': 2585 return postequ(MUL,MUL+AS); 2586 case '&': 2587 if(ch=='&') {getch();return sym=LAND;} 2588 return postequ(BAND,BAND+AS); 2589 case '-': 2590 if(ch=='>') {getch();return sym=ARROW;} 2591 if(ch=='-') {getch();return sym=DEC;} 2592 return postequ(SUB,SUB+AS); 2593 case '!': 2594 return postequ(LNOT,NEQ); 2595 case '~': 2596 return sym=BNOT; 2597 case '+': 2598 if(ch=='+') {getch();return sym=INC;} 2599 return postequ(ADD,ADD+AS); 2600 case '%': 2601 return postequ(MOD,MOD+AS); 2602 case '^': 2603 return postequ(EOR,EOR+AS); 2604 case '|': 2605 if(ch=='|') {getch();return sym=LOR;} 2606 return postequ(BOR,BOR+AS); 2607 case '=': 2608 return postequ(ASS,EQ); 2609 case '>': 2610 if(ch=='>') {getch();return postequ(RSHIFT,RSHIFT+AS);} 2611 return postequ(GT,GE); 2612 case '<': 2613 if(ch=='<') {getch();return postequ(LSHIFT,LSHIFT+AS);} 2614 return postequ(LT,LE); 2615 case '(': 2616 return sym=LPAR; 2617 case ')': 2618 return sym=RPAR; 2619 case '[': 2620 return sym=LBRA; 2621 case ']': 2622 return sym=RBRA; 2623 case '{': 2624 return sym=LC; 2625 case '}': 2626 return sym=RC; 2627 case ',': 2628 return sym=COMMA; 2629 case ';': 2630 return sym=SM; 2631 case ':': 2632 return sym=COLON; 2633 case '?': 2634 return sym=COND; 2635 case '.': 2636 return sym=PERIOD; 2637 case '/': 2638 if(ch!='*') return postequ(DIV,DIV+AS); 2639 getch(); 2640 while(ch=='*'?getch()!='/':getch()); 2641 getch(); 2642 return getsym(); 2643 default: 2644 error(CHERR); 2645 return getsym(); 2646 } 2647 } 2648 postequ(s1,s2) 2649 int s1,s2; 2650 { if(ch=='=') {getch();return sym=s2;} 2651 return sym=s1; 2652 } 2653 alpha(c) 2654 char c; 2655 { return('a'<=c&&c<='z'||'A'<=c&&c<='Z'||c=='_'); 2656 } 2657 digit(c) 2658 char c; 2659 { return('0'<=c&&c<='9'); 2660 } 2661 NMTBL *gsearch() 2662 {NMTBL *nptr,*iptr; 2663 iptr=nptr= &ntable[hash % GSYMS]; 2664 while(nptr->sc!=EMPTY && neqname(nptr->nm)) 2665 { if (++nptr== &ntable[GSYMS]) nptr=ntable; 2666 if (nptr==iptr) error(GSERR); 2667 } 2668 if (nptr->sc == EMPTY) copy(nptr->nm); 2669 return nptr; 2670 } 2671 NMTBL *lsearch() 2672 {NMTBL *nptr,*iptr; 2673 iptr=nptr= &ntable[hash%LSYMS+GSYMS]; 2674 while(nptr->sc!=EMPTY && neqname(nptr->nm)) 2675 { if (++nptr== &ntable[LSYMS+GSYMS]) nptr= &ntable[GSYMS]; 2676 if (nptr==iptr) error(LSERR); 2677 } 2678 if (nptr->sc == EMPTY) copy(nptr->nm); 2679 return nptr; 2680 } 2681 neqname(p) 2682 char *p; 2683 {char *q; 2684 q=name; 2685 while(*p) if(*p++ != *q++) return 1; 2686 return *q!=0; 2687 } 2688 copy(p) 2689 char *p; 2690 {char *q; 2691 q=name; 2692 while(*p++= *q++); 2693 } 2694 getstring() 2695 { getch(); 2696 symval = 0; 2697 sptr = cheapp; 2698 while (ch != '"') 2699 { *cheapp++ = escape(); 2700 symval++; 2701 if (cheapp >= cheap+CHEAPSIZE) error(STRERR); 2702 } 2703 getch(); 2704 *cheapp++ = '\0'; 2705 symval++; 2706 } 2707 skipspc() 2708 { while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r') getch(); 2709 return ch; 2710 } 2711 getch() 2712 { if(*chptr) return ch= *chptr++; 2713 if(mflag) {mflag=0;chptr=chptrsave;return ch=chsave;} 2714 getline(); 2715 return getch(); 2716 } 2717 char escape() 2718 {char c; 2719 if ((c=ch) == '\\') 2720 { if (digit(c=getch())) 2721 { c = ch-'0'; 2722 if (digit(getch())) 2723 { c = c*8+ch-'0'; 2724 if (digit(getch())) {c=c*8+ch-'0';getch();} 2725 } 2726 return c; 2727 } 2728 getch(); 2729 switch(c) 2730 {case 'n': 2731 return '\n'; 2732 case 't': 2733 return '\t'; 2734 case 'b': 2735 return '\b'; 2736 case 'r': 2737 return '\r'; 2738 case 'f': 2739 return '\f'; 2740 case '\n': 2741 return escape(); 2742 default: 2743 return c; 2744 } 2745 } 2746 if (c == '\n') error(EXERR); 2747 getch(); 2748 return c; 2749 } 2750 FILE *getfname() 2751 {int i; 2752 char name[LBUFSIZE]; 2753 getch(); 2754 if(skipspc()!='"') error(INCERR); 2755 for(i=0;(getch()!='"' && ch!='\n');) 2756 if(i<LBUFSIZE-1) name[i++]=ch; 2757 if(ch=='\n') error(INCERR); 2758 name[i]=0; 2759 return ( (filep+1)->fcb = fopen(name,"r") ); 2760 } 2761 getline() 2762 {int i; 2763 int c; 2764 lineno++; 2765 glineno++; 2766 chptr=linebuf; 2767 i=0; 2768 while ((*chptr++ = c = getc(filep->fcb)) != '\n') 2769 { if (++i > LBUFSIZE-2) error(LNERR); 2770 if (c==EOF) 2771 { error(EOFERR); 2772 --chptr; 2773 } 2774 } 2775 *chptr = '\0'; 2776 if (lsrc && !asmf) printf("* %s",linebuf); 2777 if (*(chptr = linebuf) == '#') 2778 { ++chptr; 2779 if (macroeq("define")) 2780 { i=mode; 2781 mode=GDECL; 2782 ch= *chptr; 2783 if (getsym() == IDENT) 2784 { if (nptr->sc == EMPTY) 2785 { nptr->sc = MACRO; 2786 nptr->dsp = (int)cheapp; 2787 while ((*cheapp++ = c = *chptr++) 2788 && c != '\n'); 2789 *cheapp++ = '\0'; 2790 if (cheapp >= cheap+CHEAPSIZE) 2791 error(STRERR); 2792 if (!c) error(EOFERR); 2793 } 2794 else error(MCERR); 2795 } 2796 else error(MCERR); 2797 mode=i; 2798 *(chptr = linebuf) = '\0'; 2799 } 2800 else if (macroeq("include")) 2801 { fprintf(stderr,"%s",linebuf); 2802 if(filep+1 >= filestack + FILES) error(FILERR); 2803 if ( ((filep+1)->fcb=getfname()) == NULL) error(FILERR); 2804 (filep+1)->ln=lineno; 2805 lineno=0; 2806 ++filep; 2807 *(chptr = linebuf) = '\0'; 2808 } 2809 else if (macroeq("asm")) 2810 { if (asmf) error(MCERR); 2811 asmf = 1; 2812 getline(); 2813 while (asmf) 2814 { printf("%s",linebuf); 2815 getline(); 2816 } 2817 } 2818 else if (macroeq("endasm")) 2819 { if (!asmf) error(MCERR); 2820 asmf = 0; 2821 } 2822 else if (macroeq(" ")) 2823 getline(); 2824 else error(MCERR); 2825 } 2826 } 2827 2828 macroeq(s) 2829 char *s; 2830 {char *p; 2831 for (p = chptr; *s;) if (*s++ != *p++) return 0; 2832 chptr = p; 2833 return 1; 2834 } 2835 2836 car(e) 2837 int e; 2838 { return heap[e]; 2839 } 2840 cadr(e) 2841 int e; 2842 { return heap[e+1]; 2843 } 2844 caddr(e) 2845 int e; 2846 { return heap[e+2]; 2847 } 2848 cadddr(e) 2849 int e; 2850 { return heap[e+3]; 2851 } 2852 list2(e1,e2) 2853 int e1,e2; 2854 {int e; 2855 e=getfree(2); 2856 heap[e]=e1; 2857 heap[e+1]=e2; 2858 return e; 2859 } 2860 list3(e1,e2,e3) 2861 int e1,e2,e3; 2862 {int e; 2863 e=getfree(3); 2864 heap[e]=e1; 2865 heap[e+1]=e2; 2866 heap[e+2]=e3; 2867 return e; 2868 } 2869 list4(e1,e2,e3,e4) 2870 int e1,e2,e3,e4; 2871 {int e; 2872 e=getfree(4); 2873 heap[e]=e1; 2874 heap[e+1]=e2; 2875 heap[e+2]=e3; 2876 heap[e+3]=e4; 2877 return e; 2878 } 2879 getfree(n) 2880 int n; 2881 {int e; 2882 switch (mode) 2883 {case GDECL: case GSDECL: case GUDECL: case GTDECL: 2884 e=gfree; 2885 gfree+=n; 2886 break; 2887 default: 2888 lfree-=n; 2889 e=lfree; 2890 } 2891 if(lfree<gfree) error(HPERR); 2892 return e; 2893 } 2894 rplacad(e,n) 2895 int e,n; 2896 { heap[e+1]=n; 2897 return e; 2898 }