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

  1. #
  2. /* C compiler
  3.  *
  4.  *
  5.  */
  6.  
  7. #include "c0h.c"
  8.  
  9. /*
  10.  * Process a single external definition
  11.  */
  12. extdef()
  13. {
  14.     register o, elsize;
  15.     int type, sclass;
  16.     register struct hshtab *ds;
  17.  
  18.     if(((o=symbol())==EOF) || o==SEMI)
  19.         return;
  20.     peeksym = o;
  21.     type = INT;
  22.     sclass = EXTERN;
  23.     xdflg = FNDEL;
  24.     if ((elsize = getkeywords(&sclass, &type)) == -1 && peeksym!=NAME)
  25.         goto syntax;
  26.     if (type==STRUCT)
  27.         blkhed();
  28.     do {
  29.         defsym = 0;
  30.         decl1(EXTERN, type, 0, elsize);
  31.         if ((ds=defsym)==0)
  32.             return;
  33.         funcsym = ds;
  34.         ds->hflag =| FNDEL;
  35.         outcode("BS", SYMDEF, ds->name);
  36.         xdflg = 0;
  37.         if ((ds->type&XTYPE)==FUNC) {
  38.             if ((peeksym=symbol())==LBRACE || peeksym==KEYW) {
  39.                 funcblk.type = decref(ds->type);
  40.                 cfunc(ds->name);
  41.                 return;
  42.             }
  43.         } else 
  44.             cinit(ds);
  45.     } while ((o=symbol())==COMMA);
  46.     if (o==SEMI)
  47.         return;
  48. syntax:
  49.     if (o==RBRACE) {
  50.         error("Too many }'s");
  51.         peeksym = 0;
  52.         return;
  53.     }
  54.     error("External definition syntax");
  55.     errflush(o);
  56.     statement(0);
  57. }
  58.  
  59. /*
  60.  * Process a function definition.
  61.  */
  62. cfunc(cs)
  63. char *cs;
  64. {
  65.     register savdimp;
  66.  
  67.     savdimp = dimp;
  68.     outcode("BBS", PROG, RLABEL, cs);
  69.     declist(ARG);
  70.     regvar = 5;
  71.     retlab = isn++;
  72.     if ((peeksym = symbol()) != LBRACE)
  73.         error("Compound statement required");
  74.     statement(1);
  75.     outcode("BNB", LABEL, retlab, RETRN);
  76.     dimp = savdimp;
  77. }
  78.  
  79. /*
  80.  * Process the initializers for an external definition.
  81.  */
  82. cinit(ds)
  83. struct hshtab *ds;
  84. {
  85.     register basetype, nel, ninit;
  86.     int o, width, realwidth;
  87.  
  88.     nel = 1;
  89.     basetype = ds->type;
  90.     /*
  91.      * If it's an array, find the number of elements.
  92.      * "basetype" is the type of thing it's an array of.
  93.      */
  94.     while ((basetype&XTYPE)==ARRAY) {
  95.         if ((nel = dimtab[ds->ssp&0377])==0)
  96.             nel = 1;
  97.         basetype = decref(basetype);
  98.     }
  99.     realwidth = width = length(ds) / nel;
  100.     /*
  101.      * Pretend a structure is kind of an array of integers.
  102.      * This is a kludge.
  103.      */
  104.     if (basetype==STRUCT) {
  105.         nel =* realwidth/2;
  106.         width = 2;
  107.     }
  108.     if ((peeksym=symbol())==COMMA || peeksym==SEMI) {
  109.         outcode("BSN",CSPACE,ds->name,(nel*width+ALIGN)&~ALIGN);
  110.         return;
  111.     }
  112.     ninit = 0;
  113.     outcode("BBS", DATA, NLABEL, ds->name);
  114.     if ((o=symbol())==LBRACE) {
  115.         do
  116.             ninit = cinit1(ds, basetype, width, ninit, nel);
  117.         while ((o=symbol())==COMMA);
  118.         if (o!=RBRACE)
  119.             peeksym = o;
  120.     } else {
  121.         peeksym = o;
  122.         ninit = cinit1(ds, basetype, width, 0, nel);
  123.     }
  124.     /*
  125.      * Above we pretended that a structure was a bunch of integers.
  126.      * Readjust in accordance with reality.
  127.      * First round up partial initializations.
  128.      */
  129.     if (basetype==STRUCT) {
  130.         if (o = 2*ninit % realwidth)
  131.             outcode("BN", SSPACE, realwidth-o);
  132.         ninit = (2*ninit+realwidth-2) / realwidth;
  133.         nel =/ realwidth/2;
  134.     }
  135.     /*
  136.      * If there are too few initializers, allocate
  137.      * more storage.
  138.      * If there are too many initializers, extend
  139.      * the declared size for benefit of "sizeof"
  140.      */
  141.     if (ninit<nel)
  142.         outcode("BN", SSPACE, (nel-ninit)*realwidth);
  143.     else if (ninit>nel) {
  144.         if ((ds->type&XTYPE)==ARRAY)
  145.             dimtab[ds->ssp&0377] = ninit;
  146.         nel = ninit;
  147.     }
  148.     /*
  149.      * If it's not an array, only one initializer is allowed.
  150.      */
  151.     if (ninit>1 && (ds->type&XTYPE)!=ARRAY)
  152.         error("Too many initializers");
  153.     if (((nel&width)&ALIGN))
  154.         outcode("B", EVEN);
  155. }
  156.  
  157. /*
  158.  * Process a single expression in a sequence of initializers
  159.  * for an external. Mainly, it's for checking
  160.  * type compatibility.
  161.  */
  162. cinit1(ds, type, awidth, aninit, nel)
  163. struct hshtab *ds;
  164. {
  165.     float sf;
  166.     register struct tnode *s;
  167.     register width, ninit;
  168.  
  169.     width = awidth;
  170.     ninit = aninit;
  171.     if ((peeksym=symbol())==STRING && type==CHAR) {
  172.         peeksym = -1;
  173.         if (ninit)
  174.             bxdec();
  175.         putstr(0);
  176.         if (nel>nchstr) {
  177.             strflg++;
  178.             outcode("BN", SSPACE, nel-nchstr);
  179.             strflg = 0;
  180.             nchstr = nel;
  181.         }
  182.         return(nchstr);
  183.     }
  184.     if (peeksym==RBRACE)
  185.         return(ninit);
  186.     initflg++;
  187.     s = tree();
  188.     initflg = 0;
  189.     switch(width) {
  190.  
  191.     case 1:
  192.         if (s->op != CON)
  193.             goto bad;
  194.         outcode("B1N0", BDATA, s->value);
  195.         break;
  196.  
  197.     case 2:
  198.         if (s->op==CON) {
  199.             outcode("B1N0", WDATA, s->value);
  200.             break;
  201.         }
  202.         if (s->op==FCON || s->op==SFCON) {
  203.             if (type==STRUCT) {
  204.                 ninit =+ 3;
  205.                 goto prflt;
  206.             }
  207.             goto bad;
  208.         }
  209.         rcexpr(block(1,INIT,0,0,s));
  210.         break;
  211.  
  212.     case 4:
  213.         sf = fcval;
  214.         outcode("B1N1N0", WDATA, sf);
  215.         goto flt;
  216.  
  217.     case 8:
  218.     prflt:
  219.         outcode("B1N1N1N1N0", WDATA, fcval);
  220.     flt:
  221.         if (s->op==FCON || s->op==SFCON)
  222.             break;
  223.  
  224.     default:
  225.     bad:
  226.         bxdec();
  227.  
  228.     }
  229.     return(++ninit);
  230. }
  231.  
  232. bxdec()
  233. {
  234.     error("Inconsistent external initialization");
  235. }
  236.  
  237. /*
  238.  * Process one statement in a function.
  239.  */
  240. statement(d)
  241. {
  242.     register o, o1, o2;
  243.     int o3, o4;
  244.     struct tnode *np;
  245.  
  246. stmt:
  247.     switch(o=symbol()) {
  248.  
  249.     case EOF:
  250.         error("Unexpected EOF");
  251.     case SEMI:
  252.         return;
  253.  
  254.     case LBRACE:
  255.         if (d) {
  256.             if (proflg)
  257.                 outcode("BN", PROFIL, isn++);
  258.             outcode("BN", SAVE, blkhed());
  259.         }
  260.         while (!eof) {
  261.             if ((o=symbol())==RBRACE)
  262.                 return;
  263.             peeksym = o;
  264.             statement(0);
  265.         }
  266.         error("Missing '}'");
  267.         return;
  268.  
  269.     case KEYW:
  270.         switch(cval) {
  271.  
  272.         case GOTO:
  273.             if (o1 = simplegoto())
  274.                 branch(o1);
  275.             else 
  276.                 dogoto();
  277.             goto semi;
  278.  
  279.         case RETURN:
  280.             doret();
  281.             goto semi;
  282.  
  283.         case IF:
  284.             np = pexpr();
  285.             o2 = 0;
  286.             if ((o1=symbol())==KEYW) switch (cval) {
  287.             case GOTO:
  288.                 if (o2=simplegoto())
  289.                     goto simpif;
  290.                 cbranch(np, o2=isn++, 0);
  291.                 dogoto();
  292.                 label(o2);
  293.                 goto hardif;
  294.  
  295.             case RETURN:
  296.                 if (nextchar()==';') {
  297.                     o2 = retlab;
  298.                     goto simpif;
  299.                 }
  300.                 cbranch(np, o1=isn++, 0);
  301.                 doret();
  302.                 label(o1);
  303.                 o2++;
  304.                 goto hardif;
  305.  
  306.             case BREAK:
  307.                 o2 = brklab;
  308.                 goto simpif;
  309.  
  310.             case CONTIN:
  311.                 o2 = contlab;
  312.             simpif:
  313.                 chconbrk(o2);
  314.                 cbranch(np, o2, 1);
  315.             hardif:
  316.                 if ((o=symbol())!=SEMI)
  317.                     goto syntax;
  318.                 if ((o1=symbol())==KEYW && cval==ELSE) 
  319.                     goto stmt;
  320.                 peeksym = o1;
  321.                 return;
  322.             }
  323.             peeksym = o1;
  324.             cbranch(np, o1=isn++, 0);
  325.             statement(0);
  326.             if ((o=symbol())==KEYW && cval==ELSE) {
  327.                 o2 = isn++;
  328.                 branch(o2);
  329.                 label(o1);
  330.                 statement(0);
  331.                 label(o2);
  332.                 return;
  333.             }
  334.             peeksym = o;
  335.             label(o1);
  336.             return;
  337.  
  338.         case WHILE:
  339.             o1 = contlab;
  340.             o2 = brklab;
  341.             label(contlab = isn++);
  342.             cbranch(pexpr(), brklab=isn++, 0);
  343.             statement(0);
  344.             branch(contlab);
  345.             label(brklab);
  346.             contlab = o1;
  347.             brklab = o2;
  348.             return;
  349.  
  350.         case BREAK:
  351.             chconbrk(brklab);
  352.             branch(brklab);
  353.             goto semi;
  354.  
  355.         case CONTIN:
  356.             chconbrk(contlab);
  357.             branch(contlab);
  358.             goto semi;
  359.  
  360.         case DO:
  361.             o1 = contlab;
  362.             o2 = brklab;
  363.             contlab = isn++;
  364.             brklab = isn++;
  365.             label(o3 = isn++);
  366.             statement(0);
  367.             label(contlab);
  368.             contlab = o1;
  369.             if ((o=symbol())==KEYW && cval==WHILE) {
  370.                 cbranch(tree(), o3, 1);
  371.                 label(brklab);
  372.                 brklab = o2;
  373.                 goto semi;
  374.             }
  375.             goto syntax;
  376.  
  377.         case CASE:
  378.             o1 = conexp();
  379.             if ((o=symbol())!=COLON)
  380.                 goto syntax;
  381.             if (swp==0) {
  382.                 error("Case not in switch");
  383.                 goto stmt;
  384.             }
  385.             if(swp>=swtab+swsiz) {
  386.                 error("Switch table overflow");
  387.             } else {
  388.                 swp->swlab = isn;
  389.                 (swp++)->swval = o1;
  390.                 label(isn++);
  391.             }
  392.             goto stmt;
  393.  
  394.         case SWITCH:
  395.             o1 = brklab;
  396.             brklab = isn++;
  397.             np = pexpr();
  398.             chkw(np, -1);
  399.             rcexpr(block(1,RFORCE,0,0,np));
  400.             pswitch();
  401.             brklab = o1;
  402.             return;
  403.  
  404.         case DEFAULT:
  405.             if (swp==0)
  406.                 error("Default not in switch");
  407.             if ((o=symbol())!=COLON)
  408.                 goto syntax;
  409.             label(deflab = isn++);
  410.             goto stmt;
  411.  
  412.         case FOR:
  413.             o1 = contlab;
  414.             o2 = brklab;
  415.             contlab = isn++;
  416.             brklab = isn++;
  417.             if (o=forstmt())
  418.                 goto syntax;
  419.             label(brklab);
  420.             contlab = o1;
  421.             brklab = o2;
  422.             return;
  423.         }
  424.  
  425.         error("Unknown keyword");
  426.         goto syntax;
  427.  
  428.     case NAME:
  429.         if (nextchar()==':') {
  430.             peekc = 0;
  431.             o1 = csym;
  432.             if (o1->hclass>0) {
  433.                 error("Redefinition");
  434.                 goto stmt;
  435.             }
  436.             o1->hclass = STATIC;
  437.             o1->htype = ARRAY;
  438.             if (o1->hoffset==0)
  439.                 o1->hoffset = isn++;
  440.             label(o1->hoffset);
  441.             goto stmt;
  442.         }
  443.     }
  444.     peeksym = o;
  445.     rcexpr(tree());
  446.  
  447. semi:
  448.     if ((o=symbol())==SEMI)
  449.         return;
  450. syntax:
  451.     error("Statement syntax");
  452.     errflush(o);
  453. }
  454.  
  455. /*
  456.  * Process a for statement.
  457.  */
  458. forstmt()
  459. {
  460.     register int l, o, sline;
  461.     int sline1, *ss;
  462.     struct tnode *st;
  463.  
  464.     if ((o=symbol()) != LPARN)
  465.         return(o);
  466.     if ((o=symbol()) != SEMI) {        /* init part */
  467.         peeksym = o;
  468.         rcexpr(tree());
  469.         if ((o=symbol()) != SEMI)
  470.             return(o);
  471.     }
  472.     label(contlab);
  473.     if ((o=symbol()) != SEMI) {        /* test part */
  474.         peeksym = o;
  475.         rcexpr(block(1,CBRANCH,tree(),brklab,0));
  476.         if ((o=symbol()) != SEMI)
  477.             return(o);
  478.     }
  479.     if ((peeksym=symbol()) == RPARN) {    /* incr part */
  480.         peeksym = -1;
  481.         statement(0);
  482.         branch(contlab);
  483.         return(0);
  484.     }
  485.     l = contlab;
  486.     contlab = isn++;
  487.     st = tree();
  488.     sline = line;
  489.     if ((o=symbol()) != RPARN)
  490.         return(o);
  491.     ss = treespace;
  492.     treespace = space;
  493.     statement(0);
  494.     sline1 = line;
  495.     line = sline;
  496.     label(contlab);
  497.     rcexpr(st);
  498.     line = sline1;
  499.     treespace = ss;
  500.     branch(l);
  501.     return(0);
  502. }
  503.  
  504. /*
  505.  * A parenthesized expression,
  506.  * as after "if".
  507.  */
  508. pexpr()
  509. {
  510.     register o, t;
  511.  
  512.     if ((o=symbol())!=LPARN)
  513.         goto syntax;
  514.     t = tree();
  515.     if ((o=symbol())!=RPARN)
  516.         goto syntax;
  517.     return(t);
  518. syntax:
  519.     error("Statement syntax");
  520.     errflush(o);
  521.     return(0);
  522. }
  523.  
  524. /*
  525.  * The switch stateent, which involves collecting the
  526.  * constants and labels for the cases.
  527.  */
  528. pswitch()
  529. {
  530.     register struct swtab *cswp, *sswp;
  531.     int dl, swlab;
  532.  
  533.     cswp = sswp = swp;
  534.     if (swp==0)
  535.         cswp = swp = swtab;
  536.     branch(swlab=isn++);
  537.     dl = deflab;
  538.     deflab = 0;
  539.     statement(0);
  540.     branch(brklab);
  541.     label(swlab);
  542.     if (deflab==0)
  543.         deflab = brklab;
  544.     outcode("BNN", SWIT, deflab, line);
  545.     for (; cswp < swp; cswp++)
  546.         outcode("NN", cswp->swlab, cswp->swval);
  547.     outcode("0");
  548.     label(brklab);
  549.     deflab = dl;
  550.     swp = sswp;
  551. }
  552.  
  553. /*
  554.  * blkhed is called at the start of each function.
  555.  * It reads the declarations at the start;
  556.  * then assigns storage locations for the
  557.  * parameters (which have been linked into a list,
  558.  * in order of appearance).
  559.  * This list is necessary because in
  560.  * f(a, b) float b; int a; ...
  561.  * the names are seen before the types.
  562.  * Also, the routine adjusts structures involved
  563.  * in some kind of forward-referencing.
  564.  */
  565. blkhed()
  566. {
  567.     register pl;
  568.     register struct hshtab *cs;
  569.  
  570.     autolen = 6;
  571.     declist(0);
  572.     pl = 4;
  573.     while(paraml) {
  574.         parame->hoffset = 0;
  575.         cs = paraml;
  576.         paraml = paraml->hoffset;
  577.         if (cs->htype==FLOAT)
  578.             cs->htype = DOUBLE;
  579.         cs->hoffset = pl;
  580.         cs->hclass = AUTO;
  581.         if ((cs->htype&XTYPE) == ARRAY) {
  582.             cs->htype =- (ARRAY-PTR);    /* set ptr */
  583.             cs->ssp++;        /* pop dims */
  584.         }
  585.         pl =+ rlength(cs);
  586.     }
  587.     for (cs=hshtab; cs<hshtab+hshsiz; cs++) {
  588.         if (cs->name[0] == '\0')
  589.             continue;
  590.         /* check tagged structure */
  591.         if (cs->hclass>KEYWC && (cs->htype&TYPE)==RSTRUCT) {
  592.             cs->lenp = dimtab[cs->lenp&0377]->lenp;
  593.             cs->htype = cs->htype&~TYPE | STRUCT;
  594.         }
  595.         if (cs->hclass == STRTAG && dimtab[cs->lenp&0377]==0)
  596.             error("Undefined structure: %.8s", cs->name);
  597.         if (cs->hclass == ARG)
  598.             error("Not an argument: %.8s", cs->name);
  599.         if (stflg)
  600.             prste(cs);
  601.     }
  602.     space = treespace;
  603.     outcode("BN", SETREG, regvar);
  604.     return(autolen);
  605. }
  606.  
  607. /*
  608.  * After a function definition, delete local
  609.  * symbols.
  610.  * Also complain about undefineds.
  611.  */
  612. blkend() {
  613.     register struct hshtab *cs;
  614.  
  615.     for (cs=hshtab; cs<hshtab+hshsiz; cs++) {
  616.         if (cs->name[0]) {
  617.             if (cs->hclass==0 && (cs->hflag&FNUND)==0) {
  618.                 error("%.8s undefined", cs->name);
  619.                 cs->hflag =| FNUND;
  620.             }
  621.             if((cs->hflag&FNDEL)==0) {
  622.                 cs->name[0] = '\0';
  623.                 hshused--;
  624.                 cs->hflag =& ~(FNUND|FFIELD);
  625.             }
  626.         }
  627.     }
  628. }
  629.  
  630. /*
  631.  * write out special definitions of local symbols for
  632.  * benefit of the debugger.  None of these are used
  633.  * by the assembler except to save them.
  634.  */
  635. prste(acs)
  636. {
  637.     register struct hshtab *cs;
  638.     register nkind;
  639.  
  640.     cs = acs;
  641.     switch (cs->hclass) {
  642.     case REG:
  643.         nkind = RNAME;
  644.         break;
  645.  
  646.     case AUTO:
  647.         nkind = ANAME;
  648.         break;
  649.  
  650.     case STATIC:
  651.         nkind = SNAME;
  652.         break;
  653.  
  654.     default:
  655.         return;
  656.  
  657.     }
  658.     outcode("BSN", nkind, cs->name, cs->hoffset);
  659. }
  660.  
  661. /*
  662.  * In case of error, skip to the next
  663.  * statement delimiter.
  664.  */
  665. errflush(ao)
  666. {
  667.     register o;
  668.  
  669.     o = ao;
  670.     while(o>RBRACE)    /* ; { } */
  671.         o = symbol();
  672.     peeksym  = o;
  673. }
  674.