home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / c / c01.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  10.3 KB  |  645 lines

  1. #
  2. /*
  3.  * C compiler
  4.  *
  5.  *
  6.  */
  7.  
  8. #include "c0.h"
  9.  
  10. /*
  11.  * Called from tree, this routine takes the top 1, 2, or 3
  12.  * operands on the expression stack, makes a new node with
  13.  * the operator op, and puts it on the stack.
  14.  * Essentially all the work is in inserting
  15.  * appropriate conversions.
  16.  */
  17. build(op)
  18. {
  19.     register int t1;
  20.     int t2, t;
  21.     register struct tnode *p1, *p2;
  22.     struct tnode *p3;
  23.     int dope, leftc, cvn, pcvn;
  24.  
  25.     /*
  26.      * a[i] => *(a+i)
  27.      */
  28.     if (op==LBRACK) {
  29.         build(PLUS);
  30.         op = STAR;
  31.     }
  32.     dope = opdope[op];
  33.     if ((dope&BINARY)!=0) {
  34.         p2 = chkfun(disarray(*--cp));
  35.         t2 = p2->type;
  36.     }
  37.     p1 = *--cp;
  38.     /*
  39.      * sizeof gets turned into a number here.
  40.      */
  41.     if (op==SIZEOF) {
  42.         t1 = cblock(length(p1));
  43.         t1->type = UNSIGN;
  44.         *cp++ = t1;
  45.         return;
  46.     }
  47.     if (op!=AMPER) {
  48.         p1 = disarray(p1);
  49.         if (op!=CALL)
  50.             p1 = chkfun(p1);
  51.     }
  52.     t1 = p1->type;
  53.     pcvn = 0;
  54.     t = INT;
  55.     switch (op) {
  56.  
  57.     case CAST:
  58.         if ((t1&XTYPE)==FUNC || (t1&XTYPE)==ARRAY)
  59.             error("Disallowed conversion");
  60.         if (t1==UNSIGN && t2==CHAR) {
  61.             t2 = INT;
  62.             p2 = block(AND,INT,NULL,NULL,p2,cblock(0377));
  63.         }
  64.         break;
  65.  
  66.     /* end of expression */
  67.     case 0:
  68.         *cp++ = p1;
  69.         return;
  70.  
  71.     /* no-conversion operators */
  72.     case QUEST:
  73.         if (p2->op!=COLON)
  74.             error("Illegal conditional");
  75.         else
  76.             if (fold(QUEST, p1, p2))
  77.                 return;
  78.  
  79.     case SEQNC:
  80.         t = t2;
  81.  
  82.     case COMMA:
  83.     case LOGAND:
  84.     case LOGOR:
  85.         *cp++ = block(op, t, NULL, NULL, p1, p2);
  86.         return;
  87.  
  88.     case EXCLA:
  89.         t1 = INT;
  90.         break;
  91.  
  92.     case CALL:
  93.         if ((t1&XTYPE) != FUNC)
  94.             error("Call of non-function");
  95.         *cp++ = block(CALL,decref(t1),p1->subsp,p1->strp,p1,p2);
  96.         return;
  97.  
  98.     case STAR:
  99.         if ((t1&XTYPE) == FUNC)
  100.             error("Illegal indirection");
  101.         *cp++ = block(STAR, decref(t1), p1->subsp, p1->strp, p1);
  102.         return;
  103.  
  104.     case AMPER:
  105.         if (p1->op==NAME || p1->op==STAR) {
  106.             *cp++ = block(op,incref(t1),p1->subsp,p1->strp,p1);
  107.             return;
  108.         }
  109.         error("Illegal lvalue");
  110.         break;
  111.  
  112.     /*
  113.      * a.b goes to (&a)->b
  114.      */
  115.     case DOT:
  116.         if (p1->op==CALL && t1==STRUCT) {
  117.             t1 = incref(t1);
  118.             setype(p1, t1, p1);
  119.         } else {
  120.             *cp++ = p1;
  121.             build(AMPER);
  122.             p1 = *--cp;
  123.         }
  124.  
  125.     /*
  126.      * In a->b, a is given the type ptr-to-structure element;
  127.      * then the offset is added in without conversion;
  128.      * then * is tacked on to access the member.
  129.      */
  130.     case ARROW:
  131.         if (p2->op!=NAME || p2->tr1->hclass!=MOS) {
  132.             error("Illegal structure ref");
  133.             *cp++ = p1;
  134.             return;
  135.         }
  136.         if (t2==INT && p2->tr1->hflag&FFIELD)
  137.             t2 = UNSIGN;
  138.         t = incref(t2);
  139.         chkw(p1, -1);
  140.         setype(p1, t, p2);
  141.         *cp++ = block(PLUS,t,p2->subsp,p2->strp,p1,cblock(p2->tr1->hoffset));
  142.         build(STAR);
  143.         if (p2->tr1->hflag&FFIELD)
  144.             *cp++ = block(FSEL,UNSIGN,NULL,NULL,*--cp,p2->tr1->hstrp);
  145.         return;
  146.     }
  147.     if ((dope&LVALUE)!=0)
  148.         chklval(p1);
  149.     if ((dope&LWORD)!=0)
  150.         chkw(p1, LONG);
  151.     if ((dope&RWORD)!=0)
  152.         chkw(p2, LONG);
  153.     if ((dope&BINARY)==0) {
  154.         if (op==ITOF)
  155.             t1 = DOUBLE;
  156.         else if (op==FTOI)
  157.             t1 = INT;
  158.         if (!fold(op, p1, 0))
  159.             *cp++ = block(op,t1,p1->subsp,p1->strp,p1);
  160.         return;
  161.     }
  162.     cvn = 0;
  163.     if (t1==STRUCT || t2==STRUCT) {
  164.         if (t1!=t2 || p1->strp != p2->strp)
  165.             error("Incompatible structures");
  166.         cvn = 0;
  167.     } else
  168.         cvn = cvtab[lintyp(t1)][lintyp(t2)];
  169.     leftc = (cvn>>4)&017;
  170.     cvn =& 017;
  171.     t = leftc? t2:t1;
  172.     if ((t==INT||t==CHAR) && (t1==UNSIGN||t2==UNSIGN))
  173.         t = UNSIGN;
  174.     if (dope&ASSGOP || op==CAST) {
  175.         t = t1;
  176.         if (op==ASSIGN || op==CAST) {
  177.             if (cvn==ITP||cvn==PTI)
  178.                 cvn = leftc = 0;
  179.             else if (cvn==LTP) {
  180.                 if (leftc==0)
  181.                     cvn = LTI;
  182.                 else {
  183.                     cvn = ITL;
  184.                     leftc = 0;
  185.                 }
  186.             }
  187.         }
  188.         if (leftc)
  189.             cvn = leftc;
  190.         leftc = 0;
  191.     } else if (op==COLON || op==MAX || op==MIN) {
  192.         if (t1>=PTR && t1==t2)
  193.             cvn = 0;
  194.         if (op!=COLON && (t1>=PTR || t2>=PTR))
  195.             op =+ MAXP-MAX;
  196.     } else if (dope&RELAT) {
  197.         if (op>=LESSEQ && (t1>=PTR||t2>=PTR||(t1==UNSIGN||t2==UNSIGN)
  198.          && (t==INT||t==CHAR||t==UNSIGN)))
  199.             op =+ LESSEQP-LESSEQ;
  200.         if (cvn==ITP || cvn==PTI)
  201.             cvn = 0;
  202.     }
  203.     if (cvn==PTI) {
  204.         cvn = 0;
  205.         if (op==MINUS) {
  206.             t = INT;
  207.             pcvn++;
  208.         } else {
  209.             if (t1!=t2 || t1!=(PTR+CHAR))
  210.                 cvn = XX;
  211.         }
  212.     }
  213.     if (cvn) {
  214.         t1 = plength(p1);
  215.         t2 = plength(p2);
  216.         if (cvn==XX || (cvn==PTI&&t1!=t2))
  217.             error("Illegal conversion");
  218.         else if (leftc)
  219.             p1 = convert(p1, t, cvn, t2);
  220.         else
  221.             p2 = convert(p2, t, cvn, t1);
  222.     }
  223.     if (dope&RELAT)
  224.         t = INT;
  225.     if (t==FLOAT)
  226.         t = DOUBLE;
  227.     if (t==CHAR)
  228.         t = INT;
  229.     if (op==CAST) {
  230.         if (t!=DOUBLE && (t!=INT || p2->type!=CHAR)) {
  231.             p2->type = t;
  232.             p2->subsp = p1->subsp;
  233.             p2->strp = p1->strp;
  234.         }
  235.         if (t==INT && p1->type==CHAR)
  236.             p2 = block(ITOC, INT, NULL, NULL, p2);
  237.         *cp++ = p2;
  238.         return;
  239.     }
  240.     if (fold(op, p1, p2)==0) {
  241.         p3 = leftc?p2:p1;
  242.         *cp++ = block(op, t, p3->subsp, p3->strp, p1, p2);
  243.     }
  244.     if (pcvn && t1!=(PTR+CHAR)) {
  245.         p1 = *--cp;
  246.         *cp++ = convert(p1, 0, PTI, plength(p1->tr1));
  247.     }
  248. }
  249.  
  250. /*
  251.  * Generate the appropriate conversion operator.
  252.  */
  253. struct tnode *
  254. convert(p, t, cvn, len)
  255. struct tnode *p;
  256. {
  257.     register int op;
  258.  
  259.     op = cvntab[cvn];
  260.     if (opdope[op]&BINARY) {
  261.         if (len==0)
  262.             error("Illegal conversion");
  263.         return(block(op, t, NULL, NULL, p, cblock(len)));
  264.     }
  265.     return(block(op, t, NULL, NULL, p));
  266. }
  267.  
  268. /*
  269.  * Traverse an expression tree, adjust things
  270.  * so the types of things in it are consistent
  271.  * with the view that its top node has
  272.  * type at.
  273.  * Used with structure references.
  274.  */
  275. setype(ap, at, anewp)
  276. struct tnode *ap, *anewp;
  277. {
  278.     register struct tnode *p, *newp;
  279.     register t;
  280.  
  281.     p = ap;
  282.     t = at;
  283.     newp = anewp;
  284.     for (;; p = p->tr1) {
  285.         p->subsp = newp->subsp;
  286.         p->strp = newp->strp;
  287.         p->type = t;
  288.         if (p->op==AMPER)
  289.             t = decref(t);
  290.         else if (p->op==STAR)
  291.             t = incref(t);
  292.         else if (p->op!=PLUS)
  293.             break;
  294.     }
  295. }
  296.  
  297. /*
  298.  * A mention of a function name is turned into
  299.  * a pointer to that function.
  300.  */
  301. struct tnode *
  302. chkfun(ap)
  303. struct tnode *ap;
  304. {
  305.     register struct tnode *p;
  306.     register int t;
  307.  
  308.     p = ap;
  309.     if (((t = p->type)&XTYPE)==FUNC && p->op!=ETYPE)
  310.         return(block(AMPER,incref(t),p->subsp,p->strp,p));
  311.     return(p);
  312. }
  313.  
  314. /*
  315.  * A mention of an array is turned into
  316.  * a pointer to the base of the array.
  317.  */
  318. struct tnode *
  319. disarray(ap)
  320. struct tnode *ap;
  321. {
  322.     register int t;
  323.     register struct tnode *p;
  324.  
  325.     p = ap;
  326.     /* check array & not MOS and not typer */
  327.     if (((t = p->type)&XTYPE)!=ARRAY || p->op==NAME&&p->tr1->hclass==MOS
  328.      || p->op==ETYPE)
  329.         return(p);
  330.     p->subsp++;
  331.     *cp++ = p;
  332.     setype(p, decref(t), p);
  333.     build(AMPER);
  334.     return(*--cp);
  335. }
  336.  
  337. /*
  338.  * make sure that p is a ptr to a node
  339.  * with type int or char or 'okt.'
  340.  * okt might be nonexistent or 'long'
  341.  * (e.g. for <<).
  342.  */
  343. chkw(p, okt)
  344. struct tnode *p;
  345. {
  346.     register int t;
  347.  
  348.     if ((t=p->type)!=INT && t<PTR && t!=CHAR && t!=UNSIGN && t!=okt)
  349.         error("Illegal type of operand");
  350.     return;
  351. }
  352.  
  353. /*
  354.  *'linearize' a type for looking up in the
  355.  * conversion table
  356.  */
  357. lintyp(t)
  358. {
  359.     switch(t) {
  360.  
  361.     case INT:
  362.     case CHAR:
  363.     case UNSIGN:
  364.         return(0);
  365.  
  366.     case FLOAT:
  367.     case DOUBLE:
  368.         return(1);
  369.  
  370.     case LONG:
  371.         return(2);
  372.  
  373.     default:
  374.         return(3);
  375.     }
  376. }
  377.  
  378. /*
  379.  * Report an error.
  380.  */
  381. error(s, p1, p2, p3, p4, p5, p6)
  382. {
  383.     nerror++;
  384.     if (filename[0])
  385.         fprintf(stderr, "%s:", filename);
  386.     fprintf(stderr, "%d: ", line);
  387.     fprintf(stderr, s, p1, p2, p3, p4, p5, p6);
  388.     fprintf(stderr, "\n");
  389. }
  390.  
  391. /*
  392.  * Generate a node in an expression tree,
  393.  * setting the operator, type, dimen/struct table ptrs,
  394.  * and the operands.
  395.  */
  396. struct tnode *
  397. block(op, t, subs, str, p1,p2)
  398. int *subs;
  399. struct str *str;
  400. struct tnode *p1, *p2;
  401. {
  402.     register struct tnode *p;
  403.  
  404.     p = gblock(sizeof(*p));
  405.     p->op = op;
  406.     p->type = t;
  407.     p->subsp = subs;
  408.     p->strp = str;
  409.     p->tr1 = p1;
  410.     if (opdope[op]&BINARY)
  411.         p->tr2 = p2;
  412.     else
  413.         p->tr2 = NULL;
  414.     return(p);
  415. }
  416.  
  417. struct tnode *
  418. nblock(ads)
  419. struct hshtab *ads;
  420. {
  421.     register struct hshtab *ds;
  422.  
  423.     ds = ads;
  424.     return(block(NAME, ds->htype, ds->hsubsp, ds->hstrp, ds));
  425. }
  426.  
  427. /*
  428.  * Generate a block for a constant
  429.  */
  430. struct cnode *
  431. cblock(v)
  432. {
  433.     register struct cnode *p;
  434.  
  435.     p = gblock(sizeof(*p));
  436.     p->op = CON;
  437.     p->type = INT;
  438.     p->subsp = NULL;
  439.     p->strp = NULL;
  440.     p->value = v;
  441.     return(p);
  442. }
  443.  
  444. /*
  445.  * A block for a float or long constant
  446.  */
  447. struct fnode *
  448. fblock(t, string)
  449. char *string;
  450. {
  451.     register struct fnode *p;
  452.  
  453.     p = gblock(sizeof(*p));
  454.     p->op = FCON;
  455.     p->type = t;
  456.     p->subsp = NULL;
  457.     p->strp = NULL;
  458.     p->cstr = string;
  459.     return(p);
  460. }
  461.  
  462. /*
  463.  * Assign a block for use in the
  464.  * expression tree.
  465.  */
  466. char *
  467. gblock(n)
  468. {
  469.     register int *p;
  470.  
  471.     p = curbase;
  472.     if ((curbase =+ n) >= coremax) {
  473.         if (sbrk(1024) == -1) {
  474.             error("Out of space");
  475.             exit(1);
  476.         }
  477.         coremax =+ 1024;
  478.     }
  479.     return(p);
  480. }
  481.  
  482. /*
  483.  * Check that a tree can be used as an lvalue.
  484.  */
  485. chklval(ap)
  486. struct tnode *ap;
  487. {
  488.     register struct tnode *p;
  489.  
  490.     p = ap;
  491.     if (p->op==FSEL)
  492.         p = p->tr1;
  493.     if (p->op!=NAME && p->op!=STAR)
  494.         error("Lvalue required");
  495. }
  496.  
  497. /*
  498.  * reduce some forms of `constant op constant'
  499.  * to a constant.  More of this is done in the next pass
  500.  * but this is used to allow constant expressions
  501.  * to be used in switches and array bounds.
  502.  */
  503. fold(op, ap1, ap2)
  504. struct tnode *ap1, *ap2;
  505. {
  506.     register struct tnode *p1;
  507.     register int v1, v2;
  508.     int unsignf;
  509.  
  510.     p1 = ap1;
  511.     if (p1->op!=CON)
  512.         return(0);
  513.     unsignf = p1->type==UNSIGN;
  514.     if (op==QUEST) {
  515.         if (ap2->tr1->op==CON && ap2->tr2->op==CON) {
  516.             p1->value = p1->value? ap2->tr1->value: ap2->tr2->value;
  517.             *cp++ = p1;
  518.             return(1);
  519.         }
  520.         return(0);
  521.     }
  522.     if (ap2) {
  523.         if (ap2->op!=CON)
  524.             return(0);
  525.         v2 = ap2->value;
  526.         unsignf |= ap2->type==UNSIGN;
  527.     }
  528.     v1 = p1->value;
  529.     switch (op) {
  530.  
  531.     case PLUS:
  532.         v1 =+ v2;
  533.         break;
  534.  
  535.     case MINUS:
  536.         v1 =- v2;
  537.         break;
  538.  
  539.     case TIMES:
  540.         v1 =* v2;
  541.         break;
  542.  
  543.     case DIVIDE:
  544.         if (v2==0)
  545.             goto divchk;
  546.         if (unsignf) {
  547.             v1 = (unsigned)v1 / v2;
  548.             break;
  549.         }
  550.         v1 =/ v2;
  551.         break;
  552.  
  553.     case MOD:
  554.         if (v2==0)
  555.             goto divchk;
  556.         if (unsignf) {
  557.             v1 = (unsigned)v1 % v2;
  558.             break;
  559.         }
  560.         v1 =% v2;
  561.         break;
  562.  
  563.     case AND:
  564.         v1 =& v2;
  565.         break;
  566.  
  567.     case OR:
  568.         v1 =| v2;
  569.         break;
  570.  
  571.     case EXOR:
  572.         v1 =^ v2;
  573.         break;
  574.  
  575.     case NEG:
  576.         v1 = - v1;
  577.         break;
  578.  
  579.     case COMPL:
  580.         v1 = ~ v1;
  581.         break;
  582.  
  583.     case LSHIFT:
  584.         v1 =<< v2;
  585.         break;
  586.  
  587.     case RSHIFT:
  588.         if (unsignf) {
  589.             v1 = (unsigned)v1 >> v2;
  590.             break;
  591.         }
  592.         v1 =>> v2;
  593.         break;
  594.  
  595.     case EQUAL:
  596.         v1 = v1==v2;
  597.         break;
  598.  
  599.     case NEQUAL:
  600.         v1 = v1!=v2;
  601.         break;
  602.  
  603.     case LESS:
  604.         v1 = v1<v2;
  605.         break;
  606.  
  607.     case GREAT:
  608.         v1 = v1>v2;
  609.         break;
  610.  
  611.     case LESSEQ:
  612.         v1 = v1<=v2;
  613.         break;
  614.  
  615.     case GREATEQ:
  616.         v1 = v1>=v2;
  617.         break;
  618.  
  619.     divchk:
  620.         error("Divide check");
  621.     default:
  622.         return(0);
  623.     }
  624.     p1->value = v1;
  625.     *cp++ = p1;
  626.     return(1);
  627. }
  628.  
  629. /*
  630.  * Compile an expression expected to have constant value,
  631.  * for example an array bound or a case value.
  632.  */
  633. conexp()
  634. {
  635.     register struct tnode *t;
  636.  
  637.     initflg++;
  638.     if (t = tree())
  639.         if (t->op != CON)
  640.             error("Constant required");
  641.     initflg--;
  642.     curbase = funcbase;
  643.     return(t->value);
  644. }
  645.