home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / sozobon / scsrc20 / hcc / p2.c < prev    next >
C/C++ Source or Header  |  1991-02-22  |  15KB  |  863 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.  *    p2.c
  12.  *
  13.  *    Expression tree routines.
  14.  *
  15.  *    Constant folding, typing of nodes, simple transformations.
  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 int xflags[];
  29. #define debug xflags['t'-'a']
  30.  
  31. extern nmerrors;
  32. NODEP bas_type();
  33. long convalue;
  34.  
  35. do_expr(np, cookie)
  36. NODE *np;
  37. {
  38.     if (np == NULL)
  39.         return;
  40. /*    include if want only one error at a time
  41.     if (nmerrors) {
  42.         freenode(np);
  43.         return;
  44.     }
  45. */
  46.     p2_expr(&np);
  47.     genx(np, cookie);
  48. }
  49.  
  50. p2_expr(npp)
  51. NODEP *npp;
  52. {
  53.     NODEP np = *npp;
  54.  
  55.     if (np == NULL) return;
  56.     if (debug > 1) {
  57.         printf("P2 enter");
  58.         printnode(np);
  59.     }
  60.     confold(npp,0);
  61.     np = *npp;
  62.     form_types(np);
  63.     if (debug) {
  64.         printf("p2_expr");
  65.         printnode(np);
  66.     }
  67.     return;
  68. }
  69.  
  70. form_types(np)
  71. NODEP np;
  72. {
  73.  
  74.     if (np == NULL) return;
  75.     switch (np->e_type) {
  76.     case E_SPEC:
  77.         switch (np->e_token) {    /* special cases */
  78.         case '.':
  79.         case ARROW:
  80.             form_types(np->n_left);
  81.             sel_type(np);
  82.             return;
  83.         case '(':
  84.             if (np->n_right) {
  85.                 form_types(np->n_right);    /* args */
  86.                 np->e_type = E_BIN;
  87.             } else
  88.                 np->e_type = E_UNARY;
  89.             fun_type(np);
  90.             return;
  91.         }
  92.         /* fall through */
  93.     case E_BIN:
  94.         form_types(np->n_left);
  95.         form_types(np->n_right);
  96.         b_types(np);
  97.         break;
  98.  
  99.     case E_UNARY:
  100.         form_types(np->n_left);
  101.         u_types(np);
  102.         break;
  103.  
  104.     case E_LEAF:
  105.         l_types(np);
  106.         break;
  107.     }
  108. }
  109.  
  110. /* (fun) (args) */
  111. fun_type(np)
  112. NODEP np;
  113. {
  114.     NODEP lp, typ;
  115.     NODEP allsyms(), new_fun();
  116.  
  117.     lp = np->n_left;
  118.     if (lp->e_token == ID) { /* may be new ID */
  119.         typ = allsyms(lp);
  120.         if (typ == NULL)
  121.             typ = new_fun(lp);
  122.         typ = typ->n_tptr;
  123.         lp->n_tptr = typ;
  124.         lp->n_flags |= N_COPYT;
  125.     } else {
  126.         form_types(lp);
  127.         typ = lp->n_tptr;
  128.     }
  129.     if (typ->t_token != '(') {    /* fun ret ? */
  130.         error("call non-fun");
  131.         goto bad;
  132.     }
  133.     typ = typ->n_tptr;
  134.     goto good;
  135. bad:
  136.     typ = bas_type(K_INT);
  137. good:
  138.     np->n_tptr = typ;
  139.     np->n_flags |= N_COPYT;
  140. }
  141.  
  142. /* (struct|union) (. or ->) ID */
  143. sel_type(xp)
  144. NODEP xp;
  145. {
  146.     NODEP np, sup;
  147.     int tok;
  148.     NODEP rv;
  149.     NODEP llook();
  150.  
  151.     np = xp->n_right;
  152.     sup = xp->n_left->n_tptr;
  153.     tok = xp->e_token;
  154.  
  155. /* already checked that np->e_token == ID */
  156.     if (tok == ARROW) {
  157.         if (sup->t_token != STAR) {
  158.             error("(non pointer)->");
  159.             goto bad;
  160.         }
  161.         sup = sup->n_tptr;
  162.     }
  163.     if (sup->t_token != K_STRUCT && sup->t_token != K_UNION) {
  164.         error("select non-struct");
  165.         goto bad;
  166.     }
  167.     rv = llook(sup->n_right, np);
  168.     if (rv == NULL) {
  169.         error("? member ID");
  170.         goto bad;
  171.     }
  172.     xp->e_offs = rv->e_offs;
  173.     if (rv->e_fldw) {
  174.         xp->e_fldw = rv->e_fldw;
  175.         xp->e_fldo = rv->e_fldo;
  176.     }
  177.     rv = rv->n_tptr;
  178.     goto good;
  179. bad:
  180.     rv = bas_type(K_INT);
  181. good:
  182.     xp->n_tptr = rv;
  183.     xp->n_flags |= N_COPYT;
  184.  
  185.     /* change to UNARY op */
  186.     xp->e_type = E_UNARY;
  187.     freenode(np);
  188.     xp->n_right = NULL;
  189.  
  190.     /* change ARY OF to PTR TO */
  191.     if (rv->t_token == '[')
  192.         see_array(xp);
  193. }
  194.  
  195. l_types(np)
  196. register NODE *np;
  197. {
  198.     NODEP allsyms();
  199.     register NODE *tp;
  200.  
  201.     switch (np->e_token) {
  202.     case ID:    /* already did see_id */
  203.         if (np->n_tptr->t_token == '[')    /* change to &ID */
  204.             see_array(np);
  205.         return;
  206.     case ICON:
  207.         tp = bas_type(icon_ty(np));
  208.         break;
  209.     case FCON:
  210.         tp = bas_type(K_DOUBLE);
  211.         break;
  212.     case SCON:
  213.         tp = bas_type(SCON);
  214.         break;
  215.     default:
  216.         errors("Weird leaf",np->n_name);
  217.     bad:
  218.         tp = bas_type(K_INT);
  219.     }
  220.     np->n_tptr = tp;
  221.     np->n_flags |= N_COPYT;
  222. }
  223.  
  224. u_types(np)
  225. NODEP np;
  226. {
  227.     NODEP tp;
  228.     NODEP lp = np->n_left;
  229.     NODEP normalty();
  230.  
  231.     tp = lp->n_tptr;    /* default */
  232.  
  233.     switch (np->e_token) {
  234.     case DOUBLE '+':
  235.     case DOUBLE '-':
  236.     case POSTINC:
  237.     case POSTDEC:
  238.         mustlval(lp);
  239.         mustty(lp, R_SCALAR);
  240.         if (tp->t_token == STAR)
  241.             np->e_offs = tp->n_tptr->t_size;
  242.         else
  243.             np->e_offs = 1;
  244.         break;
  245.     case STAR:
  246.         if (mustty(lp, R_POINTER)) goto bad;
  247.         tp = tp->n_tptr;
  248.         np->n_tptr = tp;
  249.         np->n_flags |= N_COPYT;
  250.  
  251.         /* Ary of to Ptr to */
  252.         if (tp->t_token == '[')
  253.             see_array(np);
  254.         return;
  255.     case UNARY '&':
  256.         mustlval(lp);
  257.         tp = allocnode();
  258.         tp->n_tptr = lp->n_tptr;
  259.         tp->n_flags |= N_COPYT;
  260.         tp->t_token = STAR;
  261.         sprintf(tp->n_name, "Ptr to");
  262.         tp->t_size = SIZE_P;
  263.         np->n_tptr = tp;
  264.         return;        /* no COPYT */
  265.     case UNARY '-':
  266.         mustty(lp, R_ARITH);
  267.         tp = normalty(lp, NULL);
  268.         break;
  269.     case TCONV:
  270.         if (np->n_tptr->t_token != K_VOID) {
  271.             mustty(lp, R_SCALAR);
  272.             mustty(np, R_SCALAR);
  273.         }
  274.         return;        /* type already specified */
  275.     case '!':
  276.         mustty(lp, R_SCALAR);
  277.         tp = bas_type(K_INT);
  278.         break;
  279.     case '~':
  280.         mustty(lp, R_INTEGRAL);
  281.         tp = normalty(lp, NULL);
  282.         break;
  283.     default:
  284.         error("bad unary type");
  285.     bad:
  286.         tp = bas_type(K_INT);
  287.     }
  288.     np->n_tptr = tp;
  289.     np->n_flags |= N_COPYT;
  290. }
  291.  
  292. b_types(np)
  293. NODEP np;
  294. {
  295.     NODEP tp;
  296.     NODEP lp, rp;
  297.     NODEP normalty(), addty(), colonty();
  298.     int op;
  299.  
  300.     op = np->e_token;
  301.     if (isassign(op)) {
  302.         mustlval(np->n_left);
  303.         op -= (ASSIGN 0);
  304.     }
  305.  
  306.     lp = np->n_left;
  307.     rp = np->n_right;
  308.     tp = bas_type(K_INT);
  309.     switch (op) {
  310.     case '*':
  311.     case '/':
  312.         mustty(lp, R_ARITH);
  313.         mustty(rp, R_ARITH);
  314.         tp = normalty(lp,rp);
  315.         break;
  316.     case '%':
  317.     case '&':
  318.     case '|':
  319.     case '^':
  320.         mustty(lp, R_INTEGRAL);
  321.         mustty(rp, R_INTEGRAL);
  322.         tp = normalty(lp,rp);
  323.         break;
  324.     case '+':
  325.     case '-':
  326.         mustty(lp, R_SCALAR);
  327.         mustty(rp, R_SCALAR);
  328.         tp = addty(np);
  329.         break;
  330.     case DOUBLE '<':
  331.     case DOUBLE '>':
  332.         mustty(lp, R_INTEGRAL);
  333.         mustty(rp, R_INTEGRAL);
  334.         tp = normalty(lp, NULL);
  335.         break;
  336.     case '<':
  337.     case '>':
  338.     case LTEQ:
  339.     case GTEQ:
  340.     case DOUBLE '=':
  341.     case NOTEQ:
  342.         mustty(lp, R_SCALAR);
  343.         mustty(rp, R_SCALAR);
  344.         chkcmp(np);
  345.         break;        /* INT */
  346.     case DOUBLE '&':
  347.     case DOUBLE '|':
  348.         mustty(lp, R_SCALAR);
  349.         mustty(rp, R_SCALAR);
  350.         break;        /* INT */
  351.     case '?':
  352.         mustty(lp, R_SCALAR);
  353.         tp = rp->n_tptr;
  354.         break;
  355.     case ':':
  356.         if (same_type(lp->n_tptr, rp->n_tptr)) {
  357.             tp = lp->n_tptr;
  358.             break;
  359.         }
  360.         mustty(lp, R_SCALAR);
  361.         mustty(rp, R_SCALAR);
  362.         tp = colonty(np);
  363.         break;
  364.     case '=':
  365.         mustlval(lp);
  366.         mustty(lp, R_ASSN);
  367.         asn_chk(lp->n_tptr, rp);
  368.         tp = lp->n_tptr;
  369.         break;
  370.     case ',':
  371.         tp = rp->n_tptr;
  372.         break;
  373.     default:
  374.         error("bad binary type");
  375.     bad:
  376.         tp = bas_type(K_INT);
  377.     }
  378.     if (isassign(np->e_token)) {
  379.         /* ignore normal result -- result is left type */
  380.         tp = lp->n_tptr;
  381.     }
  382.     np->n_tptr = tp;
  383.     np->n_flags |= N_COPYT;
  384. }
  385.  
  386. long
  387. conlval(np)
  388. NODEP np;
  389. {
  390.     long i;
  391.  
  392.     confold(&np,0);
  393.     if (np->e_token == ICON) {
  394.         i = np->e_ival;
  395.         freenode(np);
  396.         return i;
  397.     }
  398.     /* try the code generation */
  399.     form_types(np);
  400.     genx(np, FORVALUE);
  401.     return convalue;
  402. }
  403.  
  404. conxval(np)
  405. NODEP np;
  406. {
  407.     return (int)conlval(np);
  408. }
  409.  
  410. confold(npp,spec)
  411. NODEP *npp;
  412. {
  413.     NODEP np;
  414.     NODEP tp, onp;
  415.     int tok,spl,spr;
  416.     long l;
  417.  
  418.     np = *npp;
  419.     if (np == NULL) return;
  420.     switch (np->e_type) {
  421.     case E_LEAF:
  422.             lcanon(np,spec);
  423.             return;
  424.     case E_UNARY:
  425.             confold(&np->n_left,0);
  426.             ucanon(np);
  427.             return;
  428.     case E_BIN:
  429.             confold(&np->n_left,0);
  430.     /* delay confold on the right tree */
  431.             switch (np->e_token) {
  432.             case DOUBLE '|':
  433.                 l = np->n_left->e_ival;
  434.                 tp = np;
  435.                 goto l_or_r;
  436.             case DOUBLE '&':
  437.                 l = ! np->n_left->e_ival;
  438.                 tp = np;
  439.                 goto l_or_r;
  440.             case '?':
  441.                 l = np->n_left->e_ival;
  442.                 tp = np->n_right;    /* ':' node */
  443.         l_or_r:
  444.                 tok = np->n_left->e_token;
  445.                 if (tok != ICON) {
  446.                     confold(&np->n_right,0);
  447.                     return;
  448.                 }
  449.                 onp = np;
  450.                 if (l) {    /* take true side */
  451.                     np = tp->n_left;
  452.                     tp->n_left = NULL;
  453.                 } else {    /* take false side */
  454.                     np = tp->n_right;
  455.                     tp->n_right = NULL;
  456.                 }
  457.                 freenode(onp);
  458.                 confold(&np,0);
  459.                 *npp = np;
  460.                 return;
  461.             }
  462.             confold(&np->n_right,0);
  463.             bcanon(np);
  464.             if (np->e_flags & C_AND_A)
  465.                 b_assoc(np);
  466.             return;
  467.     case E_SPEC:
  468.         tok = np->e_token;
  469.         spl = spr = 0;
  470.         switch (tok) {
  471.         case '(':
  472.             spl = tok;    /* new name allowed */
  473.             break;
  474.         case '.':
  475.         case ARROW:
  476.             spr = tok;    /* look in struct sym.tab. */
  477.             break;
  478.         }
  479.         confold(&np->n_left,spl);
  480.         confold(&np->n_right,spr);
  481.         return;
  482.     }
  483. }
  484.  
  485. newicon(np,x,nf)
  486. NODE *np;
  487. long x;
  488. {
  489.     np->e_token = ICON;
  490.     np->e_ival = x;
  491.     np->e_flags = nf;
  492.     sprintf(np->n_name, "%ld", x);
  493.     np->e_type = E_LEAF;
  494.     if (np->n_left) {
  495.         freenode(np->n_left);
  496.         np->n_left = NULL;
  497.     }
  498.     if (np->n_right) {
  499.         freenode(np->n_right);
  500.         np->n_right = NULL;
  501.     }
  502. }
  503.  
  504. newfcon(np,x,nf)
  505. NODE *np;
  506. double x;
  507. {
  508.     np->e_token = FCON;
  509.     np->e_fval = x;
  510.     np->e_flags = nf;
  511.     sprintf(np->n_name, FLTFORM, x);
  512.     np->e_type = E_LEAF;
  513.     if (np->n_left) {
  514.         freenode(np->n_left);
  515.         np->n_left = NULL;
  516.     }
  517.     if (np->n_right) {
  518.         freenode(np->n_right);
  519.         np->n_right = NULL;
  520.     }
  521. }
  522.  
  523. /* LEAF */
  524. /* sptok is token if E_SPEC node is parent
  525.    and dont want to look at ID yet */
  526. lcanon(np,sptok)
  527. NODE *np;
  528. {
  529.     NODE *tp;
  530.     NODEP allsyms();
  531.     long x;
  532.  
  533.     if (np->e_token == ID) {
  534.         if (sptok)
  535.             return;
  536.         see_id(np);
  537.         return;
  538.     }
  539.     if (np->e_token == TSIZEOF) {
  540.         tp = np->n_tptr;
  541.         x = tp->t_size;
  542.         np->n_tptr = NULL;
  543.         if ((np->n_flags & N_COPYT) == 0)
  544.             freenode(tp);
  545.         newicon(np, x, 0);
  546.     }
  547. }
  548.  
  549. /* UNARY */
  550. ucanon(np)
  551. NODE *np;
  552. {
  553.     NODE *tp;
  554.     long x,l;
  555.     int lflags = 0;
  556.  
  557.     if (np->e_token == K_SIZEOF) {
  558.         tp = np->n_left;
  559.         confold(&tp,0);
  560.         form_types(tp);
  561.         tp = tp->n_tptr;
  562.         x = tp->t_size;
  563.         goto out;
  564.     }
  565.  
  566.     if (np->n_left->e_token == FCON) {
  567.         if (np->e_token == UNARY '-')
  568.             newfcon(np, -(np->n_left->e_fval));
  569.         return;
  570.     }
  571.     if (np->n_left->e_token != ICON)
  572.         return;
  573.     l = np->n_left->e_ival;
  574.     lflags = np->n_left->e_flags;
  575.     switch (np->e_token) {
  576.     case UNARY '-':
  577.             x = -l;        break;
  578.     case '~':
  579.             x = ~l;        break;
  580.     case '!':
  581.             x = !l;        break;
  582.     default:
  583.         return;
  584.     }
  585. out:
  586.     newicon(np, x, lflags);
  587. }
  588.  
  589. bcanon(np)
  590. register NODE *np;
  591. {
  592.     int ltok, rtok;
  593.     double l,r;
  594.     NODEP tp;
  595.  
  596.     ltok = np->n_left->e_token;
  597.     rtok = np->n_right->e_token;
  598.     if (ltok != ICON && ltok != FCON)
  599.         return;
  600.     if (rtok != ICON && rtok != FCON) {
  601.     /* left is ?CON, right is not */
  602.         if (np->e_flags & (C_AND_A|C_NOT_A)) {
  603.         /* reverse sides  - put CON on right */
  604.             tp = np->n_left;
  605.             np->n_left = np->n_right;
  606.             np->n_right = tp;
  607.             if (np->e_flags & C_NOT_A)
  608.                 swt_op(np);
  609.         }
  610.         return;
  611.     }
  612.     if (ltok == ICON && rtok == ICON) {
  613.         b2i(np);
  614.         return;
  615.     }
  616.     if (ltok == FCON)
  617.         l = np->n_left->e_fval;
  618.     else
  619.         l = (double)np->n_left->e_ival;
  620.     if (rtok == FCON)
  621.         r = np->n_right->e_fval;
  622.     else
  623.         r = (double)np->n_right->e_ival;
  624.     b2f(np,l,r);
  625. }
  626.  
  627. /* canon for assoc. & comm. op */
  628. /* this code will almost never be executed, but it was fun. */
  629. b_assoc(np)
  630. NODEP np;
  631. {
  632.     NODEP lp, rp;
  633.     int tok;
  634.  
  635.     lp = np->n_left;
  636.     if (lp->e_token != np->e_token)
  637.         return;
  638.     /* left is same op as np */
  639.     rp = np->n_right;
  640.     tok = lp->n_right->e_token;
  641.     if (tok != ICON && tok != FCON)
  642.         return;
  643.     /* left.right is ?CON */
  644.     tok = rp->e_token;
  645.     if (tok == ICON || tok == FCON) {
  646.         /* have 2 CONS l.r and r -- put together on r */
  647.         NODEP    ep;
  648.         ep = lp->n_left;
  649.         np->n_left = ep;
  650.         np->n_right = lp;
  651.         lp->n_left = rp;
  652.         /* can now fold 2 CONS */
  653.         bcanon(lp);
  654.     } else {
  655.         /* have 1 CON at l.r -- move to top right */
  656.         NODEP    kp;
  657.         kp = lp->n_right;
  658.         lp->n_right = rp;
  659.         np->n_right = kp;
  660.     }
  661. }
  662.  
  663. /* switch pseudo-commutative op */
  664. swt_op(np)
  665. NODEP np;
  666. {
  667.     int newtok;
  668.     char *newnm;
  669.  
  670.     switch (np->e_token) {
  671.     case '<':    newtok = '>';    newnm = ">";    break;
  672.     case '>':    newtok = '<';    newnm = "<";    break;
  673.     case LTEQ:    newtok = GTEQ;    newnm = ">=";    break;
  674.     case GTEQ:    newtok = LTEQ;    newnm = "<=";    break;
  675.     default:
  676.         return;
  677.     }
  678.     np->e_token = newtok;
  679.     strcpy(np->n_name, newnm);
  680. }
  681.  
  682. /* BINARY 2 ICON's */
  683. b2i(np)
  684. register NODE *np;
  685. {
  686.     register long l,r,x;
  687.     int newflags,lflags;
  688.  
  689.     newflags = 0;
  690.  
  691.     r = np->n_right->e_ival;
  692.     newflags = np->n_right->e_flags;
  693.  
  694.     l = np->n_left->e_ival;
  695.     lflags = np->n_left->e_flags;
  696.     newflags = newflags>lflags ? newflags : lflags;
  697.  
  698.     switch (np->e_token) {
  699.     case '+':
  700.             x = l+r;    break;
  701.     case '-':
  702.             x = l-r;    break;
  703.     case '*':
  704.             x = l*r;    break;
  705.     case '/':
  706.             x = l/r;    break;
  707.     case '%':
  708.             x = l%r;    break;
  709.     case '>':
  710.             x = l>r;    break;
  711.     case '<':
  712.             x = l<r;    break;
  713.     case LTEQ:
  714.             x = l<=r;    break;
  715.     case GTEQ:
  716.             x = l>=r;    break;
  717.     case DOUBLE '=':
  718.             x = l==r;    break;
  719.     case NOTEQ:
  720.             x = l!=r;    break;
  721.     case '&':
  722.             x = l&r;    break;
  723.     case '|':
  724.             x = l|r;    break;
  725.     case '^':
  726.             x = l^r;    break;
  727.     case DOUBLE '<':
  728.             x = l<<r;    break;
  729.     case DOUBLE '>':
  730.             x = l>>r;    break;
  731.     default:
  732.         return;
  733.     }
  734.     newicon(np, x, newflags);
  735. }
  736.  
  737. /* BINARY 2 FCON's */
  738. b2f(np,l,r)
  739. register NODE *np;
  740. double l,r;
  741. {
  742.     register double x;
  743.     int ix, isint;
  744.  
  745.     isint = 0;
  746.  
  747.     switch (np->e_token) {
  748.     case '+':
  749.             x = l+r;    break;
  750.     case '-':
  751.             x = l-r;    break;
  752.     case '*':
  753.             x = l*r;    break;
  754.     case '/':
  755.             x = l/r;    break;
  756.     case '>':
  757.             ix = l>r;    isint++;    break;
  758.     case '<':
  759.             ix = l<r;    isint++;    break;
  760.     case LTEQ:
  761.             ix = l>=r;    isint++;    break;
  762.     case GTEQ:
  763.             ix = l<=r;    isint++;    break;
  764.     case DOUBLE '=':
  765.             ix = l==r;    isint++;    break;
  766.     case NOTEQ:
  767.             ix = l!=r;    isint++;    break;
  768.     default:
  769.         return;
  770.     }
  771.     if (isint)
  772.         newicon(np, (long)ix, 0);
  773.     else
  774.         newfcon(np, x);
  775. }
  776.  
  777. same_type(a,b)
  778. register NODE *a, *b;
  779. {
  780. more:
  781.     if (a == b)
  782.         return 1;
  783.     if (a == NULL || b == NULL)
  784.         return 0;
  785.     if (a->t_token != b->t_token)
  786.         return 0;
  787.     if (a->t_token != STAR && a->t_size != b->t_size)
  788.         return 0;
  789.     a = a->n_tptr;
  790.     b = b->n_tptr;
  791.     goto more;
  792. }
  793.  
  794. see_id(np)
  795. NODEP np;
  796. {
  797.     NODEP tp;
  798.     NODEP allsyms(), def_type();
  799.  
  800.     tp = allsyms(np);
  801.     if (tp == NULL) {
  802.         errorn("undefined:", np);
  803.         tp = def_type();
  804.         goto out;
  805.     }
  806.     switch (tp->e_sc) {
  807.     case ENUM_SC:
  808.         newicon(np, tp->e_ival, 0);
  809.         return;
  810.     case K_REGISTER:
  811.         np->e_rno = tp->e_rno;
  812.         /* fall through */
  813.     default:
  814.         np->e_sc = tp->e_sc;
  815.         np->e_offs = tp->e_offs;
  816.         tp = tp->n_tptr;
  817.     }
  818. out:
  819.     np->n_tptr = tp;
  820.     np->n_flags |= N_COPYT;
  821.  
  822.     /* special conversions */
  823.     if (tp->t_token == '(')
  824.         insptrto(np);
  825. }
  826.  
  827. insptrto(np)
  828. NODEP np;
  829. {
  830.     NODEP op, copyone();
  831.  
  832.     op = copyone(np);
  833.  
  834.     np->n_left = op;
  835.     np->e_token = UNARY '&';
  836.     np->e_type = E_UNARY;
  837.     strcpy(np->n_name, "&fun");
  838.     np->n_flags &= ~N_COPYT;
  839. }
  840.  
  841. /* np points to ID or STAR or '.' node
  842.     tptr is a COPY
  843.     tptr token is '[' */
  844.  
  845. see_array(np)
  846. NODEP np;
  847. {
  848.     NODEP tp, copyone();
  849.  
  850.     tp = copyone(np);
  851.     tp->n_left = np->n_left;
  852.     tp->n_tptr = tp->n_tptr->n_tptr;
  853.  
  854.     np->n_left = tp;
  855.     np->e_token = UNARY '&';
  856.     np->e_type = E_UNARY;
  857.     strcpy(np->n_name, "&ary");
  858.     arytoptr(np);
  859. /* leave old size
  860.     np->n_tptr->t_size = SIZE_P;
  861. */
  862. }
  863.