3 * 2.1 (2.11BSD) 1996/01/04
6 * c0 source temp1 temp2 [ profileflag ]
7 * temp1 gets most of the intermediate code;
8 * strings are put on temp2, which c1 reads after temp1.
16 #include "c1.h" /* for isn1 since want to keep float labels the same */
21 struct locnnode funcblk = { { { NAME, 0, (int *)NULL, (union str *)NULL }, (struct nmlist *)NULL, 0/*nn_class*/, 0/*nn_regno*/, 0/*nn_offset*/}, 0/*locnn_nloc*/ };
23 struct kwtab kwtab[] = {
57 struct node *cmst[CMSIZ];
58 struct node **cp = cmst;
61 int main(argc, argv) int argc; char *argv[]; {
63 register struct kwtab *ip;
67 if (argc>1 && strcmp(argv[1], "-u")==0) {
76 if (freopen(argv[1], "r", stdin)==NULL) {
77 error0("Can't find %s", argv[1]);
80 setbuf(stdin,buf1); /* stdio sbrk problems */
81 if (freopen(argv[2], "w", stdout)==NULL || (sbufp=fopen(argv[3],"w"))==NULL) {
82 error0("Can't create temp");
85 setbuf(stdout,buf2); /* stdio sbrk problems */
88 * Overlays: allow an extra word on the stack for
89 * each stack from to store the overlay number.
97 case 'V': /* overlays; default, now */
100 case 'W': /* don't print warning messages */
107 * The hash table locations of the keywords
108 * are marked; if an identifier hashes to one of
109 * these locations, it is looked up in in the keyword
112 for (ip=kwtab; ip->kwname; ip++) {
113 i = hash(ip->kwname);
114 kwhash[i/LNBPW] |= 1 << (i%LNBPW);
116 coremax = locbase = sbrk(0);
128 * Look up the identifier in symbuf in the symbol table.
129 * If it hashes to the same spot as a keyword, try the keyword table
131 * Return is a ptr to the symbol table entry.
135 register struct nmlist *rp;
137 ihash = hash(symbuf);
138 if (kwhash[ihash/LNBPW] & (1 << (ihash%LNBPW)))
143 if (strcmp(symbuf, rp->nl_name) != 0)
145 if (mossym != (rp->nl_flag&FKIND))
152 rp = (struct nmlist *)Dblock(sizeof(struct nmlist));
153 rp->nl_nextnm = hshtab[ihash];
156 /* rp->nl_type = 0;*/
158 /* rp->nl_subsp = NULL;
159 rp->nl_strp = NULL;*/
161 rp->nl_sparent = NULL;
162 rp->nl_blklev = blklev;
163 rp->nl_flag = mossym;
164 rp->nl_name = Dblock((strlen(symbuf) + 1 + LNCPW - 1) & ~(LNCPW - 1));
165 strcpy(rp->nl_name, symbuf);
171 * Search the keyword table.
174 register struct kwtab *kp;
176 for (kp=kwtab; kp->kwname; kp++) {
177 if (strcmp(symbuf, kp->kwname) == 0) {
187 * Return the next symbol from the input.
188 * peeksym is a pushed-back symbol, peekc is a pushed-back
189 * character (after peeksym).
190 * mosflg means that the next symbol, if an identifier,
191 * is a member of structure or a structure tag or an enum tag
221 if ((c=symbol())!=CON) {
226 while (ctab[peekc]==SPACE)
230 while (sp < filename + MAXPATHLEN - 1 && (c = mapch('"')) >= 0) /* Nick */
237 while (getchar()!='\n' && eof==0)
252 return(subseq(c,PLUS,INCBEF));
257 return(subseq('>', MINUS, ARROW));
260 return(subseq(c, ASSIGN, EQUAL));
265 return(subseq('=',LESS,LESSEQ));
270 return(subseq('=',GREAT,GREATEQ));
273 return(subseq('=',EXCLA,NEQUAL));
276 if (subseq('/', 0, 1))
281 if (subseq('\\', 0, 1))
285 while ((c = spnextchar()) != EOFC) {
288 if (spnextchar() == '/') {
296 error0("Nonterminated comment");
313 while (ctab[c]==LETTER || ctab[c]==DIGIT) {
314 if (sp < symbuf + MAXCPS)
322 if ((c=lookup())==KEYW && cval==SIZEOF)
327 return(subseq('&', AND, LOGAND));
330 return(subseq('|', OR, LOGOR));
334 error0("Unknown character");
343 * Read a number. Return kind.
347 register int c, base;
348 int expseen, sym, ndigit;
352 nsyn = "Number syntax";
360 if ((c=spnextchar()) == '0')
362 for (;; c = getchar()) {
364 if (ctab[c]==DIGIT || (base==16) && ('a'<=c&&c<='f'||'A'<=c&&c<='F')) {
368 lcval = ((lcval<<2) + lcval)<<1;
384 if (base==16 || sym==FCON)
394 if ((c=='e'||c=='E') && expseen==0) {
397 if (base==16 || maxdigit>=10)
400 *np++ = c = getchar();
401 if (c!='+' && c!='-' && ctab[c]!=DIGIT)
403 } else if (c=='x' || c=='X') {
404 if (base!=8 || lcval!=0 || sym!=CON)
407 } else if ((c=='l' || c=='L') && sym==CON) {
415 if (maxdigit >= base)
419 /* cval = np-numbuf;*/
421 fcval = atof(numbuf);
423 fcval = fp_atof(numbuf);
427 if (sym==CON && (lcval<0 || lcval>MAXINT&&base==10 || (lcval>>1)>MAXINT)) {
435 * If the next input character is c, return b and advance.
436 * Otherwise push back the character and return a.
438 int subseq(c, a, b) int c; int a; int b; {
439 if (spnextchar() != c)
446 * Write out a string, either in-line
447 * or in the string temp file labelled by
450 void putstr(lab, max) int lab; register int max; {
451 static char def_prefix[] = "\n.byte ";
452 static char com_prefix[] = ",";
453 char *prefix = def_prefix + 1;
463 outcode("BN", LABEL, lab);
466 /* outcode("B", BDATA);*/
467 while ((c = mapch('"')) >= 0) {
471 /* outcode("0B", BDATA);*/
474 /* outcode("1N", c & 0377);*/
475 fprintf(temp_fp[temp_fi], "%s%o", prefix, c & 0377);
482 fprintf(temp_fp[temp_fi], "%s0", prefix);
486 if (prefix == com_prefix)
487 fputc('\n', temp_fp[temp_fi]);
499 while ((c = mapch('"')) >= 0) {
505 * read a single-quoted character constant.
506 * The routine is sensitive to the layout of
507 * characters in a word.
525 while((c=mapch('\'')) >= 0)
530 cval |= (c & 0377) << shift;
535 error0("Long character constant");
541 /* we default to signed char */
550 * Read a character in a string or character constant,
551 * detecting the end of the string.
552 * It implements the escape sequences.
554 int mapch(ac) int ac; {
555 register int a, c, n;
570 error0("Nonterminated string");
575 switch (a=getchar()) {
592 case '0': case '1': case '2': case '3':
593 case '4': case '5': case '6': case '7':
596 while (++c<=3 && '0'<=a && a<='7') {
617 * Read an expression and return a pointer to its tree.
618 * It's the classical bottom-up, priority-driven scheme.
619 * The initflg prevents the parse from going past
620 * "," or ":" because those delimiters are special
621 * in initializer (and some other) expressions.
623 struct node *tree(/*eflag*/) /*int eflag;*/ {
624 int *op, opst[SSIZE], *pp, prst[SSIZE];
625 register int andflg, o;
626 register struct nmlist *cs;
627 int p, ps, os, xo = 0, *xop;
629 static struct cnode garbage = { { CON, INT, (int *)NULL, (union str *)NULL}, 0 };
630 static struct type t_int = {INT};
631 static struct ftype t_func_int = {{{FUNC}, &t_int}, (struct nmlist **)NULL};
632 static struct type t_char = {CHAR};
633 static struct type t_unchar = {UNCHAR};
635 /*svtree = starttree();*/
643 switch (o=symbol()) {
647 if (cs->nl_class==TYPEDEF)
649 if (cs->nl_class==ENUMCON) {
650 *cp++ = (struct node *)cblock(cs->nl_offset);
653 if (cs->nl_class==0 && /*cs->nl_type==0*/cs->nl_dtype==NULL)
654 if(nextchar()=='(') {
656 cs->nl_class = EXTERN;
657 /* cs->nl_type = FUNC;*/
658 cs->nl_dtype = (struct type *)&t_func_int;
660 cs->nl_class = STATIC;
661 error0("%s undefined; func. %s", cs->nl_name,
662 funcsym ? funcsym->nl_name : "(none)");
664 *cp++ = (struct node *)nblock(cs);
668 /* *cp++ = fblock(DOUBLE, copnum(cval));*/
669 *cp++ = (struct node *)fblock(isn1++, fcval);
673 #if 1 /* one-pass version */
674 if (lcval >= -0x8000L && lcval < 0x8000L) {
675 *cp++ = (struct node *)cblock((_INT)lcval);
676 cp[-1] = (struct node *)block(ITOL, LONG, (int *)NULL, (union str *)NULL, cp[-1], (struct node *)NULL);
680 *cp++ = (struct node *)lblock(lcval);
684 *cp++ = (struct node *)cblock(cval);
687 /* fake a static char array */
690 * This hack is to compensate for a bit of simplemindedness I'm not sure how
693 * i = sizeof ("foobar");
696 * i = sizeof "foobar";
698 * would generate ".byte 'f,'o','o,'b,'a,'r,0" into the data segment!
700 * What I did here was to scan to "operator" stack looking for left parens
701 * "(" preceeded by a "sizeof". If both are seen and in that order or only
702 * a SIZEOF is sedn then the string is inside a 'sizeof' and should not
703 * generate any data to the object file.
716 cs = (struct nmlist *)Tblock(sizeof(struct nmlist));
717 cs->nl_class = STATIC;
718 /* cs->nl_offset = cval;
719 *cp++ = block(NAME, unscflg? ARRAY+UNCHAR:ARRAY+CHAR, &nchstr,
720 (union str *)NULL, (struct node *)cs, (struct node *)NULL);*/
722 /* cs->nl_type = unscflg? ARRAY+UNCHAR:ARRAY+CHAR;
723 cs->nl_subsp = &nchstr;
724 cs->nl_strp = (union str *)NULL;*/
725 cs->nl_dtype = (struct type *)Tblock(sizeof(struct atype));
726 ((struct atype *)cs->nl_dtype)->at_id = REF | ARRAY;
727 ((struct atype *)cs->nl_dtype)->at_reftype = unscflg ? &t_unchar : &t_char;
728 ((struct atype *)cs->nl_dtype)->at_nelt = nchstr;
729 cs->nl_offset = cval;
733 cs->nl_name = /*0*/"<string>";
734 *cp++ = (struct node *)nblock(cs);
738 error0("Expression overflow");
748 if (*op != LPARN || andflg)
751 *cp++ = (struct node *)xprtype();
752 if ((o=symbol()) != RPARN)
818 if (andflg==0 && PLUS<=*op && *op<=EXOR) {
819 o = *op-- + ASPLUS - PLUS;
832 p = (opdope0[o]>>9) & 037;
834 if (o==COLON && op[0]==COLON && op[-1]==QUEST) {
840 if (p>ps || p==ps && (opdope0[o]&RASSOC)!=0) {
853 if ((o==COMMA && *op!=LPARN && *op!=CALL)
854 || (o==COLON && *op!=QUEST)) {
859 if (op >= &opst[SSIZE-1]) {
860 error0("expression overflow");
869 if (andflg==0 && p>5 && ((opdope0[o]&BINARY)==0 || o>=INCBEF&&o<=DECAFT) && opdope0[os]&BINARY)
875 build(0); /* flush conversions */
892 *cp++ = (struct node *)block(NULLOP0, INT, (int *)NULL,
893 (union str *)NULL, (struct node *)NULL, (struct node *)NULL);
901 *cp++ = (struct node *)cblock(1);
919 error0("Expression syntax");
923 return((struct node *) &garbage);
926 struct tnode *xprtype() {
927 struct nmlist /*typer,*/ absname;
929 register struct node **scp;
931 static struct type t_int = {INT};
938 sc = DEFXTRN; /* will cause error if class mentioned */
939 /* getkeywords(&sc, &typer);*/
940 dtype = getkeywords(&sc);
943 absname.nl_class = 0;
944 absname.nl_blklev = blklev;
945 /* absname.nl_subsp = NULL;
946 absname.nl_strp = NULL;
947 absname.nl_type = 0;*/
948 absname.nl_dtype = NULL;
949 absname.nl_name = "<anon>";
950 decl1(sc, /*&typer*/dtype, 0, &absname);
953 type = XXXoldtype(absname.nl_dtype, &dim, (struct SS **)&strp);
954 subsp = dim.rank ? (int *)Tblock(dim.rank*sizeof(dim.rank)) : NULL;
955 for (a=0; a<dim.rank; a++)
956 subsp[a] = dim.dimens[a];
957 return(block(ETYPE, /*absname.nl_*/type, /*absname.nl_*/subsp,
958 /*absname.nl_*/strp, (struct node *)NULL, (struct node *)NULL));
961 /*char *copnum(len) int len; {
964 s1 = Tblock((len+LNCPW-1) & ~(LNCPW-1));