|
|
1.1 root 1: /*
2: * Table processor for the
3: * new compiler, machine independent.
4: * Runs under Coherent. Uses
5: * two output files for compatability with
6: * the VAX cross compilers.
7: * Caches pattern flags, node flags, and type flags.
8: * Overlays common sequences before end of macros.
9: */
10: char helpmessage[] = "\
11: Usage: tabgen [-s] [-d define] [-p pfn] [-m mfn] file ...\n\
12: ";
13: /*
14: * Options:
15: * -s report statistics
16: * -d define treat 'define' as defined in #ifdef and #ifndef
17: * NDEF is limit on number of -d define's
18: * -p pfn make 'pfn' the pattern file name
19: * -m mfn make 'mfn' the macro file name
20: * Arguments are concatenated into the tables with attention
21: * #ifdef's and #ifndef's.
22: */
23:
24: #include <ctype.h>
25: #define YATC 1
26: #ifdef vax
27: #include "INC$LIB:host.h"
28: #include "INC$LIB:cc1.h"
29: #else
30: #include "host.h"
31: #include "cc1.h"
32: #endif
33:
34: #define nel(x) (sizeof(x)/sizeof(x[0]))
35:
36: #define NCPS 8 /* Max identifier size */
37: #define NDEF 32 /* Limit on number of -d defines */
38: #define NHASH 512 /* Size of macro element hash */
39: #define NMAC 256 /* Max number of elements in macro */
40:
41: typedef struct cache {
42: struct cache *c_fp;
43: int c_type;
44: int c_sequence;
45: char c_data[];
46: } CACHE;
47:
48: #define CPAT 0
49: #define CTYPE 1
50: #define CFLAG 2
51: #define CICON 3
52: #define CLCON 4
53: #define CGID 5
54: #define CFILE 6
55: #define NCACHE 7
56:
57: typedef struct hash {
58: char s_name[NCPS];
59: } HASH;
60:
61: HASH hash[NHASH];
62: HASH *macv[NMAC];
63: HASH *m_end, *m_newl, *m_jmp, *m_gid, *m_icon, *m_lcon;
64: HASH *mlookup();
65: int nmac = 0;
66:
67: typedef struct sort {
68: int t_boffs;
69: HASH *t_symb;
70: struct sort *t_diff, *t_same;
71: } SORT;
72:
73: SORT *root;
74:
75: FILE *ifp;
76: FILE *pfp;
77: FILE *mfp;
78:
79: int fnseq = 0;
80: char *fname = NULL;
81: int lineno = 0;
82: CACHE *cache = NULL;
83: int boffs = 0;
84: int bsave = 0;
85: int npats = 0;
86: int sflag = 0;
87: int nflag = 0;
88: int flevel = 0;
89: int tlevel = 0;
90: int getnc = 0;
91: int nbol = 0;
92: int ndef = 0;
93: int hiteof = 0;
94: int ungetc = -1;
95: int opseq = 1;
96: int fargc;
97: char **fargv;
98:
99: int cacheseq[NCACHE];
100: char pbuf[128];
101: char *def[NDEF];
102: char *getcp;
103: char getbuf[128];
104:
105: struct optable {
106: char o_id[NCPS]; /* Name */
107: short o_value; /* Op value */
108: short o_seq; /* Pattern sequence */
109: short o_npat; /* # of patterns */
110: } optable[] = {
111: { "ADD", ADD },
112: { "SUB", SUB },
113: { "MUL", MUL },
114: { "DIV", DIV },
115: { "REM", REM },
116: { "AND", AND },
117: { "OR", OR },
118: { "XOR", XOR },
119: { "SHL", SHL },
120: { "SHR", SHR },
121: { "AADD", AADD },
122: { "ASUB", ASUB },
123: { "AMUL", AMUL },
124: { "ADIV", ADIV },
125: { "AREM", AREM },
126: { "AAND", AAND },
127: { "AOR", AOR },
128: { "AXOR", AXOR },
129: { "ASHL", ASHL },
130: { "ASHR", ASHR },
131: { "EQ", EQ },
132: { "NE", NE },
133: { "GT", GT },
134: { "GE", GE },
135: { "LE", LE },
136: { "LT", LT },
137: { "UGT", UGT },
138: { "UGE", UGE },
139: { "ULE", ULE },
140: { "ULT", ULT },
141: { "STAR", STAR },
142: { "ADDR", ADDR },
143: { "NEG", NEG },
144: { "COM", COM },
145: { "NOT", NOT },
146: { "QUEST", QUEST },
147: { "COLON", COLON },
148: { "INCBEF", INCBEF },
149: { "DECBEF", DECBEF },
150: { "INCAFT", INCAFT },
151: { "DECAFT", DECAFT },
152: { "COMMA", COMMA },
153: { "CALL", CALL },
154: { "ANDAND", ANDAND },
155: { "OROR", OROR },
156: { "CAST", CAST },
157: { "CONVERT", CONVERT },
158: { "FIELD", FIELD },
159: { "SIZEOF", SIZEOF },
160: { "ASSIGN", ASSIGN },
161: { "NOP", NOP },
162: { "INIT", INIT },
163: { "ARGLST", ARGLST },
164: { "LEAF", LEAF },
165: { "FIXUP", FIXUP },
166: { "BLKMOVE", BLKMOVE }
167: };
168:
169: /*
170: * Only macros which must be recognized
171: * are listed, the rest are output symbolically.
172: */
173: struct mtab {
174: char m_id[NCPS];
175: short m_byte;
176: } mtab[] = {
177: { "IFR", M_IFR },
178: { "IFE", M_IFE },
179: { "IFV", M_IFV },
180: { "CONST", M_ICON },
181: { "LCONST", M_LCON },
182: { "REGNO", M_REGNO },
183: { "GID", M_GID }
184: };
185:
186: #ifdef Z8001
187: FILE *ofp;
188: char file[2];
189: int line;
190: VARIANT variant;
191: #endif
192:
193: main(argc, argv)
194: char *argv[];
195: {
196: char *pfn;
197: char *mfn;
198: char *p;
199: int c;
200: int i;
201:
202: pfn = "patern.c";
203: mfn = "macros.c";
204: for (i=1; i<argc; ++i) {
205: p = argv[i];
206: if (*p == '-') {
207: while ((c = *++p) != 0) {
208: switch (c) {
209:
210: case 'p':
211: if (++i >= argc)
212: usage();
213: pfn = argv[i];
214: break;
215:
216: case 'm':
217: if (++i >= argc)
218: usage();
219: mfn = argv[i];
220: break;
221:
222: case 's':
223: sflag = 1;
224: break;
225:
226: case 'n':
227: nflag = 1;
228: break;
229:
230: case 'd':
231: if (++i >= argc)
232: usage();
233: def[ndef++] = argv[i];
234: break;
235:
236: default:
237: usage();
238: }
239: }
240: } else
241: break;
242: }
243: fargc = argc - i;
244: fargv = argv + i;
245: if (fargc == 0)
246: usage();
247: pinit(pfn);
248: minit(mfn);
249: if (sflag)
250: for (i=0; i<ndef; ++i)
251: fprintf(stderr, "def[%d] = \"%s\"\n", i, def[i]);
252: ncompile();
253: pfinis();
254: mfinis();
255: if (sflag) {
256: fprintf(stderr, "%d patterns, %d bytes.\n", npats, boffs);
257: fprintf(stderr, "%d bytes saved by goto\n", bsave);
258: fprintf(stderr, "%d patflags\n", cacheseq[CPAT]);
259: fprintf(stderr, "%d types\n", cacheseq[CTYPE]);
260: fprintf(stderr, "%d flags\n", cacheseq[CFLAG]);
261: fprintf(stderr, "%d constants\n", cacheseq[CICON]);
262: fprintf(stderr, "%d long constants\n", cacheseq[CLCON]);
263: fprintf(stderr, "%d global identifiers\n", cacheseq[CGID]);
264: fprintf(stderr, "%d files\n", cacheseq[CFILE]);
265: }
266: exit (OK);
267: }
268:
269: usage()
270: {
271: fprintf(stderr, helpmessage);
272: exit(ABORT);
273: }
274:
275:
276: pinit(pfn)
277: char *pfn;
278: {
279: if ((pfp = fopen(pfn, "w")) == NULL) {
280: fprintf(stderr, "%s: cannot create\n", pfn);
281: exit(ABORT);
282: }
283: intro(pfp);
284: fprintf(pfp, "#if !TINY\n");
285: fprintf(pfp, "#define fl(f,l) , f, l\n");
286: fprintf(pfp, "#else\n");
287: fprintf(pfp, "#define fl(f,l) /* f, l */\n");
288: fprintf(pfp, "#endif\n");
289: fprintf(pfp, "extern char macros[];\n");
290: }
291:
292: minit(mfn)
293: char *mfn;
294: {
295: if ((mfp = fopen(mfn, "w")) == NULL) {
296: fprintf(stderr, "%s: cannot create\n", mfn);
297: exit(ABORT);
298: }
299: intro(mfp);
300: fprintf(mfp, "char macros[] = {\n");
301: m_end = mlookup("M_END");
302: m_newl = mlookup("\n");
303: m_jmp = mlookup("M_JMP");
304: m_gid = mlookup("M_GID");
305: m_icon = mlookup("M_ICON");
306: m_lcon = mlookup("M_LCON");
307: }
308:
309: pfinis()
310: {
311: opindex();
312: dumpcache("PATFLAG\tpatcache", CPAT);
313: fprintf(pfp, "int patcsize=sizeof(patcache)/sizeof(PATFLAG);\n");
314: dumpcache("TYPESET\ttypecache", CTYPE);
315: dumpcache("FLAG\tflagcache", CFLAG);
316: dumpcache("ival_t\tivalcache", CICON);
317: dumpcache("lval_t\tlvalcache", CLCON);
318: dumpcache("char\t*gidcache", CGID);
319: fprintf(pfp, "#if !TINY\n");
320: dumpcache("char\t*namecache", CFILE);
321: fprintf(pfp, "#endif\n");
322: fclose(pfp);
323: }
324:
325: mfinis()
326: {
327: fprintf(mfp, " 0\n};\n");
328: fclose(mfp);
329: }
330:
331: intro(fp)
332: FILE *fp;
333: {
334: fprintf(fp, "#ifdef vax\n");
335: fprintf(fp, "#include \"INC$LIB:cc1.h\"\n");
336: fprintf(fp, "#else\n");
337: fprintf(fp, "#include \"cc1.h\"\n");
338: fprintf(fp, "#endif\n");
339: }
340:
341: ncompile()
342: {
343: extern char *rindex();
344: for (fnseq = 0; fnseq < fargc; fnseq += 1) {
345: fname = fargv[fnseq];
346: if ((ifp = fopen(fname, "r")) == NULL) {
347: fprintf(stderr, "%s: cannot open\n", fname);
348: exit(ABORT);
349: }
350: lineno = 0;
351: hiteof = 0;
352: fprintf(pfp, "/* %s */\n", fname);
353: fprintf(mfp, "/* %s */\n", fname);
354: if (rindex(fname, '/') != 0)
355: fname = rindex(fname, '/')+1;
356: findcache(fname, CFILE);
357: compile();
358: if (tlevel!=0 || flevel!=0)
359: fatal("dangeling #if");
360: fclose(ifp);
361: }
362: }
363:
364: compile()
365: {
366: register struct optable *opp;
367: register c;
368: struct optable *oplookup();
369: char id[NCPS];
370: int npat;
371:
372: c = getnb();
373: while (c != EOF) {
374: if (!isalpha(c))
375: fatal("missing op name");
376: do {
377: getid(c, id);
378: opp = oplookup(id);
379: opp->o_seq = opseq;
380: if (getnb() != ':')
381: fatal("missing ':'");
382: } while (isalpha(c = getnb()));
383: if (c != '%')
384: fatal("missing '%'");
385: fprintf(pfp, "PAT p%d[] = {\n", opseq);
386: npat = 0;
387: do {
388: do {
389: pat(npat);
390: ++npat;
391: ++npats;
392: } while ((c = getnb()) == '%');
393: if (c == EOF)
394: fatal("eof");
395: unget(c);
396: c = body();
397: } while (c == '%');
398: fprintf(pfp, "\n};\n");
399: for (opp = &optable[0]; opp < &optable[nel(optable)]; ++opp)
400: if (opp->o_seq == opseq)
401: opp->o_npat = npat;
402: ++opseq;
403: }
404: }
405:
406: pat(nth)
407: {
408: register char *cbp;
409: register int c;
410: register int i;
411: register int needtbar;
412: int pline;
413: /*
414: * Pattern fields requiring mapping with T_ prefixes
415: * and * translation.
416: */
417: static int tbars[] = {
418: 0,
419: 0, 0, 0, 0, 0,
420: 1, 0,
421: 1, 0
422: };
423: static char none[] = " NONE";
424: static char zero[] = " 0";
425: static char *stars[] = {
426: zero,
427: zero, none, none, none, none,
428: zero, zero,
429: zero, zero
430: };
431:
432: pline = lineno;
433: if (nth > 0)
434: fprintf(pfp, ",\n");
435: fprintf(pfp, " {");
436: for (i=0; i<10; ++i) {
437: cbp = pbuf;
438: if ((c = getnb()) == EOF)
439: fatal("eof");
440: needtbar = tbars[i];
441: do {
442: if (needtbar != 0) {
443: needtbar = 0;
444: if (c != '*') {
445: *cbp++ = 'T';
446: *cbp++ = '_';
447: }
448: }
449: *cbp++ = c;
450: if (c == '|')
451: needtbar = tbars[i];
452: c = get();
453: } while (c!=' ' && c!='\t' && c!='\n');
454: *cbp++ = 0;
455: unget(c);
456: if (strcmp(pbuf, "*") == 0)
457: fprintf(pfp, stars[i]);
458: else {
459: switch (i) {
460: case 0:
461: fprintf(pfp, " %2d", findcache(pbuf, CPAT));
462: break;
463: case 1:
464: case 7:
465: case 9:
466: fprintf(pfp, " %2d", findcache(pbuf, CTYPE));
467: break;
468: case 6:
469: case 8:
470: fprintf(pfp, " %2d", findcache(pbuf, CFLAG));
471: break;
472: default:
473: fprintf(pfp, " %4s", pbuf);
474: }
475: }
476: putc(',', pfp);
477: }
478: fprintf(pfp, " ¯os[%4d]", boffs);
479: fprintf(pfp, " fl(%d,%d)", fnseq, pline);
480: fprintf(pfp, " }");
481: }
482:
483: findcache(p, t)
484: char *p;
485: {
486: register struct cache *cp;
487:
488: cp = cache;
489: while (cp != NULL) {
490: if (cp->c_type==t && strcmp(p, cp->c_data)==0)
491: return (cp->c_sequence);
492: cp = cp->c_fp;
493: }
494: cp = (struct cache *) malloc(sizeof(struct cache)+strlen(p)+1);
495: if (cp == NULL)
496: fatal("out of cache!");
497: cp->c_fp = cache;
498: cache = cp;
499: cp->c_type = t;
500: cp->c_sequence = ++cacheseq[t];
501: strcpy(cp->c_data, p);
502: return (cp->c_sequence);
503: }
504:
505: dumpcache(p, t)
506: char *p;
507: {
508: register struct cache *cp;
509: register int i;
510:
511: fprintf(pfp, "%s[] = {\n", p);
512: for (i=1; i<=cacheseq[t]; ++i) {
513: cp = cache;
514: while (cp != NULL) {
515: if (cp->c_type==t && cp->c_sequence==i)
516: break;
517: cp = cp->c_fp;
518: }
519: if (i > 1)
520: fprintf(pfp, ",\n\t");
521: else
522: fprintf(pfp, "\t");
523: if (t==CGID || t==CFILE)
524: fprintf(pfp, "\"%s\"", cp->c_data);
525: else
526: fprintf(pfp, "%s", cp->c_data);
527: }
528: if (i==1)
529: fprintf(pfp, "\t0");
530: fprintf(pfp, "\n};\n");
531: }
532:
533: struct optable *
534: oplookup(id)
535: register char *id;
536: {
537: register struct optable *opp;
538:
539: opp = &optable[0];
540: while (opp < &optable[sizeof(optable)/sizeof(optable[0])]) {
541: if (strncmp(id, opp->o_id, NCPS) == 0)
542: return (opp);
543: ++opp;
544: }
545: fatal("operator not defined");
546: }
547:
548: body()
549: {
550: int c;
551:
552: c = body1();
553: body2();
554: return (c);
555: }
556:
557: /*
558: * Parse body.
559: */
560: body1()
561: {
562: register b, c;
563: static char id[NCPS];
564: int iff;
565:
566: fprintf(mfp, "/* %4d */\n", boffs);
567: /* Read body and subsequent blank lines */
568: for (;;) {
569: c = getnb();
570: /* End of body reached */
571: if (c==EOF || c=='%' || (c>='A' && c<='Z'))
572: break;
573: if (c == ';')
574: continue; /* Eat them */
575: /* No conditional yet */
576: iff = 0;
577: /* Parse line */
578: do {
579: /* Eat intermediate spaces */
580: while (c==' ' || c=='\t')
581: c = get();
582: /* Catch trailing spaces */
583: if (c == '\n')
584: break;
585: /* Read bracketed macros */
586: if (c == '[') {
587: /* Until matching ] found */
588: do {
589: /* No more tab spacing */
590: while ((c = get()) == ' ')
591: ;
592: getid(c, id);
593: c = get();
594: b = maclookup(id);
595: /* Output most macros */
596: if (b != M_ICON && b != M_LCON) {
597: if (id[0] == 'Z')
598: mbyte(id);
599: else
600: mbar(id);
601: }
602: /* Output register name */
603: if (b == M_REGNO) {
604: while (c == ' ')
605: c = get();
606: getid(c, id);
607: mbyte(id);
608: c = get();
609: }
610: /* Output identifier */
611: if (b == M_GID) {
612: while (c == ' ')
613: c = get();
614: getid(c, id);
615: mnum(findcache(id, CGID));
616: c = get();
617: }
618: /* Note conditional macros */
619: if (b==M_IFR || b==M_IFV || b==M_IFE)
620: iff = 1;
621: /* Pack constants */
622: if (b == M_ICON || b == M_LCON)
623: c = getcon(b, c);
624: } while (c == ' ');
625: if (c != ']')
626: fatal("missing ']' in macro");
627: }
628: c = get();
629: } while (c!=EOF && c!='\n');
630: /* Terminate conditional */
631: if (iff != 0)
632: mbyte("M_ENDIF");
633: macv[nmac++] = m_newl;
634: if (nmac >= NMAC)
635: fatal("macro too big");
636: }
637: /* Terminate macro */
638: macv[nmac++] = m_end;
639: boffs += 1;
640: macv[nmac++] = m_newl;
641: return (c);
642: }
643:
644: maclookup(id)
645: register char *id;
646: {
647: register struct mtab *mtp;
648:
649: for (mtp = &mtab[0]; mtp < &mtab[sizeof(mtab)/sizeof(mtab[0])]; ++mtp)
650: if (strncmp(id, mtp->m_id, NCPS) == 0) {
651: return (mtp->m_byte);
652: }
653: return (-1);
654: }
655:
656: getcon(m, c)
657: int m;
658: register int c;
659: {
660: register long l;
661: register int b;
662: register char *p;
663: static char digita[] = "0123456789ABCDEF";
664: static char digitb[] = "0123456789abcdef";
665: static char nbuf[16];
666: extern char *index();
667:
668: while (c == ' ')
669: c = get();
670: l = 0;
671: b = 10;
672: if (c == '0') {
673: b = 8;
674: c = get();
675: if (c=='x' || c == 'X') {
676: b = 16;
677: c = get();
678: }
679: }
680: for (;;) {
681: if ((p = index(digita, c)) && (p-digita) < b)
682: c = p - digita;
683: else if ((p = index(digitb, c)) && (p-digitb) < b)
684: c = p - digitb;
685: else
686: break;
687: l = b*l + c;
688: c = get();
689: }
690: sprintf(nbuf, "0x%lx", l);
691: if (m == M_ICON) {
692: mbar("ICON");
693: mnum(findcache(nbuf, CICON));
694: } else {
695: strcat(nbuf, "L");
696: mbar("LCON");
697: mnum(findcache(nbuf, CLCON));
698: }
699: return (c);
700: }
701:
702: mbyte(id)
703: char *id;
704: {
705: macv[nmac++] = mlookup(id);
706: boffs += 1;
707: }
708:
709: HASH *
710: mlookup(id)
711: char *id;
712: {
713: register HASH *sp;
714: register char *p;
715: register int i;
716: unsigned h;
717:
718: p = id;
719: h = 0;
720: i = NCPS;
721: while (--i >= 0)
722: if (*p)
723: h += *p++;
724: sp = &hash[h%NHASH];
725: p = id;
726: i = NHASH;
727: while (--i >= 0) {
728: if (sp->s_name[0] == 0) {
729: strncpy(sp->s_name, p, NCPS);
730: return (sp);
731: }
732: if (strncmp(sp->s_name, p, NCPS) == 0)
733: return (sp);
734: if (++sp >= &hash[NHASH])
735: sp = &hash[0];
736: }
737: fatal("out of hash");
738: }
739:
740: mbar(id)
741: register char *id;
742: {
743: static char t[NCPS] = "M_";
744:
745: strncpy(t+2, id, NCPS-2);
746: mbyte(t);
747: }
748:
749: mnum(num)
750: int num;
751: {
752: static char t[] = "0x??";
753:
754: mknum(t, num);
755: mbyte(t);
756: }
757:
758: mknum(id, n)
759: register char *id;
760: register int n;
761: {
762: static char d[] = "0123456789ABCDEF";
763:
764: id[0] = '0';
765: id[1] = 'x';
766: id[3] = d[n&0xf];
767: n >>= 4;
768: id[2] = d[n&0xf];
769: id[4] = 0;
770: }
771:
772: /*
773: * Match body into reverse sorted tree,
774: * replace common ends with jumps,
775: * print body.
776: */
777: body2()
778: {
779: int sboffs; /* Saved byte size of macro */
780: int jto; /* Byte offset to jump to */
781: int jfrom; /* Byte offset to jump from */
782: int jnmac; /* The element which becomes M_JMP */
783: int noto; /* We're in the middle of a macro, don't jump */
784: register SORT **tpp;
785: register HASH *sp;
786: static char t1[] = "0x??";
787: static char t2[] = "0x??";
788: register int i;
789:
790: sboffs = boffs;
791: jto = -1;
792: tpp = &root;
793: i = nmac;
794: /* For each input macro element */
795: while (--i >= 0) {
796: /* Avoid gotos from within two byte macros */
797: noto = 0;
798: if (i > 0) {
799: sp = macv[i-1];
800: if (sp==m_gid || sp==m_icon || sp==m_lcon)
801: noto += 1;
802: }
803: /* Count down the byte offset */
804: if ((sp = macv[i]) != m_newl)
805: boffs -= 1;
806: /* Until match or new entry */
807: for (;;) {
808: /* New entry */
809: if (*tpp == NULL) {
810: if ((*tpp = malloc(sizeof(SORT))) == NULL)
811: fatal("out of trees");
812: (*tpp)->t_boffs = boffs;
813: (*tpp)->t_symb = sp;
814: (*tpp)->t_diff = NULL;
815: (*tpp)->t_same = NULL;
816: break;
817: }
818: /* Match */
819: if ((*tpp)->t_symb == sp) {
820: if (noto == 0) {
821: jto = (*tpp)->t_boffs;
822: jfrom = boffs;
823: jnmac = i;
824: }
825: break;
826: }
827: /* Search for match or empty */
828: tpp = &(*tpp)->t_same;
829: }
830: /* Advance to next element in macro */
831: tpp = &(*tpp)->t_diff;
832: }
833: /* Ignore any matches if nflag is set */
834: if (nflag)
835: jto = -1;
836: /* See if we found a jump */
837: if (jto >= 0) {
838: /* Make the offset strings for each form of jump */
839: if (jto < 256) {
840: mknum(t1, jto);
841: i = 2;
842: } else if ((jfrom-jto) < 256) {
843: mknum(t1, jfrom-jto);
844: i = 2;
845: } else {
846: mknum(t1, jto);
847: mknum(t2, jto>>8);
848: i = 3;
849: }
850: /* If we save space, make the jump */
851: if ((jfrom+i) < sboffs) {
852: nmac = jnmac;
853: if (nmac != 0 && macv[nmac-1] != m_newl)
854: macv[nmac++] = m_newl;
855: macv[nmac++] = m_jmp;
856: }
857: }
858: /* Print out the macro */
859: for (i = 0; --nmac > 0; i += 1)
860: if ((sp = macv[i]) == m_newl)
861: putc('\n', mfp);
862: else {
863: if (i==0 || macv[i-1] == m_newl)
864: putc('\t', mfp);
865: else
866: putc(' ', mfp);
867: fprintf(mfp, "%.8s,", sp->s_name);
868: boffs += 1;
869: }
870: /* The last entry is m_jmp or a m_newl */
871: if (macv[i] == m_jmp) {
872: if (jto < 256) {
873: fprintf(mfp, "\tM_JMP1, %s,\t\t", t1);
874: boffs += 2;
875: } else if ((jfrom-jto) < 256) {
876: fprintf(mfp, "\tM_JMPB, %s,\t\t", t1);
877: boffs += 2;
878: } else {
879: fprintf(mfp, "\tM_JMP2, %s, %s,\t", t1, t2);
880: boffs += 3;
881: }
882: /* Identify the destination */
883: fprintf(mfp, "/* %d */\n", jto);
884: } else
885: putc('\n', mfp);
886: bsave += sboffs - boffs;
887: }
888:
889: getnb()
890: {
891: register int c;
892:
893: while ((c=get())==' ' || c=='\t' || c=='\n')
894: ;
895: return (c);
896: }
897:
898: get()
899: {
900: register char *p1;
901: register char *p2;
902: register int c;
903: register int hitslash;
904: register int isdef;
905: register int i;
906:
907: if ((c=ungetc) >= 0) {
908: ungetc = -1;
909: return (c);
910: }
911: if (hiteof != 0)
912: return (EOF);
913: while (getnc == 0) {
914: p1 = &getbuf[0];
915: hitslash = 0;
916: while ((c=getc(ifp))!=EOF && c!='\n') {
917: if (hitslash == 0) {
918: if (c == '/')
919: hitslash = 1;
920: else
921: *p1++ = c;
922: }
923: }
924: if (c == EOF) {
925: hiteof = 1;
926: return (EOF);
927: }
928: *p1++ = '\n';
929: ++lineno;
930: if (getbuf[0] == '#') {
931: static char endif[] = "endif";
932: static char ifdef[] = "ifdef";
933: static char ifndef[] = "ifndef";
934:
935: p2 = &getbuf[1];
936: if (match(p2, endif)) {
937: if (tlevel != 0)
938: --tlevel;
939: else if (flevel != 0)
940: --flevel;
941: else
942: fatal(endif);
943: if ((tlevel+flevel) == 0)
944: fprintf(pfp, "\n/* #%s */", endif);
945: continue;
946: }
947: if (match(p2, ifdef) || match(p2, ifndef)) {
948: if (flevel != 0) {
949: ++flevel;
950: continue;
951: }
952: while ((c = *p2)!=' ' && c!='\t' && c!='\n')
953: ++p2;
954: while ((c = *p2)==' ' || c=='\t')
955: ++p2;
956: if (c == '\n')
957: fatal("if name");
958: p1 = p2;
959: while (*p2!=' ' && *p2!='\t' && *p2!='\n')
960: ++p2;
961: *p2 = 0;
962: isdef = 0;
963: for (i=0; i<ndef; ++i) {
964: if (strcmp(def[i], p1) == 0) {
965: isdef = 1;
966: break;
967: }
968: }
969: if (getbuf[3] == 'n') /* #ifndef */
970: isdef = !isdef;
971: if (isdef != 0)
972: ++tlevel;
973: else
974: ++flevel;
975: fprintf(pfp, "\n/* %s */", getbuf);
976: continue;
977: }
978: if (flevel == 0) {
979: p2 = &getbuf[0];
980: while (p2 < p1)
981: putc(*p2++, pfp);
982: }
983: continue;
984: }
985: if (flevel == 0) {
986: getnc = p1 - &getbuf[0];
987: getcp = &getbuf[0];
988: }
989: }
990: --getnc;
991: return (*getcp++);
992: }
993:
994: unget(c)
995: {
996: ungetc = c;
997: }
998:
999: getid(c, id)
1000: register c;
1001: char id[];
1002: {
1003: register char *p;
1004:
1005: if (!isalpha(c) && c != '_')
1006: fatal("missing identifier");
1007: p = id;
1008: do {
1009: if (p < &id[NCPS])
1010: *p++ = c;
1011: c = get();
1012: } while (isalnum(c));
1013: while (p < &id[NCPS])
1014: *p++ = 0;
1015: unget(c);
1016: }
1017:
1018: fatal(s)
1019: char *s;
1020: {
1021: fprintf(stderr, "%s: %d: %s\n", fname, lineno, s);
1022: exit(ABORT);
1023: }
1024:
1025: opindex()
1026: {
1027: register struct optable *opp;
1028:
1029: fprintf(pfp, "PATX patx[] = {\n");
1030: opp = &optable[0];
1031: while (opp < &optable[nel(optable)]) {
1032: fprintf(pfp, "\t");
1033: if (opp->o_seq == 0)
1034: fprintf(pfp, "NULL,\t0");
1035: else
1036: fprintf(pfp, "p%d,\t%d", opp->o_seq, opp->o_npat);
1037: if (opp != &optable[nel(optable)-1])
1038: putc(',', pfp);
1039: putc('\n', pfp);
1040: ++opp;
1041: }
1042: fprintf(pfp, "};\n");
1043: }
1044:
1045: match(p1, p2)
1046: register char *p1;
1047: register char *p2;
1048: {
1049: register int c;
1050:
1051: while ((c = *p2++) != 0) {
1052: if (*p1++ != c)
1053: return (0);
1054: }
1055: return (1);
1056: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.