home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v92.tgz / v92.tar / v92 / src / icont / tsym.c < prev    next >
C/C++ Source or Header  |  1996-03-22  |  13KB  |  532 lines

  1. /*
  2.  * tsym.c -- functions for symbol table management.
  3.  */
  4.  
  5. #include "::h:gsupport.h"
  6. #include "tproto.h"
  7. #include "tglobals.h"
  8. #include "ttoken.h"
  9. #include "tsym.h"
  10. #include "keyword.h"
  11.  
  12. #ifndef VarTran
  13. #include "lfile.h"
  14. #endif                    /* VarTran */
  15.  
  16. /*
  17.  * Prototypes.
  18.  */
  19.  
  20. hidden struct    tgentry *alcglob
  21.    Params((struct tgentry *blink, char *name,int flag,int nargs));
  22. hidden struct    tcentry *alclit    
  23.    Params((struct tcentry *blink, char *name, int len,int flag));
  24. hidden struct    tlentry *alcloc    
  25.    Params((struct tlentry *blink, char *name,int flag));
  26. hidden struct    tcentry *clookup    Params((char *id,int flag));
  27. hidden struct    tgentry *glookup    Params((char *id));
  28. hidden struct    tlentry *llookup    Params((char *id));
  29. hidden novalue    putglob
  30.    Params((char *id,int id_type, int n_args));
  31.  
  32. #ifdef DeBugTrans
  33. novalue    cdump    Params((noargs));
  34. novalue    gdump    Params((noargs));
  35. novalue    ldump    Params((noargs));
  36. #endif                    /* DeBugTrans */
  37.  
  38.  
  39. #ifndef VarTran
  40.  
  41. /*
  42.  * Keyword table.
  43.  */
  44.  
  45. struct keyent {
  46.    char *keyname;
  47.    int keyid;
  48.    };
  49.  
  50. #define KDef(p,n) Lit(p), n,
  51. static struct keyent keytab[] = {
  52. #include "::h:kdefs.h"
  53.    NULL, -1
  54. };
  55.  
  56. /*
  57.  * loc_init - clear the local and constant symbol tables.
  58.  */
  59.  
  60. novalue loc_init()
  61.    {
  62.    struct tlentry *lptr, *lptr1;
  63.    struct tcentry *cptr, *cptr1;
  64.    int i;
  65.  
  66.    /*
  67.     * Clear local table, freeing entries.
  68.     */
  69.    for (i = 0; i < lhsize; i++) {
  70.       for (lptr = lhash[i]; lptr != NULL; lptr = lptr1) {
  71.           lptr1 = lptr->l_blink;
  72.           free((char *)lptr);
  73.           }
  74.        lhash[i] = NULL;
  75.        }
  76.    lfirst = NULL;
  77.    llast = NULL;
  78.  
  79.    /*
  80.     * Clear constant table, freeing entries.
  81.     */
  82.    for (i = 0; i < lchsize; i++) {
  83.       for (cptr = chash[i]; cptr != NULL; cptr = cptr1) {
  84.           cptr1 = cptr->c_blink;
  85.           free((char *)cptr);
  86.           }
  87.        chash[i] = NULL;
  88.        }
  89.    cfirst = NULL;
  90.    clast = NULL;
  91.    }
  92.  
  93. /*
  94.  * install - put an identifier into the global or local symbol table.
  95.  *  The basic idea here is to look in the right table and install
  96.  *  the identifier if it isn't already there.  Some semantic checks
  97.  *  are performed.
  98.  */
  99. novalue install(name, flag, argcnt)
  100. char *name;
  101. int flag, argcnt;
  102.    {
  103.    union {
  104.       struct tgentry *gp;
  105.       struct tlentry *lp;
  106.       } p;
  107.  
  108.    switch (flag) {
  109.       case F_Global:    /* a variable in a global declaration */
  110.          if ((p.gp = glookup(name)) == NULL)
  111.             putglob(name, flag, argcnt);
  112.          else
  113.             p.gp->g_flag |= flag;
  114.          break;
  115.  
  116.       case F_Proc|F_Global:    /* procedure declaration */
  117.       case F_Record|F_Global:    /* record declaration */
  118.       case F_Builtin|F_Global:    /* external declaration */
  119.          if ((p.gp = glookup(name)) == NULL)
  120.             putglob(name, flag, argcnt);
  121.          else if ((p.gp->g_flag & (~F_Global)) == 0) { /* superfluous global
  122.                                declaration for
  123.                                record or proc */
  124.             p.gp->g_flag |= flag;
  125.             p.gp->g_nargs = argcnt;
  126.             }
  127.          else            /* the user can't make up his mind */
  128.             tfatal("inconsistent redeclaration", name);
  129.          break;
  130.  
  131.       case F_Static:    /* static declaration */
  132.       case F_Dynamic:    /* local declaration (possibly implicit?) */
  133.       case F_Argument:    /* formal parameter */
  134.          if ((p.lp = llookup(name)) == NULL)
  135.             putloc(name,flag);
  136.          else if (p.lp->l_flag == flag) /* previously declared as same type */
  137.             tfatal("redeclared identifier", name);
  138.          else        /* previously declared as different type */
  139.             tfatal("inconsistent redeclaration", name);
  140.          break;
  141.  
  142.       default:
  143.          tsyserr("install: unrecognized symbol table flag.");
  144.       }
  145.    }
  146.  
  147. /*
  148.  * putloc - make a local symbol table entry and return the index
  149.  *  of the entry in lhash.  alcloc does the work if there is a collision.
  150.  */
  151. int putloc(id,id_type)
  152. char *id;
  153. int id_type;
  154.    {
  155.    register struct tlentry *ptr;
  156.  
  157.    if ((ptr = llookup(id)) == NULL) {    /* add to head of hash chain */
  158.       ptr = lhash[lhasher(id)];
  159.       lhash[lhasher(id)] = alcloc(ptr, id, id_type);
  160.       return lhash[lhasher(id)]->l_index;
  161.       }
  162.    return ptr->l_index;
  163.    }
  164.  
  165. /*
  166.  * putglob makes a global symbol table entry. alcglob does the work if there
  167.  *  is a collision.
  168.  */
  169.  
  170. static novalue putglob(id, id_type, n_args)
  171. char *id;
  172. int id_type, n_args;
  173.    {
  174.    register struct tgentry *ptr;
  175.  
  176.    if ((ptr = glookup(id)) == NULL) {     /* add to head of hash chain */
  177.       ptr = ghash[ghasher(id)];
  178.       ghash[ghasher(id)] = alcglob(ptr, id, id_type, n_args);
  179.       }
  180.    }
  181.  
  182. /*
  183.  * putlit makes a constant symbol table entry and returns the table "index"
  184.  *  of the constant.  alclit does the work if there is a collision.
  185.  */
  186. int putlit(id, idtype, len)
  187. char *id;
  188. int len, idtype;
  189.    {
  190.    register struct tcentry *ptr;
  191.  
  192.    if ((ptr = clookup(id,idtype)) == NULL) {   /* add to head of hash chain */
  193.       ptr = chash[chasher(id)];
  194.       chash[chasher(id)] = alclit(ptr, id, len, idtype);
  195.       return chash[chasher(id)]->c_index;
  196.       }
  197.    return ptr->c_index;
  198.    }
  199.  
  200. /*
  201.  * llookup looks up id in local symbol table and returns pointer to
  202.  *  to it if found or NULL if not present.
  203.  */
  204.  
  205. static struct tlentry *llookup(id)
  206. char *id;
  207.    {
  208.    register struct tlentry *ptr;
  209.  
  210.    ptr = lhash[lhasher(id)];
  211.    while (ptr != NULL && ptr->l_name != id)
  212.       ptr = ptr->l_blink;
  213.    return ptr;
  214.    }
  215.  
  216. /*
  217.  * glookup looks up id in global symbol table and returns pointer to
  218.  *  to it if found or NULL if not present.
  219.  */
  220. static struct tgentry *glookup(id)
  221. char *id;
  222.    {
  223.    register struct tgentry *ptr;
  224.  
  225.    ptr = ghash[ghasher(id)];
  226.    while (ptr != NULL && ptr->g_name != id) {
  227.       ptr = ptr->g_blink;
  228.       }
  229.    return ptr;
  230.    }
  231.  
  232. /*
  233.  * clookup looks up id in constant symbol table and returns pointer to
  234.  *  to it if found or NULL if not present.
  235.  */
  236. static struct tcentry *clookup(id,flag)
  237. char *id;
  238. int flag;
  239.    {
  240.    register struct tcentry *ptr;
  241.  
  242.    ptr = chash[chasher(id)];
  243.    while (ptr != NULL && (ptr->c_name != id || ptr->c_flag != flag))
  244.       ptr = ptr->c_blink;
  245.  
  246.    return ptr;
  247.    }
  248.  
  249. /*
  250.  * klookup looks up keyword named by id in keyword table and returns
  251.  *  its number (keyid).
  252.  */
  253. int klookup(id)
  254. register char *id;
  255.    {
  256.    register struct keyent *kp;
  257.  
  258.    for (kp = keytab; kp->keyid >= 0; kp++)
  259.       if (strcmp(kp->keyname,id) == 0)
  260.          return (kp->keyid);
  261.  
  262.    return 0;
  263.    }
  264.  
  265. #ifdef DeBugTrans
  266. /*
  267.  * ldump displays local symbol table to stdout.
  268.  */
  269.  
  270. novalue ldump()
  271.    {
  272.    register int i;
  273.    register struct tlentry *lptr;
  274.    int n;
  275.  
  276.    if (llast == NULL)
  277.       n = 0;
  278.    else
  279.       n = llast->l_index + 1;
  280.    fprintf(stderr,"Dump of local symbol table (%d entries)\n", n);
  281.    fprintf(stderr," loc   blink   id          (name)      flags\n");
  282.    for (i = 0; i < lhsize; i++)
  283.       for (lptr = lhash[i]; lptr != NULL; lptr = lptr->l_blink)
  284.          fprintf(stderr,"%5d  %5d  %5d    %20s  %7o\n", lptr->l_index,
  285.         lptr->l_blink, lptr->l_name, lptr->l_name, lptr->l_flag);
  286.    fflush(stderr);
  287.  
  288.    }
  289.  
  290. /*
  291.  * gdump displays global symbol table to stdout.
  292.  */
  293.  
  294. novalue gdump()
  295.    {
  296.    register int i;
  297.    register struct tgentry *gptr;
  298.    int n;
  299.  
  300.    if (glast == NULL)
  301.       n = 0;
  302.    else
  303.       n = glast->g_index + 1;
  304.    fprintf(stderr,"Dump of global symbol table (%d entries)\n", n);
  305.    fprintf(stderr," loc   blink   id          (name)      flags      nargs\n");
  306.    for (i = 0; i < ghsize; i++)
  307.       for (gptr = ghash[i]; gptr != NULL; gptr = gptr->g_blink)
  308.          fprintf(stderr,"%5d  %5d  %5d    %20s  %7o   %8d\n", gptr->g_index,
  309.         gptr->g_blink, gptr->g_name, gptr->g_name,
  310.         gptr->g_flag, gptr->g_nargs);
  311.    fflush(stderr);
  312.    }
  313.  
  314. /*
  315.  * cdump displays constant symbol table to stdout.
  316.  */
  317.  
  318. novalue cdump()
  319.    {
  320.    register int i;
  321.    register struct tcentry *cptr;
  322.    int n;
  323.  
  324.    if (clast == NULL)
  325.       n = 0;
  326.    else
  327.       n = clast->c_index + 1;
  328.    fprintf(stderr,"Dump of constant symbol table (%d entries)\n", n);
  329.    fprintf(stderr," loc   blink   id          (name)      flags\n");
  330.    for (i = 0; i < lchsize; i++)
  331.       for (cptr = chash[i]; cptr != NULL; cptr = cptr->c_blink)
  332.          fprintf(stderr,"%5d  %5d  %5d    %20s  %7o\n", cptr->c_index,
  333.         cptr->c_blink, cptr->c_name, cptr->c_name, cptr->c_flag);
  334.    fflush(stderr);
  335.    }
  336. #endif                    /* DeBugTrans */
  337.  
  338. /*
  339.  * alcloc allocates a local symbol table entry, fills in fields with
  340.  *  specified values and returns the new entry.  
  341.  */
  342. static struct tlentry *alcloc(blink, name, flag)
  343. struct tlentry *blink;
  344. char *name;
  345. int flag;
  346.    {
  347.    register struct tlentry *lp;
  348.  
  349.    lp = NewStruct(tlentry);
  350.    lp->l_blink = blink;
  351.    lp->l_name = name;
  352.    lp->l_flag = flag;
  353.    lp->l_next = NULL;
  354.    if (lfirst == NULL) {
  355.       lfirst = lp;
  356.       lp->l_index = 0;
  357.       }
  358.    else {
  359.       llast->l_next = lp;
  360.       lp->l_index = llast->l_index + 1;
  361.       }
  362.    llast = lp;
  363.    return lp;
  364.    }
  365.  
  366. /*
  367.  * alcglob allocates a global symbol table entry, fills in fields with
  368.  *  specified values and returns offset of new entry.  
  369.  */
  370. static struct tgentry *alcglob(blink, name, flag, nargs)
  371. struct tgentry *blink;
  372. char *name;
  373. int flag, nargs;
  374.    {
  375.    register struct tgentry *gp;
  376.  
  377.    gp = NewStruct(tgentry);
  378.    gp->g_blink = blink;
  379.    gp->g_name = name;
  380.    gp->g_flag = flag;
  381.    gp->g_nargs = nargs;
  382.    gp->g_next = NULL;
  383.    if (gfirst == NULL) {
  384.       gfirst = gp;
  385.       gp->g_index = 0;
  386.       }
  387.    else {
  388.       glast->g_next = gp;
  389.       gp->g_index = glast->g_index + 1;
  390.       }
  391.    glast = gp;
  392.    return gp;
  393.    }
  394.  
  395. /*
  396.  * alclit allocates a constant symbol table entry, fills in fields with
  397.  *  specified values and returns the new entry.  
  398.  */
  399. static struct tcentry *alclit(blink, name, len, flag)
  400. struct tcentry *blink;
  401. char *name;
  402. int len, flag;
  403.    {
  404.    register struct tcentry *cp;
  405.  
  406.    cp = NewStruct(tcentry);
  407.    cp->c_blink = blink;
  408.    cp->c_name = name;
  409.    cp->c_length = len;
  410.    cp->c_flag = flag;
  411.    cp->c_next = NULL;
  412.    if (cfirst == NULL) {
  413.       cfirst = cp;
  414.       cp->c_index = 0;
  415.       }
  416.    else {
  417.       clast->c_next = cp;
  418.       cp->c_index = clast->c_index + 1;
  419.       }
  420.    clast = cp;
  421.    return cp;
  422.    }
  423.  
  424. /*
  425.  * lout dumps local symbol table to fd, which is a .u1 file.
  426.  */
  427. novalue lout(fd)
  428. FILE *fd;
  429.    {
  430.    register struct tlentry *lp;
  431.  
  432.    for (lp = lfirst; lp != NULL; lp = lp->l_next)
  433.       writecheck(fprintf(fd, "\tlocal\t%d,%06o,%s\n",
  434.          lp->l_index, lp->l_flag, lp->l_name));
  435.    }
  436.  
  437. /*
  438.  * constout dumps constant symbol table to fd, which is a .u1 file.
  439.  */
  440. novalue constout(fd)
  441. FILE *fd;
  442.    {
  443.    register int l;
  444.    register char *c;
  445.    register struct tcentry *cp;
  446.  
  447.    for (cp = cfirst; cp != NULL; cp = cp->c_next) {
  448.       writecheck(fprintf(fd, "\tcon\t%d,%06o", cp->c_index, cp->c_flag));
  449.       if (cp->c_flag & F_IntLit)
  450.          writecheck(fprintf(fd,",%d,%s\n",(int)strlen(cp->c_name),cp->c_name));
  451.       else if (cp->c_flag & F_RealLit)
  452.          writecheck(fprintf(fd, ",%s\n", cp->c_name));
  453.       else {
  454.          c = cp->c_name;
  455.          l = cp->c_length;
  456.          writecheck(fprintf(fd, ",%d", l));
  457.          while (l--)
  458.             writecheck(fprintf(fd, ",%03o", *c++ & 0377));
  459.          writecheck(putc('\n', fd));
  460.          }
  461.       }
  462.    }
  463.  
  464. /*
  465.  * rout dumps a record declaration for name to file fd, which is a .u2 file.
  466.  */
  467. novalue rout(fd,name)
  468. FILE *fd;
  469. char *name;
  470.    {
  471.    register struct tlentry *lp;
  472.    int n;
  473.  
  474.    if (llast == NULL)
  475.       n = 0;
  476.    else
  477.       n = llast->l_index + 1;
  478.    writecheck(fprintf(fd, "record\t%s,%d\n", name, n));
  479.    for (lp = lfirst; lp != NULL; lp = lp->l_next)
  480.       writecheck(fprintf(fd, "\t%d,%s\n", lp->l_index, lp->l_name));
  481.    }
  482.  
  483. /*
  484.  * gout writes various items to fd, which is a .u2 file.  These items
  485.  *  include: implicit status, tracing activation, link directives,
  486.  *  invocable directives, and the global table.
  487.  */
  488. novalue gout(fd)
  489. FILE *fd;
  490.    {
  491.    register char *name;
  492.    register struct tgentry *gp;
  493.    int n;
  494.    struct lfile *lfl;
  495.    struct invkl *ivl;
  496.    
  497.    if (uwarn)
  498.       name = "error";
  499.    else
  500.       name = "local";
  501.    writecheck(fprintf(fd, "impl\t%s\n", name));
  502.    if (trace)
  503.       writecheck(fprintf(fd, "trace\n"));
  504.    
  505.    lfl = lfiles;
  506.    while (lfl) {
  507.  
  508. #if MVS
  509.       writecheck(fprintf(fd,"link\t%s\n",lfl->lf_name));
  510. #else                    /* MVS */
  511.       writecheck(fprintf(fd,"link\t%s.u1\n",lfl->lf_name));
  512. #endif                    /* MVS */
  513.  
  514.       lfl = lfl->lf_link;
  515.       }
  516.    lfiles = 0;
  517.  
  518.    for (ivl = invkls; ivl != NULL; ivl = ivl->iv_link)
  519.       writecheck(fprintf(fd, "invocable\t%s\n", ivl->iv_name));
  520.    invkls = NULL;
  521.  
  522.    if (glast == NULL)
  523.       n = 0;
  524.    else
  525.       n = glast->g_index + 1;
  526.    writecheck(fprintf(fd, "global\t%d\n", n));
  527.    for (gp = gfirst; gp != NULL; gp = gp->g_next)
  528.       writecheck(fprintf(fd, "\t%d,%06o,%s,%d\n", gp->g_index, gp->g_flag,
  529.          gp->g_name, gp->g_nargs));
  530.    }
  531. #endif                    /* VarTran */
  532.