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