home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / source / c / c04.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-07-18  |  4.8 KB  |  344 lines

  1. #
  2. /*
  3.  * C compiler
  4.  *
  5.  *
  6.  */
  7.  
  8. #include "c0h.c"
  9.  
  10. /*
  11.  * Reduce the degree-of-reference by one.
  12.  * e.g. turn "ptr-to-int" into "int".
  13.  */
  14. decref(at)
  15. {
  16.     register t;
  17.  
  18.     t = at;
  19.     if ((t & ~TYPE) == 0) {
  20.         error("Illegal indirection");
  21.         return(t);
  22.     }
  23.     return((t>>TYLEN) & ~TYPE | t&TYPE);
  24. }
  25.  
  26. /*
  27.  * Increase the degree of reference by
  28.  * one; e.g. turn "int" to "ptr-to-int".
  29.  */
  30. incref(t)
  31. {
  32.     return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);
  33. }
  34.  
  35. /*
  36.  * Make a tree that causes a branch to lbl
  37.  * if the tree's value is non-zero together with the cond.
  38.  */
  39. cbranch(tree, lbl, cond)
  40. struct tnode *tree;
  41. {
  42.     rcexpr(block(1,CBRANCH,tree,lbl,cond));
  43. }
  44.  
  45. /*
  46.  * Write out a tree.
  47.  */
  48. rcexpr(tree)
  49. struct tnode *tree;
  50. {
  51.  
  52.     treeout(tree);
  53.     outcode("BN", EXPR, line);
  54. }
  55.  
  56. treeout(atree)
  57. struct tnode *atree;
  58. {
  59.     register struct tnode *tree;
  60.  
  61.     if ((tree = atree) == 0)
  62.         return;
  63.     switch(tree->op) {
  64.  
  65.     case 0:
  66.         outcode("B", NULL);
  67.         return;
  68.  
  69.     case NAME:
  70.         outcode("BNN", NAME, tree->class, tree->type);
  71.         if (tree->class==EXTERN)
  72.             outcode("S", tree->nname);
  73.         else
  74.             outcode("N", tree->nloc);
  75.         return;
  76.  
  77.     case CON:
  78.     case FCON:
  79.     case SFCON:
  80.         outcode("BNN", tree->op, tree->type, tree->value);
  81.         return;
  82.  
  83.     case FSEL:
  84.         treeout(tree->tr1);
  85.         outcode("BNN", tree->op, tree->type, tree->tr2);
  86.         return;
  87.  
  88.     case CBRANCH:
  89.         treeout(tree->btree);
  90.         outcode("BNN", tree->op, tree->lbl, tree->cond);
  91.         return;
  92.  
  93.     default:
  94.         treeout(tree->tr1);
  95.         if (opdope[tree->op]&BINARY)
  96.             treeout(tree->tr2);
  97.         outcode("BN", tree->op, tree->type);
  98.         return;
  99.     }
  100. }
  101.  
  102. /*
  103.  * Generate a branch
  104.  */
  105. branch(lab) {
  106.     outcode("BN", BRANCH, lab);
  107. }
  108.  
  109. /*
  110.  * Generate a label
  111.  */
  112. label(l) {
  113.     outcode("BN", LABEL, l);
  114. }
  115.  
  116. /*
  117.  * ap is a tree node whose type
  118.  * is some kind of pointer; return the size of the object
  119.  * to which the pointer points.
  120.  */
  121. plength(ap)
  122. struct tname *ap;
  123. {
  124.     register t, l;
  125.     register struct tname *p;
  126.  
  127.     p = ap;
  128.     if (p==0 || ((t=p->type)&~TYPE) == 0)        /* not a reference */
  129.         return(1);
  130.     p->type = decref(t);
  131.     l = length(p);
  132.     p->type = t;
  133.     return(l);
  134. }
  135.  
  136. /*
  137.  * return the number of bytes in the object
  138.  * whose tree node is acs.
  139.  */
  140. length(acs)
  141. struct tnode *acs;
  142. {
  143.     register t, n;
  144.     register struct tnode *cs;
  145.  
  146.     cs = acs;
  147.     t = cs->type;
  148.     n = 1;
  149.     while ((t&XTYPE) == ARRAY) {
  150.         t = decref(t);
  151.         n = dimtab[cs->ssp&0377];
  152.     }
  153.     if ((t&~TYPE)==FUNC)
  154.         return(0);
  155.     if (t>=PTR)
  156.         return(2*n);
  157.     switch(t&TYPE) {
  158.  
  159.     case INT:
  160.         return(2*n);
  161.  
  162.     case CHAR:
  163.         return(n);
  164.  
  165.     case FLOAT:
  166.     case LONG:
  167.         return(4*n);
  168.  
  169.     case DOUBLE:
  170.         return(8*n);
  171.  
  172.     case STRUCT:
  173.         return(n * dimtab[cs->lenp&0377]);
  174.  
  175.     case RSTRUCT:
  176.         error("Bad structure");
  177.         return(0);
  178.     }
  179.     error("Compiler error (length)");
  180. }
  181.  
  182. /*
  183.  * The number of bytes in an object, rounded up to a word.
  184.  */
  185. rlength(cs)
  186. struct tnode *cs;
  187. {
  188.     return((length(cs)+ALIGN) & ~ALIGN);
  189. }
  190.  
  191. /*
  192.  * After an "if (...) goto", look to see if the transfer
  193.  * is to a simple label.
  194.  */
  195. simplegoto()
  196. {
  197.     register struct hshtab *csp;
  198.  
  199.     if ((peeksym=symbol())==NAME && nextchar()==';') {
  200.         csp = csym;
  201.         if (csp->hclass==0 && csp->htype==0) {
  202.             csp->htype = ARRAY;
  203.             if (csp->hoffset==0)
  204.                 csp->hoffset = isn++;
  205.         }
  206.         if ((csp->hclass==0||csp->hclass==STATIC)
  207.          &&  csp->htype==ARRAY) {
  208.             peeksym = -1;
  209.             return(csp->hoffset);
  210.         }
  211.     }
  212.     return(0);
  213. }
  214.  
  215. /*
  216.  * Return the next non-white-space character
  217.  */
  218. nextchar()
  219. {
  220.     while (spnextchar()==' ')
  221.         peekc = 0;
  222.     return(peekc);
  223. }
  224.  
  225. /*
  226.  * Return the next character, translating all white space
  227.  * to blank and handling line-ends.
  228.  */
  229. spnextchar()
  230. {
  231.     register c;
  232.  
  233.     if ((c = peekc)==0)
  234.         c = getchar();
  235.     if (c=='\t')
  236.         c = ' ';
  237.     else if (c=='\n') {
  238.         c = ' ';
  239.         if (inhdr==0)
  240.             line++;
  241.         inhdr = 0;
  242.     } else if (c=='\001') {    /* SOH, insert marker */
  243.         inhdr++;
  244.         c = ' ';
  245.     }
  246.     peekc = c;
  247.     return(c);
  248. }
  249.  
  250. /*
  251.  * is a break or continue legal?
  252.  */
  253. chconbrk(l)
  254. {
  255.     if (l==0)
  256.         error("Break/continue error");
  257. }
  258.  
  259. /*
  260.  * The goto statement.
  261.  */
  262. dogoto()
  263. {
  264.     register struct tnode *np;
  265.  
  266.     *cp++ = tree();
  267.     build(STAR);
  268.     chkw(np = *--cp, -1);
  269.     rcexpr(block(1,JUMP,0,0,np));
  270. }
  271.  
  272. /*
  273.  * The return statement, which has to convert
  274.  * the returned object to the function's type.
  275.  */
  276. doret()
  277. {
  278.     register struct tnode *t;
  279.  
  280.     if (nextchar() != ';') {
  281.         t = tree();
  282.         *cp++ = &funcblk;
  283.         *cp++ = t;
  284.         build(ASSIGN);
  285.         cp[-1] = cp[-1]->tr2;
  286.         build(RFORCE);
  287.         rcexpr(*--cp);
  288.     }
  289.     branch(retlab);
  290. }
  291.  
  292. /*
  293.  * write out a character to the usual output
  294.  * or to the string file
  295.  */
  296. putchar(c)
  297. {
  298.     write(1, &c, 1);
  299. }
  300.  
  301. outcode(s, a)
  302. char *s;
  303. {
  304.     register char *sp;
  305.     register *ap, *bufp;
  306.     int n;
  307.     char *np;
  308.  
  309.     bufp = obuf;
  310.     if (strflg)
  311.         bufp = sbuf;
  312.     ap = &a;
  313.     for (;;) switch(*s++) {
  314.     case 'B':
  315.         putw(*ap++ | (0376<<8), bufp);
  316.         continue;
  317.  
  318.     case 'N':
  319.         putw(*ap++, bufp);
  320.         continue;
  321.  
  322.     case 'S':
  323.         np = *ap++;
  324.         n = ncps;
  325.         while (n-- && *np) {
  326.             putc(*np++, bufp);
  327.         }
  328.         putc(0, bufp);
  329.         continue;
  330.  
  331.     case '1':
  332.         putw(1, bufp);
  333.         continue;
  334.  
  335.     case '0':
  336.         putw(0, bufp);
  337.         continue;
  338.  
  339.     case '\0':
  340.         return;
  341.     }
  342.     error("Botch in outcode");
  343. }
  344.