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