home *** CD-ROM | disk | FTP | other *** search
/ Dream 48 / Amiga_Dream_48.iso / Atari / c / sozobon-v2 / scsrc20.lzh / HCC.LZH / D2.C < prev    next >
C/C++ Source or Header  |  1991-02-22  |  11KB  |  710 lines

  1. /* Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    d2.c
  12.  *
  13.  *    Declaration subroutines
  14.  *
  15.  *    Mostly routines for initializations
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include "param.h"
  20. #include "tok.h"
  21. #include "nodes.h"
  22. #include "cookie.h"
  23.  
  24. #if MMCC
  25. overlay "pass2"
  26. #endif
  27.  
  28. extern NODEP cur;
  29. extern NODEP symtab[];
  30. extern level;
  31.  
  32. extern int oflags[];
  33. #define debugi    oflags['i'-'a']
  34.  
  35. su_size(lp, cp, xp, isunion)
  36. register long *lp;
  37. char *cp;
  38. register NODE *xp;
  39. {
  40.     long sz;
  41.     char al;
  42.  
  43.     sz = xp->n_tptr->t_size;
  44.     al = xp->n_tptr->t_aln;
  45.     if (isunion) {
  46.         *lp = *lp > sz ? *lp : sz;
  47.     } else {
  48.         while (al & (*lp)) {    /* align new field */
  49.             (*lp)++;
  50.             xp->e_offs++;
  51.         }
  52.         *lp += sz;
  53.     }
  54.     *cp = *cp > al ? *cp : al;
  55. }
  56.  
  57. lc_size(lp, rp, xp)
  58. register long *lp;
  59. int *rp;
  60. register NODE *xp;
  61. {
  62.     long sz;
  63.     char al;
  64.     long arg_size();
  65. #ifdef LAT_HOST
  66.     long tsz;
  67. #endif
  68.  
  69.     if (level > 1 && xp->e_sc == K_REGISTER) {
  70.         if (lc_reg(rp, xp))
  71.             return;
  72.         else
  73.             xp->e_sc = K_AUTO;
  74.     }
  75.     if (xp->e_sc == K_AUTO || level == 1) {
  76.         sz = xp->n_tptr->t_size;
  77.         al = xp->n_tptr->t_aln;
  78.         while (al & (*lp)) {    /* align new field */
  79.             (*lp)++;
  80.             xp->e_offs++;
  81.         }
  82.         if (level == 1) {
  83. #ifndef LAT_HOST
  84.             sz = arg_size(sz,xp);
  85. #else
  86.             tsz = arg_size(sz,xp);
  87.             sz = tsz;
  88. #endif
  89.             xp->e_offs += ARG_BASE + *lp;
  90.         }
  91.         *lp += sz;
  92.         if (level != 1)
  93.             xp->e_offs = LOC_BASE - *lp;
  94.     }
  95. }
  96.  
  97. su_fld(lp, alp, xp, fldw, fop)
  98. register long *lp;
  99. char *alp;
  100. register NODE *xp;
  101. int *fop;
  102. {
  103.     if (*alp < ALN_I)
  104.         *alp = ALN_I;
  105.     if (fldw == 0) {
  106.         afterfld(lp, fop);
  107.         return;
  108.     }
  109.     if (fldw + *fop > 8*SIZE_I)
  110.         afterfld(lp, fop);
  111.     if (xp) {
  112.         xp->e_fldw = fldw;
  113.         xp->e_fldo = *fop;
  114.     }
  115.     *fop += fldw;
  116. }
  117.  
  118. afterfld(szp, fop)
  119. long *szp;
  120. int *fop;
  121. {
  122.     if (*fop) {
  123.         *szp += SIZE_I;
  124.         *fop = 0;
  125.     }
  126. }
  127.  
  128. ok_gsh(sc, np)
  129. NODE *np;
  130. {
  131.     if (sc == K_REGISTER || sc == K_AUTO) {
  132.         error("reg/auto outside fun");
  133.         return 0;
  134.     }
  135.     return ok_ty(np, NULL);
  136. }
  137.  
  138. ok_gx(np, endp)
  139. NODEP np, endp;
  140. {
  141.     if (np)
  142.         return ok_ty(np->n_tptr, endp);
  143.     return 0;
  144. }
  145.  
  146. ok_lsh(sc, np)
  147. NODE *np;
  148. {
  149.     return ok_ty(np, NULL);
  150. }
  151.  
  152. arytoptr(np)
  153. NODEP np;
  154. {
  155.     NODEP tp = np->n_tptr;
  156.     NODEP copyone();
  157.  
  158.     if (np->n_flags & N_COPYT) {    /* cant change if a dupl. */
  159.         tp = copyone(tp);
  160.         np->n_tptr = tp;
  161.         np->n_flags &= ~N_COPYT;
  162.     }
  163.     tp->t_token = STAR;
  164.     strcpy(tp->n_name, "Aptr to");
  165. }
  166.  
  167. ok_lx(np,endp)
  168. NODEP np, endp;
  169. {
  170.     if (np) {
  171.         if (level == 1 && np->n_tptr->t_token == '[')
  172.             arytoptr(np);
  173.         return ok_ty(np->n_tptr, endp);
  174.     }
  175.     return 0;
  176. }
  177.  
  178. ok_suh(np)
  179. NODEP np;
  180. {
  181.     return 1;
  182. }
  183.  
  184. ok_sux(np, endp)
  185. NODEP np, endp;
  186. {
  187.     if (np)
  188.         return ok_ty(np->n_tptr, endp);
  189.     return 0;
  190. }
  191.  
  192. ok_enx(np, endp)
  193. NODEP np, endp;
  194. {
  195.     if (np && np->n_tptr == endp)    /* no modifiers */
  196.         return 1;
  197.     return 0;
  198. }
  199.  
  200. ok_cast(np, endp)
  201. NODEP np, endp;
  202. {
  203.     if (np)
  204.         return ok_ty(np, endp);
  205.     return 0;
  206. }
  207.  
  208. ok_ty(np, endp)
  209. register NODEP np, endp;
  210. {
  211.     NODEP child;
  212.     long csize;
  213.     long conlval();
  214.  
  215.     if (np == endp)
  216.         return 1;
  217.     child = np->n_tptr;
  218.     if (child) {
  219.         if (ok_ty(child, endp) == 0)
  220.             return 0;
  221.         csize = child->t_size;
  222.     }
  223.  
  224.     switch (np->t_token) {
  225.     case STAR:
  226.         np->t_size = SIZE_P;
  227.         np->t_aln = ALN_P;
  228.         break;
  229.     case '(':
  230.         /* size 0 okay - fun ret void */
  231.         if (child->t_token == '[') {
  232.             error("bad func");
  233.             return 0;
  234.         }
  235.         /* size 0 */
  236.         break;
  237.     case '[':
  238.         if (csize == 0) {
  239.             error("bad array");
  240.             return 0;
  241.         }
  242.         if (np->n_right) {
  243.             csize *= conlval(np->n_right);
  244.             np->n_right = NULL;
  245.             np->t_size = csize;
  246.         }
  247.         np->t_aln = child->t_aln;
  248.         break;
  249.     default:
  250.         return 1;
  251.     }
  252.     return 1;
  253. }
  254.  
  255. ok_revx(rv,forcast)
  256. NODEP rv;
  257. {
  258.     if (rv == NULL)
  259.         return 1;
  260.     if (forcast == 0 && rv->e_token != ID) {
  261.         error("need ID");
  262.         return 0;
  263.     }
  264.     if (forcast && rv->e_token == ID) {
  265.         error("ID in cast");
  266.         return 0;
  267.     }
  268.     return 1;
  269. }
  270.  
  271. opt_ginit(xp)
  272. NODEP xp;
  273. {
  274.     if (xp->e_token != ID)
  275.         return;
  276.     if (xp->n_tptr->t_token == '(')
  277.         return;
  278.     switch (xp->e_sc) {
  279.     case K_STATIC:
  280.     case HERE_SC:
  281.         if (cur->e_token == '=') {
  282.             out_gv(xp, 0);
  283.             fadvnode();
  284.             g_init(xp->n_tptr);
  285.         } else
  286.             out_gv(xp, 1);
  287.     }
  288. }
  289.  
  290. opt_linit(xp)
  291. NODEP xp;
  292. {
  293.     if (xp->e_token != ID)
  294.         return;
  295.     if (xp->n_tptr->t_token == '(')
  296.         return;
  297.     switch (xp->e_sc) {
  298.     case K_STATIC:
  299.         if (cur->e_token == '=') {
  300.             out_gv(xp, 0);
  301.             fadvnode();
  302.             g_init(xp->n_tptr);
  303.         } else
  304.             out_gv(xp, 1);
  305.         to_text();
  306.         break;
  307.     case K_AUTO:
  308.     case K_REGISTER:
  309.         if (xp->n_tptr->t_token == '[')
  310.             return;
  311.         if (cur->e_token == '=')
  312.             a_init(xp);
  313.         break;
  314.     }
  315. }
  316.  
  317. a_init(op)
  318. NODEP op;
  319. {
  320.     register NODEP np, xp;
  321.     NODEP assignx(), copynode();
  322.  
  323.     np = cur;  advnode();
  324.     xp = assignx();
  325.     op = copynode(op);
  326.     np->n_left = op;
  327.     np->n_right = xp;
  328.     np->e_type = E_BIN;
  329.     do_expr(np, FORSIDE);
  330.     return;
  331. }
  332.  
  333. opt_enval(intp)
  334. int *intp;
  335. {
  336.     NODEP np;
  337.     NODEP questx();
  338.  
  339.     if (cur->e_token == '=') {
  340.         fadvnode();
  341.         np = questx();
  342.         *intp = conxval(np);
  343.         return;
  344.     }
  345. }
  346.  
  347. opt_field(xp,wdp,isunion)
  348. NODE *xp;
  349. int *wdp;
  350. {
  351.     NODEP np;
  352.     NODEP questx();
  353.     int i;
  354.  
  355.     *wdp = -1;
  356.     if (isunion) return;
  357.     if (cur->e_token == ':') {
  358.         fadvnode();
  359.         np = questx();
  360.         i = conxval(np);
  361.         if (i > 8*SIZE_I) {
  362.             error("field too big");
  363.             i = 8*SIZE_I;
  364.         }
  365.         if (xp) {
  366.             if (i <= 0 || bad_fty(xp->n_tptr)) {
  367.                 error("bad field");
  368.                 return;
  369.             }
  370.         } else if (i < 0) {
  371.             error("neg field width");
  372.             return;
  373.         }
  374.         *wdp = i;
  375.         return;
  376.     }
  377. }
  378.  
  379. bad_fty(tp)
  380. NODEP tp;
  381. {
  382.     int tok;
  383.  
  384.     tok = tp->t_token;
  385.     if (tok == K_INT || tok == K_UNSIGNED)
  386.         return 0;
  387.     return 1;
  388. }
  389.  
  390. field(xp, wd, ofp)
  391. NODEP xp;
  392. int *ofp;
  393. {
  394. }
  395.  
  396. NODEP
  397. def_type()
  398. {
  399.     NODEP bas_type();
  400.  
  401.     return bas_type(K_INT);
  402. }
  403.  
  404. #define NSC    LAST_SC-FIRST_SC+1
  405. #define NBAS    LAST_BAS-FIRST_BAS+1
  406.  
  407. NODE basics[NBAS];
  408. NODE str_ptr, fun_int;
  409.  
  410. struct bt {
  411.     char    *name;
  412.     int    size;
  413.     char    align;
  414. } btbl[] = {
  415.     {"Uchar",    SIZE_C, ALN_C},
  416.     {"Ulong",    SIZE_L, ALN_L},
  417.     {"Long",    SIZE_L,    ALN_L},
  418.     {"Short",    SIZE_S, ALN_S},
  419.     {"Uns",        SIZE_U, ALN_U},
  420.     {"Int",        SIZE_I, ALN_I},
  421.     {"Char",    SIZE_C, ALN_C},
  422.     {"Float",    SIZE_F, ALN_F},
  423.     {"Dbl",        SIZE_D, ALN_D},
  424.     {"Void",    0},
  425. };
  426.  
  427. NODEP
  428. bas_type(btype)
  429. {
  430.     NODEP rv;
  431.     static once = 0;
  432.  
  433.     if (once == 0) {
  434.         once++;
  435.  
  436.         sprintf(str_ptr.n_name, "Ptr to");
  437.         str_ptr.t_token = STAR;
  438.         str_ptr.n_tptr = bas_type(K_CHAR);
  439.         str_ptr.n_flags = N_COPYT;
  440.         str_ptr.t_size = SIZE_P;
  441.         str_ptr.t_aln = ALN_P;
  442.  
  443.         sprintf(fun_int.n_name, "Fun ret");
  444.         fun_int.t_token = '(';
  445.         fun_int.n_tptr = bas_type(K_INT);
  446.         fun_int.n_flags = N_COPYT;
  447.     }
  448.     if (btype == SCON)
  449.         return &str_ptr;
  450.     else if (btype == '(')
  451.         return &fun_int;
  452.     rv = &basics[btype-FIRST_BAS];
  453.     if (rv->t_token == 0) {
  454.         rv->t_token = btype;
  455.         rv->t_size = btbl[btype-FIRST_BAS].size;
  456.         rv->t_aln = btbl[btype-FIRST_BAS].align;
  457.         sprintf(rv->n_name, btbl[btype-FIRST_BAS].name);
  458.     }
  459.     return rv;
  460. }
  461.  
  462. /* new function name seen in expr */
  463. NODEP
  464. new_fun(op)
  465. NODE *op;
  466. {
  467.     NODEP np;
  468.     NODEP copyone();
  469.  
  470.     /* we know left, right and tptr are NULL */
  471.     np = copyone(op); /* ID node */
  472.     np->n_tptr = bas_type('(');
  473.     np->n_flags = N_COPYT;
  474.     np->e_sc = K_EXTERN;
  475.     new_sym(symtab, np);
  476.     return np;
  477. }
  478.  
  479. /* declare arg name as int */
  480. def_arg(listpp, op)
  481. NODE **listpp, *op;
  482. {
  483.     register NODEP np;
  484.     NODEP copyone();
  485.  
  486.     np = copyone(op);
  487.     np->n_tptr = bas_type(K_INT);
  488.     np->n_flags = N_COPYT;
  489.     np->e_sc = K_AUTO;
  490.     new_sym(listpp, np);
  491. }
  492.  
  493. /* initialize 0 or 1 thing of any type (tp) */
  494. g_init(tp)
  495. register NODEP tp;
  496. {
  497.     int nsee;
  498.     long sz;
  499.     int oldsize;
  500.     int seebr = 0;
  501.  
  502.     if (cur->e_token == SCON &&
  503.            tp->t_token == '[' &&
  504.            tp->n_tptr->t_token == K_CHAR) { /* hack for SCON ary */
  505.             nsee = out_scon(cur);
  506.             fadvnode();
  507.             a_fix(tp, nsee);
  508.             return 1;
  509.     }
  510.  
  511.     if (cur->e_token == '{') {
  512.         fadvnode();
  513.         seebr = 1;
  514.     }
  515.  
  516.     switch (tp->t_token) {
  517.     case '[':
  518.         if (tp->t_size)
  519.             oldsize = tp->t_size / tp->n_tptr->t_size;
  520.         else
  521.             oldsize = 0;
  522.         nsee = inita(tp->n_tptr, oldsize);
  523.         if (nsee)
  524.             a_fix(tp, nsee);
  525.         break;
  526.     case K_STRUCT:
  527.         o_aln(tp->t_aln);
  528.         nsee = inits(tp->n_right);
  529.         break;
  530.     case K_UNION:
  531.         o_aln(tp->t_aln);
  532.         nsee = g_init(tp->n_right->n_tptr);
  533.         if (nsee) {
  534.             sz = tp->t_size - tp->n_right->n_tptr->t_size;
  535.             if (sz)
  536.                 o_nz(sz, 0);
  537.         }
  538.         break;
  539.     default:
  540.         nsee = init1(tp);
  541.         break;
  542.     }
  543.  
  544.     if (seebr) {
  545.         if (cur->e_token == ',')
  546.             fadvnode();
  547.         eat('}');
  548.     }
  549.     return nsee ? 1 : 0;
  550. }
  551.  
  552. /* initialize one (or 0) scalar to an expr */
  553. init1(tp)
  554. register NODEP tp;
  555. {
  556.     NODEP xp;
  557.     NODEP assignx();
  558.  
  559.     if (debugi) {
  560.         printf("init1");
  561.         printnode(tp);
  562.     }
  563.     xp = assignx();
  564.     if (xp) {
  565.         if (debugi)
  566.             printnode(xp);
  567.         o_vinit(tp, xp);
  568.         return 1;
  569.     } else
  570.         return 0;
  571. }
  572.  
  573. /* set array size or fill array with zeros */
  574. a_fix(tp, nsee)
  575. register NODEP tp;
  576. {
  577.     int oldsize;
  578.  
  579.     if (tp->t_size) {
  580.         oldsize = tp->t_size / tp->n_tptr->t_size;
  581.         if (oldsize > nsee) {
  582.             o_nz(tp->n_tptr->t_size * (oldsize-nsee),
  583.                 tp->n_tptr->t_aln);
  584.         } else if (oldsize < nsee) {
  585.             error("too many init exprs");
  586.         }
  587.     } else
  588.         tp->t_size = nsee * tp->n_tptr->t_size;
  589. }
  590.  
  591. /* initialize up to max items of type tp */
  592. /* if max is 0, any number is okay */
  593.  
  594. inita(tp, maxi)
  595. NODEP tp;
  596. {
  597.     int nsee;
  598.  
  599.     nsee = g_init(tp);
  600.     if (nsee == 0)
  601.         return 0;
  602.  
  603.     while (cur->e_token == ',') {
  604.         if (nsee == maxi)
  605.             break;
  606.         fadvnode();
  607.         nsee += g_init(tp);
  608.     }
  609.     return nsee;
  610. }
  611.  
  612. long fldoffs = -1;
  613. int fldvalue = 0;
  614.  
  615. /* initialize (possible) structure */
  616. inits(np)
  617. register NODEP np;
  618. {
  619.     int see1;
  620.  
  621.     if (np->e_fldw)
  622.         see1 = fld_init(np,1);
  623.     else
  624.         see1 = g_init(np->n_tptr);
  625.     if (see1 == 0)
  626.         return 0;
  627.  
  628.     while (np->n_next) {
  629.         np = np->n_next;
  630.         if (cur->e_token == ',') {
  631.             fadvnode();
  632.             if (np->e_fldw)
  633.                 see1 = fld_init(np,1);
  634.             else {
  635.                 fld_put();
  636.                 see1 = g_init(np->n_tptr);
  637.             }
  638.         } else
  639.             see1 = 0;
  640.         if (see1 == 0)
  641.             if (np->e_fldw)
  642.                 fld_init(np,0);
  643.             else {
  644.                 fld_put();
  645.                 z_init(np->n_tptr);
  646.             }
  647.     }
  648.  
  649.     fld_put();
  650.     return 1;
  651. }
  652.  
  653. fld_put()
  654. {
  655.     if (fldoffs != -1)
  656.         out_fi(fldvalue);
  657.     fldoffs = -1;
  658. }
  659.  
  660. fld_init(np, valflg)
  661. NODEP np;
  662. {
  663.     NODEP xp;
  664.     NODEP assignx();
  665.     int val, width, woffs;
  666.     long soffs;
  667.     
  668.     width = np->e_fldw;
  669.     woffs = np->e_fldo;
  670.     soffs = np->e_offs;
  671.  
  672.     if (valflg == 0) {
  673.         val = 0;
  674.     } else {
  675.         xp = assignx();
  676.         if (xp) {
  677.             val = conxval(xp);
  678.         } else {
  679.             fld_put();
  680.             return 0;
  681.         }
  682.     }
  683.  
  684.     if (soffs != fldoffs) {
  685.         fld_put();
  686.         fldoffs = soffs;
  687.         fldvalue = 0;
  688.     }
  689.  
  690.     val &= ones(width);
  691.     val <<= woffs;
  692.     fldvalue |= val;
  693.  
  694.     return 1;
  695. }
  696.  
  697. z_init(tp)
  698. register NODEP tp;
  699. {
  700.     switch (tp->t_token) {
  701.     case '[':
  702.     case K_STRUCT:
  703.     case K_UNION:
  704.         o_nz(tp->t_size, tp->t_aln);
  705.         break;
  706.     default:
  707.         out_zi(tp);
  708.     }
  709. }
  710.