comparison os9/mc09/mc.c @ 99:92ed427b7f7d

add micro-c by mohta
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 27 Dec 2018 11:01:16 +0900
parents
children 990add11e9f8
comparison
equal deleted inserted replaced
98:ba0af2b8836b 99:92ed427b7f7d
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 }