|
|
1.1 ! root 1: /* C compiler ! 2: * ! 3: * ! 4: * ! 5: * Called from cc: ! 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. ! 9: */ ! 10: ! 11: #include "c0.h" ! 12: ! 13: int isn = 1; ! 14: int peeksym = -1; ! 15: int line = 1; ! 16: struct tnode funcblk = { NAME }; ! 17: ! 18: struct kwtab { ! 19: char *kwname; ! 20: int kwval; ! 21: } kwtab[] = { ! 22: "int", INT, ! 23: "char", CHAR, ! 24: "float", FLOAT, ! 25: "double", DOUBLE, ! 26: "struct", STRUCT, ! 27: "long", LONG, ! 28: "unsigned", UNSIGN, ! 29: "union", UNION, ! 30: "short", INT, ! 31: "void", VOID, ! 32: "auto", AUTO, ! 33: "extern", EXTERN, ! 34: "static", STATIC, ! 35: "register", REG, ! 36: "goto", GOTO, ! 37: "return", RETURN, ! 38: "if", IF, ! 39: "while", WHILE, ! 40: "else", ELSE, ! 41: "switch", SWITCH, ! 42: "case", CASE, ! 43: "break", BREAK, ! 44: "continue", CONTIN, ! 45: "do", DO, ! 46: "default", DEFAULT, ! 47: "for", FOR, ! 48: "sizeof", SIZEOF, ! 49: "typedef", TYPEDEF, ! 50: "enum", ENUM, ! 51: 0, 0, ! 52: }; ! 53: ! 54: union tree *cmst[CMSIZ]; ! 55: union tree **cp = cmst; ! 56: ! 57: main(argc, argv) ! 58: char *argv[]; ! 59: { ! 60: register unsigned i; ! 61: register struct kwtab *ip; ! 62: ! 63: if (argc>1 && strcmp(argv[1], "-u")==0) { ! 64: argc--; ! 65: argv++; ! 66: unscflg++; ! 67: } ! 68: if(argc<4) { ! 69: error("Arg count"); ! 70: exit(1); ! 71: } ! 72: if (freopen(argv[1], "r", stdin)==NULL) { ! 73: error("Can't find %s", argv[1]); ! 74: exit(1); ! 75: } ! 76: if (freopen(argv[2], "w", stdout)==NULL || (sbufp=fopen(argv[3],"w"))==NULL) { ! 77: error("Can't create temp"); ! 78: exit(1); ! 79: } ! 80: setbuf(sbufp, sbuf); ! 81: if (argc>4) ! 82: proflg++; ! 83: /* ! 84: * The hash table locations of the keywords ! 85: * are marked; if an identifier hashes to one of ! 86: * these locations, it is looked up in in the keyword ! 87: * table first. ! 88: */ ! 89: for (ip=kwtab; ip->kwname; ip++) { ! 90: i = hash(ip->kwname); ! 91: kwhash[i/LNBPW] |= 1 << (i%LNBPW); ! 92: } ! 93: coremax = locbase = sbrk(0); ! 94: while(!eof) ! 95: extdef(); ! 96: outcode("B", EOFC); ! 97: strflg++; ! 98: outcode("B", EOFC); ! 99: blkend(); ! 100: exit(nerror!=0); ! 101: } ! 102: ! 103: /* ! 104: * Look up the identifier in symbuf in the symbol table. ! 105: * If it hashes to the same spot as a keyword, try the keyword table ! 106: * first. ! 107: * Return is a ptr to the symbol table entry. ! 108: */ ! 109: lookup() ! 110: { ! 111: unsigned ihash; ! 112: register struct nmlist *rp; ! 113: register char *sp, *np; ! 114: ! 115: ihash = hash(symbuf); ! 116: if (kwhash[ihash/LNBPW] & (1 << (ihash%LNBPW))) ! 117: if (findkw()) ! 118: return(KEYW); ! 119: rp = hshtab[ihash]; ! 120: while (rp) { ! 121: np = rp->name; ! 122: for (sp=symbuf; sp<symbuf+NCPS;) ! 123: if (*np++ != *sp++) ! 124: goto no; ! 125: if (mossym != (rp->hflag&FKIND)) ! 126: goto no; ! 127: csym = rp; ! 128: return(NAME); ! 129: no: ! 130: rp = rp->nextnm; ! 131: } ! 132: rp = (struct nmlist *)Dblock(sizeof(struct nmlist)); ! 133: rp->nextnm = hshtab[ihash]; ! 134: hshtab[ihash] = rp; ! 135: rp->hclass = 0; ! 136: rp->htype = 0; ! 137: rp->hoffset = 0; ! 138: rp->hsubsp = NULL; ! 139: rp->hstrp = NULL; ! 140: rp->sparent = NULL; ! 141: rp->hblklev = blklev; ! 142: rp->hflag = mossym; ! 143: sp = symbuf; ! 144: for (np=rp->name; sp<symbuf+NCPS;) ! 145: *np++ = *sp++; ! 146: csym = rp; ! 147: return(NAME); ! 148: } ! 149: ! 150: /* ! 151: * Search the keyword table. ! 152: */ ! 153: findkw() ! 154: { ! 155: register struct kwtab *kp; ! 156: register char *p1, *p2; ! 157: char *wp; ! 158: int firstc; ! 159: ! 160: wp = symbuf; ! 161: firstc = *wp; ! 162: for (kp=kwtab; (p2 = kp->kwname); kp++) { ! 163: p1 = wp; ! 164: while (*p1 == *p2++) ! 165: if (*p1++ == '\0') { ! 166: cval = kp->kwval; ! 167: return(1); ! 168: } ! 169: } ! 170: *wp = firstc; ! 171: return(0); ! 172: } ! 173: ! 174: ! 175: /* ! 176: * Return the next symbol from the input. ! 177: * peeksym is a pushed-back symbol, peekc is a pushed-back ! 178: * character (after peeksym). ! 179: * mosflg means that the next symbol, if an identifier, ! 180: * is a member of structure or a structure tag or an enum tag ! 181: */ ! 182: symbol() ! 183: { ! 184: register c; ! 185: register char *sp; ! 186: register tline; ! 187: ! 188: if (peeksym>=0) { ! 189: c = peeksym; ! 190: peeksym = -1; ! 191: if (c==NAME) ! 192: mosflg = 0; ! 193: return(c); ! 194: } ! 195: if (peekc) { ! 196: c = peekc; ! 197: peekc = 0; ! 198: } else ! 199: if (eof) ! 200: return(EOFC); ! 201: else ! 202: c = getchar(); ! 203: loop: ! 204: if (c==EOF) { ! 205: eof++; ! 206: return(EOFC); ! 207: } ! 208: switch(ctab[c]) { ! 209: ! 210: case SHARP: ! 211: if ((c=symbol())!=CON) { ! 212: error("Illegal #"); ! 213: return(c); ! 214: } ! 215: tline = cval; ! 216: while (ctab[peekc]==SPACE) ! 217: peekc = getchar(); ! 218: if (peekc=='"') { ! 219: sp = filename; ! 220: while ((c = mapch('"')) >= 0) ! 221: *sp++ = c; ! 222: *sp++ = 0; ! 223: peekc = getchar(); ! 224: } ! 225: if (peekc != '\n') { ! 226: error("Illegal #"); ! 227: while (getchar()!='\n' && eof==0) ! 228: ; ! 229: } ! 230: peekc = 0; ! 231: line = tline; ! 232: return(symbol()); ! 233: ! 234: case NEWLN: ! 235: line++; ! 236: ! 237: case SPACE: ! 238: c = getchar(); ! 239: goto loop; ! 240: ! 241: case PLUS: ! 242: return(subseq(c,PLUS,INCBEF)); ! 243: ! 244: case MINUS: ! 245: if (subseq(c, 0, 1)) ! 246: return(DECBEF); ! 247: return(subseq('>', MINUS, ARROW)); ! 248: ! 249: case ASSIGN: ! 250: return(subseq(c, ASSIGN, EQUAL)); ! 251: ! 252: case LESS: ! 253: if (subseq(c,0,1)) ! 254: return(LSHIFT); ! 255: return(subseq('=',LESS,LESSEQ)); ! 256: ! 257: case GREAT: ! 258: if (subseq(c,0,1)) ! 259: return(RSHIFT); ! 260: return(subseq('=',GREAT,GREATEQ)); ! 261: ! 262: case EXCLA: ! 263: return(subseq('=',EXCLA,NEQUAL)); ! 264: ! 265: case BSLASH: ! 266: if (subseq('/', 0, 1)) ! 267: return(MAX); ! 268: goto unkn; ! 269: ! 270: case DIVIDE: ! 271: if (subseq('\\', 0, 1)) ! 272: return(MIN); ! 273: if (subseq('*',1,0)) ! 274: return(DIVIDE); ! 275: while ((c = spnextchar()) != EOFC) { ! 276: peekc = 0; ! 277: if (c=='*') { ! 278: if (spnextchar() == '/') { ! 279: peekc = 0; ! 280: c = getchar(); ! 281: goto loop; ! 282: } ! 283: } ! 284: } ! 285: eof++; ! 286: error("Nonterminated comment"); ! 287: return(0); ! 288: ! 289: case PERIOD: ! 290: case DIGIT: ! 291: peekc = c; ! 292: return(getnum()); ! 293: ! 294: case DQUOTE: ! 295: cval = isn++; ! 296: return(STRING); ! 297: ! 298: case SQUOTE: ! 299: return(getcc()); ! 300: ! 301: case LETTER: ! 302: sp = symbuf; ! 303: while(ctab[c]==LETTER || ctab[c]==DIGIT) { ! 304: if (sp<symbuf+NCPS) ! 305: *sp++ = c; ! 306: c = getchar(); ! 307: } ! 308: while(sp<symbuf+NCPS) ! 309: *sp++ = '\0'; ! 310: mossym = mosflg; ! 311: mosflg = 0; ! 312: peekc = c; ! 313: if ((c=lookup())==KEYW && cval==SIZEOF) ! 314: c = SIZEOF; ! 315: return(c); ! 316: ! 317: case AND: ! 318: return(subseq('&', AND, LOGAND)); ! 319: ! 320: case OR: ! 321: return(subseq('|', OR, LOGOR)); ! 322: ! 323: case UNKN: ! 324: unkn: ! 325: error("Unknown character"); ! 326: c = getchar(); ! 327: goto loop; ! 328: ! 329: } ! 330: return(ctab[c]); ! 331: } ! 332: ! 333: /* ! 334: * Read a number. Return kind. ! 335: */ ! 336: getnum() ! 337: { ! 338: register char *np; ! 339: register c, base; ! 340: int expseen, sym, ndigit; ! 341: char *nsyn; ! 342: int maxdigit; ! 343: ! 344: nsyn = "Number syntax"; ! 345: lcval = 0; ! 346: base = 10; ! 347: maxdigit = 0; ! 348: np = numbuf; ! 349: ndigit = 0; ! 350: sym = CON; ! 351: expseen = 0; ! 352: if ((c=spnextchar()) == '0') ! 353: base = 8; ! 354: for (;; c = getchar()) { ! 355: *np++ = c; ! 356: if (ctab[c]==DIGIT || (base==16) && ('a'<=c&&c<='f'||'A'<=c&&c<='F')) { ! 357: if (base==8) ! 358: lcval <<= 3; ! 359: else if (base==10) ! 360: lcval = ((lcval<<2) + lcval)<<1; ! 361: else ! 362: lcval <<= 4; ! 363: if (ctab[c]==DIGIT) ! 364: c -= '0'; ! 365: else if (c>='a') ! 366: c -= 'a'-10; ! 367: else ! 368: c -= 'A'-10; ! 369: lcval += c; ! 370: ndigit++; ! 371: if (c>maxdigit) ! 372: maxdigit = c; ! 373: continue; ! 374: } ! 375: if (c=='.') { ! 376: if (base==16 || sym==FCON) ! 377: error(nsyn); ! 378: sym = FCON; ! 379: base = 10; ! 380: continue; ! 381: } ! 382: if (ndigit==0) { ! 383: sym = DOT; ! 384: break; ! 385: } ! 386: if ((c=='e'||c=='E') && expseen==0) { ! 387: expseen++; ! 388: sym = FCON; ! 389: if (base==16 || maxdigit>=10) ! 390: error(nsyn); ! 391: base = 10; ! 392: *np++ = c = getchar(); ! 393: if (c!='+' && c!='-' && ctab[c]!=DIGIT) ! 394: break; ! 395: } else if (c=='x' || c=='X') { ! 396: if (base!=8 || lcval!=0 || sym!=CON) ! 397: error(nsyn); ! 398: base = 16; ! 399: } else if ((c=='l' || c=='L') && sym==CON) { ! 400: c = getchar(); ! 401: sym = LCON; ! 402: break; ! 403: } else ! 404: break; ! 405: } ! 406: peekc = c; ! 407: if (maxdigit >= base) ! 408: error(nsyn); ! 409: if (sym==FCON) { ! 410: np[-1] = 0; ! 411: cval = np-numbuf; ! 412: return(FCON); ! 413: } ! 414: if (sym==CON && (lcval<0 || lcval>MAXINT&&base==10 || (lcval>>1)>MAXINT)) { ! 415: sym = LCON; ! 416: } ! 417: cval = lcval; ! 418: return(sym); ! 419: } ! 420: ! 421: /* ! 422: * If the next input character is c, return b and advance. ! 423: * Otherwise push back the character and return a. ! 424: */ ! 425: subseq(c,a,b) ! 426: { ! 427: if (spnextchar() != c) ! 428: return(a); ! 429: peekc = 0; ! 430: return(b); ! 431: } ! 432: ! 433: /* ! 434: * Write out a string, either in-line ! 435: * or in the string temp file labelled by ! 436: * lab. ! 437: */ ! 438: putstr(lab, max) ! 439: register max; ! 440: { ! 441: register int c; ! 442: ! 443: nchstr = 0; ! 444: if (lab) { ! 445: strflg++; ! 446: outcode("BNB", LABEL, lab, BDATA); ! 447: max = 10000; ! 448: } else ! 449: outcode("B", BDATA); ! 450: while ((c = mapch('"')) >= 0) { ! 451: if (nchstr < max) { ! 452: nchstr++; ! 453: if (nchstr%15 == 0) ! 454: outcode("0B", BDATA); ! 455: outcode("1N", c & 0377); ! 456: } ! 457: } ! 458: if (nchstr < max) { ! 459: nchstr++; ! 460: outcode("10"); ! 461: } ! 462: outcode("0"); ! 463: strflg = 0; ! 464: } ! 465: ! 466: /* ! 467: * read a single-quoted character constant. ! 468: * The routine is sensitive to the layout of ! 469: * characters in a word. ! 470: */ ! 471: getcc() ! 472: { ! 473: register int c, cc; ! 474: register char *ccp; ! 475: char realc; ! 476: ! 477: cval = 0; ! 478: ccp = (char *)&cval; ! 479: cc = 0; ! 480: while((c=mapch('\'')) >= 0) ! 481: if(cc++ < LNCPW) ! 482: *ccp++ = c; ! 483: if (cc>LNCPW) ! 484: error("Long character constant"); ! 485: if (cc==1) { ! 486: realc = cval; ! 487: cval = realc; ! 488: } ! 489: return(CON); ! 490: } ! 491: ! 492: /* ! 493: * Read a character in a string or character constant, ! 494: * detecting the end of the string. ! 495: * It implements the escape sequences. ! 496: */ ! 497: mapch(ac) ! 498: { ! 499: register int a, c, n; ! 500: static mpeek; ! 501: ! 502: c = ac; ! 503: if (a = mpeek) ! 504: mpeek = 0; ! 505: else ! 506: a = getchar(); ! 507: loop: ! 508: if (a==c) ! 509: return(-1); ! 510: switch(a) { ! 511: ! 512: case '\n': ! 513: case '\0': ! 514: error("Nonterminated string"); ! 515: peekc = a; ! 516: return(-1); ! 517: ! 518: case '\\': ! 519: switch (a=getchar()) { ! 520: ! 521: case 't': ! 522: return('\t'); ! 523: ! 524: case 'n': ! 525: return('\n'); ! 526: ! 527: case 'b': ! 528: return('\b'); ! 529: ! 530: case 'f': ! 531: return('\014'); ! 532: ! 533: case 'v': ! 534: return('\013'); ! 535: ! 536: case '0': case '1': case '2': case '3': ! 537: case '4': case '5': case '6': case '7': ! 538: n = 0; ! 539: c = 0; ! 540: while (++c<=3 && '0'<=a && a<='7') { ! 541: n <<= 3; ! 542: n += a-'0'; ! 543: a = getchar(); ! 544: } ! 545: mpeek = a; ! 546: return(n); ! 547: ! 548: case 'r': ! 549: return('\r'); ! 550: ! 551: case '\n': ! 552: line++; ! 553: a = getchar(); ! 554: goto loop; ! 555: } ! 556: } ! 557: return(a); ! 558: } ! 559: ! 560: /* ! 561: * Read an expression and return a pointer to its tree. ! 562: * It's the classical bottom-up, priority-driven scheme. ! 563: * The initflg prevents the parse from going past ! 564: * "," or ":" because those delimiters are special ! 565: * in initializer (and some other) expressions. ! 566: */ ! 567: union tree * ! 568: tree(eflag) ! 569: { ! 570: int *op, opst[SSIZE], *pp, prst[SSIZE]; ! 571: register int andflg, o; ! 572: register struct nmlist *cs; ! 573: int p, ps, os; ! 574: char *svtree; ! 575: static struct cnode garbage = { CON, INT, (int *)NULL, (union str *)NULL, 0 }; ! 576: ! 577: svtree = starttree(); ! 578: op = opst; ! 579: pp = prst; ! 580: *op = SEOF; ! 581: *pp = 06; ! 582: andflg = 0; ! 583: ! 584: advanc: ! 585: switch (o=symbol()) { ! 586: ! 587: case NAME: ! 588: cs = csym; ! 589: if (cs->hclass==TYPEDEF) ! 590: goto atype; ! 591: if (cs->hclass==ENUMCON) { ! 592: *cp++ = cblock(cs->hoffset); ! 593: goto tand; ! 594: } ! 595: if (cs->hclass==0 && cs->htype==0) ! 596: if(nextchar()=='(') { ! 597: /* set function */ ! 598: cs->hclass = EXTERN; ! 599: cs->htype = FUNC; ! 600: } else { ! 601: cs->hclass = STATIC; ! 602: error("%.8s undefined; func. %.8s", cs->name, ! 603: funcsym?funcsym->name:"(none)"); ! 604: } ! 605: *cp++ = nblock(cs); ! 606: goto tand; ! 607: ! 608: case FCON: ! 609: *cp++ = fblock(DOUBLE, copnum(cval)); ! 610: goto tand; ! 611: ! 612: case LCON: ! 613: *cp = (union tree *)Tblock(sizeof(struct lnode)); ! 614: (*cp)->l.op = LCON; ! 615: (*cp)->l.type = LONG; ! 616: (*cp)->l.lvalue = lcval; ! 617: cp++; ! 618: goto tand; ! 619: ! 620: case CON: ! 621: *cp++ = cblock(cval); ! 622: goto tand; ! 623: ! 624: /* fake a static char array */ ! 625: case STRING: ! 626: putstr(cval, 0); ! 627: cs = (struct nmlist *)Tblock(sizeof(struct nmlist)); ! 628: cs->hclass = STATIC; ! 629: cs->hoffset = cval; ! 630: *cp++ = block(NAME, unscflg? ARRAY+UNCHAR:ARRAY+CHAR, &nchstr, ! 631: (union str *)NULL, (union tree *)cs, TNULL); ! 632: ! 633: tand: ! 634: if(cp>=cmst+CMSIZ) { ! 635: error("Expression overflow"); ! 636: exit(1); ! 637: } ! 638: if (andflg) ! 639: goto syntax; ! 640: andflg = 1; ! 641: goto advanc; ! 642: ! 643: case KEYW: ! 644: atype: ! 645: if (*op != LPARN || andflg) ! 646: goto syntax; ! 647: peeksym = o; ! 648: *cp++ = xprtype(); ! 649: if ((o=symbol()) != RPARN) ! 650: goto syntax; ! 651: o = CAST; ! 652: --op; ! 653: --pp; ! 654: if (*op == SIZEOF) { ! 655: andflg = 1; ! 656: *pp = 100; ! 657: goto advanc; ! 658: } ! 659: goto oponst; ! 660: ! 661: case INCBEF: ! 662: case DECBEF: ! 663: if (andflg) ! 664: o += 2; ! 665: goto oponst; ! 666: ! 667: case COMPL: ! 668: case EXCLA: ! 669: case SIZEOF: ! 670: if (andflg) ! 671: goto syntax; ! 672: goto oponst; ! 673: ! 674: case MINUS: ! 675: if (!andflg) ! 676: o = NEG; ! 677: andflg = 0; ! 678: goto oponst; ! 679: ! 680: case AND: ! 681: case TIMES: ! 682: if (andflg) ! 683: andflg = 0; ! 684: else if (o==AND) ! 685: o = AMPER; ! 686: else ! 687: o = STAR; ! 688: goto oponst; ! 689: ! 690: case LPARN: ! 691: if (andflg) { ! 692: o = symbol(); ! 693: if (o==RPARN) ! 694: o = MCALL; ! 695: else { ! 696: peeksym = o; ! 697: o = CALL; ! 698: andflg = 0; ! 699: } ! 700: } ! 701: goto oponst; ! 702: ! 703: case RBRACK: ! 704: case RPARN: ! 705: if (!andflg) ! 706: goto syntax; ! 707: goto oponst; ! 708: ! 709: case DOT: ! 710: case ARROW: ! 711: mosflg = FMOS; ! 712: break; ! 713: ! 714: case ASSIGN: ! 715: if (andflg==0 && PLUS<=*op && *op<=EXOR) { ! 716: o = *op-- + ASPLUS - PLUS; ! 717: pp--; ! 718: goto oponst; ! 719: } ! 720: break; ! 721: ! 722: } ! 723: /* binaries */ ! 724: if (andflg==0) ! 725: goto syntax; ! 726: andflg = 0; ! 727: ! 728: oponst: ! 729: p = (opdope[o]>>9) & 037; ! 730: opon1: ! 731: if (o==COLON && op[0]==COLON && op[-1]==QUEST) { ! 732: build(*op--); ! 733: build(*op--); ! 734: pp -= 2; ! 735: } ! 736: ps = *pp; ! 737: if (p>ps || p==ps && (opdope[o]&RASSOC)!=0) { ! 738: switch (o) { ! 739: ! 740: case INCAFT: ! 741: case DECAFT: ! 742: p = 37; ! 743: break; ! 744: case LPARN: ! 745: case LBRACK: ! 746: case CALL: ! 747: p = 04; ! 748: } ! 749: if (initflg) { ! 750: if ((o==COMMA && *op!=LPARN && *op!=CALL) ! 751: || (o==COLON && *op!=QUEST)) { ! 752: p = 00; ! 753: goto opon1; ! 754: } ! 755: } ! 756: if (op >= &opst[SSIZE-1]) { ! 757: error("expression overflow"); ! 758: exit(1); ! 759: } ! 760: *++op = o; ! 761: *++pp = p; ! 762: goto advanc; ! 763: } ! 764: --pp; ! 765: os = *op--; ! 766: if (andflg==0 && p>5 && ((opdope[o]&BINARY)==0 || o>=INCBEF&&o<=DECAFT) && opdope[os]&BINARY) ! 767: goto syntax; ! 768: switch (os) { ! 769: ! 770: case SEOF: ! 771: peeksym = o; ! 772: build(0); /* flush conversions */ ! 773: if (eflag) ! 774: endtree(svtree); ! 775: return(*--cp); ! 776: ! 777: case COMMA: ! 778: if (*op != CALL) ! 779: os = SEQNC; ! 780: break; ! 781: ! 782: case CALL: ! 783: if (o!=RPARN) ! 784: goto syntax; ! 785: build(os); ! 786: goto advanc; ! 787: ! 788: case MCALL: ! 789: *cp++ = block(NULLOP, INT, (int *)NULL, ! 790: (union str *)NULL, TNULL, TNULL); ! 791: os = CALL; ! 792: break; ! 793: ! 794: case INCBEF: ! 795: case INCAFT: ! 796: case DECBEF: ! 797: case DECAFT: ! 798: *cp++ = cblock(1); ! 799: break; ! 800: ! 801: case LPARN: ! 802: if (o!=RPARN) ! 803: goto syntax; ! 804: goto advanc; ! 805: ! 806: case LBRACK: ! 807: if (o!=RBRACK) ! 808: goto syntax; ! 809: build(LBRACK); ! 810: goto advanc; ! 811: } ! 812: build(os); ! 813: goto opon1; ! 814: ! 815: syntax: ! 816: error("Expression syntax"); ! 817: errflush(o); ! 818: if (eflag) ! 819: endtree(svtree); ! 820: return((union tree *) &garbage); ! 821: } ! 822: ! 823: union tree * ! 824: xprtype() ! 825: { ! 826: struct nmlist typer, absname; ! 827: int sc; ! 828: register union tree **scp; ! 829: ! 830: scp = cp; ! 831: sc = DEFXTRN; /* will cause error if class mentioned */ ! 832: getkeywords(&sc, &typer); ! 833: absname.hclass = 0; ! 834: absname.hblklev = blklev; ! 835: absname.hsubsp = NULL; ! 836: absname.hstrp = NULL; ! 837: absname.htype = 0; ! 838: decl1(sc, &typer, 0, &absname); ! 839: cp = scp; ! 840: return(block(ETYPE, absname.htype, absname.hsubsp, ! 841: absname.hstrp, TNULL, TNULL)); ! 842: } ! 843: ! 844: char * ! 845: copnum(len) ! 846: { ! 847: register char *s1, *s2, *s3; ! 848: ! 849: s1 = s2 = Tblock((len+LNCPW-1) & ~(LNCPW-1)); ! 850: s3 = numbuf; ! 851: while (*s2++ = *s3++) ! 852: ; ! 853: return(s1); ! 854: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.