home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 357_01 / cstar1.exe / ST.C < prev    next >
C/C++ Source or Header  |  1991-06-18  |  9KB  |  448 lines

  1. /*
  2.     C* --  symbol table routines.
  3.  
  4.     source:  st.c
  5.     started: November 4, 1985
  6.     version:
  7.         December 24, 1986
  8.         March 7, 1989
  9.  
  10.     PUBLIC DOMAIN SOFTWARE
  11.  
  12.     The CSTAR program was placed in    the public domain on June 15, 1991,
  13.     by its author and sole owner,
  14.  
  15.         Edward K. Ream
  16.         1617 Monroe Street
  17.         Madison, WI 53711
  18.         (608) 257-0802
  19.  
  20.     CSTAR may be used for any commercial or non-commercial purpose.
  21.  
  22.     See cstar.h or cstar.c for a DISCLAIMER OF WARRANTIES.
  23. */
  24.  
  25. #include "cstar.h"
  26.  
  27. /*
  28.     Externally visible routines:
  29. */
  30. struct st_node * ast_lookup    (char * symbol);
  31.  
  32. struct st_node * gst_enter     (char * symbol,
  33.                 struct type_node * type, int class);
  34. static int     gst_hash     (char * symbol);
  35. struct st_node * gst_lookup     (char * symbol);
  36. struct st_node * lst_enter     (char * symbol,
  37.                 struct type_node * type, int class);
  38. static int     lst_hash     (char * symbol);
  39. void         lst_init    (void);
  40. struct st_node * lst_lookup     (char * symbol);
  41. struct st_node * rst_lookup    (char * symbol);
  42. struct st_node * rst_enter     (char * symbol,
  43.                 struct type_node * type, int class);
  44. void         st_init    (void);
  45. struct st_node * st_lookup    (char * symbol);
  46.  
  47. /*
  48.     Internal routines:
  49. */
  50. static void    st_show    (struct st_node * st_ht[], int size);
  51. static void    st_dump    (void);
  52.  
  53. /*
  54.     Define the hash tables.
  55. */
  56. #define G_PRIME 101
  57. #define L_PRIME 101
  58. static struct st_node * gst_ht [G_PRIME];
  59. static struct st_node * lst_ht [L_PRIME];
  60.  
  61. /*
  62.     Dump all symbols of both symbol tables.
  63.     This function is used for debugging only.
  64. */
  65.  
  66. #ifdef SHERLOCK
  67. static void
  68. st_dump(void)
  69. {
  70.     TRACEP("st_dump",
  71.         printf("&gst_ht=%p, &lst_ht=%p, ", gst_ht,lst_ht);
  72.         printf("*gst_ht=%p, *lst_ht=%p\n", *gst_ht, *lst_ht));
  73.  
  74.     printf(">> Global symbols:\n");
  75.     st_show(gst_ht, G_PRIME);
  76.     printf("\n>> Local symbols:\n");
  77.     st_show(lst_ht, L_PRIME);
  78.     printf("\n");
  79. }
  80.  
  81. static void
  82. st_show(struct st_node * st_ht[], int size)
  83. {
  84.     register int i;
  85.     register struct st_node *bp;
  86.  
  87.     for (i = 0; i < size; i++) {
  88.         bp = st_ht[i];
  89.         if (bp != NULL) {
  90.             TRACEP("st_dump",
  91.                 printf("st_show: st_ht [%d] = %p\n", i, bp));
  92.  
  93.             do {
  94.                 TRACEP("st_dump",
  95.                     printf("st_show: typenode %p, next %p\n",
  96.                     bp -> st_type, bp -> st_next));
  97.  
  98.                 printf("%s/%s: ",bp -> st_name,bp -> st_alias);
  99.                 pr_sclass(bp -> st_sclass);
  100.                                 printf(" ");
  101.                 if (bp -> st_type != NULL) {
  102.                     pr_type(bp -> st_type);
  103.                     printf("\n");
  104.                 }
  105.                 else {
  106.                     printf("type <NULL>\n");
  107.                 }
  108.  
  109.             } while (bp = bp -> st_next);
  110.         }
  111.     }
  112. }
  113. #endif /* SHERLOCK */
  114.  
  115. /*
  116.     Look up a symbol in the local symbol table.
  117.     If not found, try the global symbol table.
  118. */
  119. struct st_node *
  120. st_lookup(register char * symbol)
  121. {
  122.     register struct st_node * p;
  123.     struct st_node * gst_lookup();
  124.     struct st_node * lst_lookup();
  125.  
  126.     TRACEPB("st_lookup", printf("(%s)\n", symbol));
  127.  
  128.     p = lst_lookup(symbol);
  129.     if (p != NULL) {
  130.         RETURN_PTR("st_lookup", p);
  131.     }
  132.     else {
  133.         RETURN_PTR("st_lookup", gst_lookup(symbol));
  134.     }
  135. }
  136.  
  137. /*
  138.     Look up a symbol in any symbol tables are appropriate to
  139.     scope.s_scope.
  140. */
  141. struct st_node *
  142. ast_lookup(symbol)
  143. register char * symbol;
  144. {
  145.     register struct st_node * p;
  146.     struct st_node * gst_lookup();
  147.     struct st_node * lst_lookup();
  148.  
  149.     TRACEPB("ast_lookup", printf("(%s)\n", symbol));
  150.  
  151.     switch(scope.s_scope) {
  152.     case PROTO_SCOPE:
  153.     case BLOCK_SCOPE:
  154.         /* try the block symbol table ... */
  155.         /*
  156.         if (p != NULL) {
  157.             break;
  158.         }
  159.         */
  160.         /* FALL_THROUGH */
  161.  
  162.     case FNDEF_SCOPE:
  163.         p = lst_lookup(symbol);
  164.         if (p != NULL) {
  165.             break;
  166.         }
  167.         /* FALL_THROUGH */
  168.  
  169.     case FILE_SCOPE:
  170.         p = gst_lookup(symbol);
  171.         break;
  172.     default:
  173.         p = NULL;
  174.         t_error("ast_lookup: unknown scope");
  175.     }
  176.     RETURN_PTR("ast_lookup", p);
  177. }
  178.  
  179. /*
  180.     Restricted lookup:
  181.     Look up a symbol in the symbol table local to scope.s_scope
  182.     It happens that this process will find the formals from the block
  183.     scope, although this may not be correct.
  184. */
  185. struct st_node *
  186. rst_lookup(symbol)
  187. register char * symbol;
  188. {
  189.     register struct st_node * p;
  190.  
  191.     TRACEPB("rst_lookup", printf("(%s)\n", symbol));
  192.  
  193.     switch(scope.s_scope) {
  194.     case PROTO_SCOPE:
  195.     case BLOCK_SCOPE:
  196.     case FNDEF_SCOPE:
  197.         RETURN_PTR("rst_lookup", lst_lookup(symbol));
  198.  
  199.     case FILE_SCOPE:
  200.         RETURN_PTR("rst_lookup", gst_lookup(symbol));
  201.     default:
  202.         t_error("rst_lookup: unknown scope");
  203.     }
  204.     RETURN_PTR("rst_lookup", NULL);
  205. }
  206.  
  207. /*
  208.     Place a symbol in whatever table is appropriate for 
  209.     scope.s_scope.
  210. */
  211. struct st_node *
  212. rst_enter (symbol, type, class)
  213. register char * symbol;
  214. struct type_node * type;
  215. int class;
  216. {
  217.     TRACEPB("rst_enter", printf("(%s, %p, %d)\n", 
  218.         symbol, type, class));
  219.  
  220.     switch(scope.s_scope) {
  221.     case PROTO_SCOPE:
  222.     case BLOCK_SCOPE:
  223.     case FNDEF_SCOPE:
  224.         RETURN_PTR("rst_enter", lst_enter(symbol, type, class));
  225.  
  226.     case FILE_SCOPE:
  227.         RETURN_PTR("rst_enter", gst_enter(symbol, type, class));
  228.  
  229.     default:
  230.         t_error("rst_enter: unknown scope");
  231.     }
  232.     RETURN_PTR("rst_enter", NULL);
  233. }
  234.  
  235. /*
  236.     Place a symbol in the global symbol table.
  237.     Return a pointer to the created node.
  238.     NOTE: gst_enter ought to be combined with lst_enter,
  239.     which would make things more orderly and make it easier to
  240.     adopt ANSI symbol tables.
  241.     
  242. */
  243. struct st_node *
  244. gst_enter (register char * symbol, struct type_node * type, int class)
  245. {
  246.     register struct st_node **bp0, *bp1;
  247.  
  248.     TRACEPB("gst_enter", printf("(%s, %p, %d)\n", 
  249.         symbol, type, class));
  250.  
  251.     if (symbol == NULL) {
  252.         t_error("gst_enter: internal: NULL symbol");
  253.         symbol = "";
  254.     }
  255.  
  256.     /* Dynamically allocate space for node. */
  257.     bp1 = CAST(struct st_node *) mg_alloc(sizeof(struct st_node));
  258.     
  259.     /* Hang node from hash table. */
  260.     bp0  = &gst_ht[0];
  261.     bp0 += gst_hash(symbol);
  262.  
  263.     bp1 -> st_next = *bp0;
  264.     *bp0           = bp1;
  265.  
  266.     /* Fill in the name, type, and class fields. */
  267.     bp1 -> st_alias  = str_gcat("_", symbol);
  268.     bp1 -> st_name = bp1 -> st_alias + 1;
  269.     bp1 -> st_type   = type;
  270.     bp1 -> st_sclass = class;
  271.  
  272.     RETURN_PTR("gst_enter", bp1);
  273. }
  274.  
  275. /*
  276.     Place a symbol in the local symbol table.
  277.     Return a pointer to the created node.
  278. */
  279. struct st_node *
  280. lst_enter (register char * symbol, struct type_node * type, int class)
  281. {
  282.     register struct st_node **bp0, *bp1;
  283.  
  284.     TRACEPB("lst_enter", printf("(%s, %p, %d)\n", 
  285.         symbol, type, class));
  286.  
  287.     if (symbol == NULL) {
  288.         t_error("lst_enter: internal: NULL symbol");
  289.         symbol = "";
  290.     }
  291.  
  292.     /* Dynamically allocate space for node. */
  293.     bp1 = CAST(struct st_node *) ml_alloc(sizeof(struct st_node));
  294.     
  295.     /* Hang node from hash table. */
  296.     bp0  = &lst_ht[0];
  297.     bp0 += lst_hash(symbol);
  298.  
  299.     bp1 -> st_next = *bp0;
  300.     *bp0           = bp1;
  301.  
  302.     /* Fill in the name and text fields. */
  303.     bp1 -> st_alias  = str_lcat("_", symbol);
  304.     bp1 -> st_name = bp1 -> st_alias + 1;
  305.     bp1 -> st_type   = type;
  306.     bp1 -> st_sclass = class;
  307.  
  308.     RETURN_PTR("lst_enter", bp1);
  309. }
  310.  
  311. /*
  312.     Compute the hash function for a global symbol.
  313. */
  314. static int
  315. gst_hash (register char * symbol)
  316. {
  317.     register int hash;
  318.  
  319.     SL_DISABLE();
  320.  
  321.     for (hash = 0; *symbol; ) {
  322.         hash *= 3;
  323.         hash += (int) *symbol++;
  324.         hash %= G_PRIME;
  325.     }
  326.     return hash;
  327. }
  328.  
  329. /*
  330.     Compute the hash function for a local symbol.
  331. */
  332. static int
  333. lst_hash (register char * symbol)
  334. {
  335.     register int hash;
  336.  
  337.     SL_DISABLE();
  338.  
  339.     for (hash = 0; *symbol; ) {
  340.         hash *= 3;
  341.         hash += (int) *symbol++;
  342.         hash %= L_PRIME;
  343.     }
  344.     return hash;
  345. }
  346.  
  347. /*
  348.     Initialize both symbol tables.
  349. */
  350. void
  351. st_init(void)
  352. {
  353.     register int i;
  354.     register struct st_node ** bp0;
  355.  
  356.     TICKB("st_init");
  357.  
  358.     /* Clear the global hash table. */
  359.     for (i = 0, bp0 = &gst_ht[0]; i < G_PRIME; i++) {
  360.         *bp0++ = NULL;
  361.     }
  362.  
  363.     /* Clear the local hash table. */
  364.     lst_init();
  365.  
  366.     TICKX("st_init");
  367. }
  368.  
  369. /*
  370.     Re-initialize the local symbol table.
  371. */
  372. void
  373. lst_init(void)
  374. {
  375.     register int i;
  376.     register struct st_node ** bp0;
  377.  
  378.     /* Clear the local hash table. */
  379.  
  380.     TICKB("lst_init");
  381.  
  382.     for (i = 0, bp0 = &lst_ht[0]; i < L_PRIME; i++) {
  383.         *bp0++ = NULL;
  384.     }
  385.  
  386.     TICKX("lst_init");
  387. }
  388.  
  389. /*
  390.     Look up a symbol in the global symbol table.
  391.     Return a pointer to the node or NULL.
  392. */
  393. struct st_node *
  394. gst_lookup (register char * symbol)
  395. {
  396.     register struct st_node ** bp0, *bp1;
  397.  
  398.     /* Calculate the hash value of the symbol. */
  399.  
  400.     TRACEPB("gst_lookup", printf("(%s)\n", symbol));
  401.  
  402.     bp0  = &gst_ht[0];
  403.     bp0 += gst_hash(symbol);
  404.  
  405.     /* Search down the list of gst_nodes. */
  406.     for (bp1 = *bp0; bp1; bp1 = bp1 -> st_next) {
  407.  
  408.         if(str_eq(symbol, bp1 -> st_name)) {
  409.             /* Found. */
  410.             RETURN_PTR("gst_lookup", bp1);
  411.         }
  412.     }
  413.  
  414.     /* Return failure. */
  415.  
  416.     RETURN_PTR("gst_lookup", NULL);
  417. }
  418.  
  419. /*
  420.     Look up a symbol in the local symbol table.
  421.     Return a pointer to the node or NULL.
  422. */
  423. struct st_node *
  424. lst_lookup (register char * symbol)
  425. {
  426.     register struct st_node ** bp0, *bp1;
  427.  
  428.     /* Calculate the hash value of the symbol. */
  429.  
  430.     TRACEPB("lst_lookup", printf("(%s)\n", symbol));
  431.  
  432.     bp0  = &lst_ht[0];
  433.     bp0 += lst_hash(symbol);
  434.  
  435.     /* Search down the list of lst_nodes. */
  436.     for (bp1 = *bp0; bp1; bp1 = bp1 -> st_next) {
  437.  
  438.         if(str_eq(symbol, bp1 -> st_name)) {
  439.             /* Found. */
  440.             RETURN_PTR("lst_lookup", bp1);
  441.         }
  442.     }
  443.  
  444.     /* Return failure. */
  445.  
  446.     RETURN_PTR("lst_lookup", NULL);
  447. }
  448.