home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / tables.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  6.9 KB  |  270 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains routines for management of symbol tables.  Symbol tables
  35.  * are used very heavily in Harvest C.  They manage everything from
  36.  * preprocessor symbols to string literals, and of course, the C identifiers.
  37.  * 
  38.  * 
  39.  * 
  40.  */
  41.  
  42. #include "conditcomp.h"
  43. #include <stdio.h>
  44. #include <string.h>
  45.  
  46. #include "structs.h"
  47.  
  48. #pragma segment SymbolLists
  49.  
  50.  
  51. SYMVia_t
  52. RawSymbol(char *name)
  53. {
  54.     register SYMVia_t               raw;
  55.     raw = Ealloc(sizeof(SYM_t) + strlen(name));
  56.     if (raw) {
  57.         Via(raw)->next = 0;
  58.         Via(raw)->TP = 0;
  59.         Via(raw)->SymbolFlags = 0;
  60.         Via(raw)->storage_class = 0;
  61.         Via(raw)->numbers.CountParams = 0;
  62.         Via(raw)->Definition.FuncBody = 0;
  63.         Via(raw)->M68kDef.Loc = 0;
  64.         strcpy(Via(raw)->name, name);
  65.     }
  66.     return raw;
  67. }
  68.  
  69. LabSYMVia_t
  70. RawLabSymbol(char *name)
  71. {
  72.     register LabSYMVia_t            raw;
  73.     raw = Ealloc(sizeof(LabSYM_t) + strlen(name));
  74.     if (raw) {
  75.     Via(raw)->left = NULL;
  76.     Via(raw)->right = NULL;
  77.     Via(raw)->SymbolFlags = 0;
  78.     Via(raw)->Definition.superclass = NULL;
  79.     Via(raw)->M68kDef.where = NULL;
  80.     strcpy(Via(raw)->name, name);
  81.     }
  82.     return raw;
  83. }
  84.  
  85. LabSymListVia_t
  86. RawLabTable(void)
  87. /* Create an empty, unused label Symbol Table. */
  88. {
  89.     register LabSymListVia_t        raw;
  90.     raw = Ealloc(sizeof(LabSymList_t));
  91.     if (raw) {
  92.     Via(raw)->_head = NULL;
  93.     Via(raw)->count = 0;
  94.     }
  95.     return raw;
  96. }
  97.  
  98. /*
  99.  * A symbol table, is a data structure which describes the definitions of
  100.  * symbols.  As identifiers are declared (as meanings are given to symbols),
  101.  * these identifiers (symbols) are inserted into the appropriate symbol
  102.  * table. Any identifier declared twice in the same scope is an error, but
  103.  * one identifier may have many different meanings in different scopes.
  104.  * Different scopes will, in general, be represented by different symbol
  105.  * tables. Generally, scope can be global, or local to some compound
  106.  * statement.  The following name spaces do not conflict with each other:
  107.  * 1(objects,functions,typedef names, and enum constants), 2(labels), 3(tags
  108.  * of structures, unions, and enumerations), and 4(members of each structure
  109.  * or union individually).  Scope of a declared identifier begins at the end
  110.  * of its declarator, and proceeds until the end of the translation unit.
  111.  */
  112.  
  113. SymImageVia_t
  114. ListAdd(SymImageVia_t table, SYMVia_t thesym)
  115. {
  116.     SymImageVia_t                   added = NULL;
  117.     if (thesym) {
  118.     added = Ealloc(sizeof(SymImage_t));
  119.     Via(added)->Symbol = thesym;
  120.     Via(added)->next = table;
  121.     if (table) {
  122.         Via(added)->count = Via(table)->count + 1;
  123.     } else {
  124.         Via(added)->count = 1;
  125.     }
  126.     }
  127.     return added;
  128. }
  129.  
  130. LabSYMVia_t
  131. LabTableAdd(LabSymListVia_t table, char *name)
  132. /*
  133.  * General routine for adding a symbol to a symbol table.  The symbol table
  134.  * data structures are used for many purposes.  Note that currently, a number
  135.  * of routines depend on these tables being kept in order.
  136.  */
  137. {
  138.     /*
  139.      * All the table manipulation routines may be modified later to make the
  140.      * tables vastly more efficient.
  141.      */
  142.     register LabSYMVia_t            tmp;
  143.     register LabSYMVia_t            tmp2, prev;
  144.     register unsigned long          hk;
  145.     tmp = RawLabSymbol(name);
  146.     Via(tmp)->HashKey = hk = TableHash(name);
  147.     if (!table) {
  148.     return tmp;
  149.     }
  150.     Via(tmp)->IndexInserted = ++Via(table)->count;
  151.     if (Via(table)->_head) {
  152.     tmp2 = Via(table)->_head;
  153.     while (tmp2) {
  154.         prev = tmp2;
  155.         if (Via(tmp2)->HashKey < hk) {
  156.         tmp2 = Via(tmp2)->right;
  157.         } else {
  158.         tmp2 = Via(tmp2)->left;
  159.         }
  160.     }
  161.     if (Via(prev)->HashKey < hk) {
  162.         Via(prev)->right = tmp;
  163.     } else {
  164.         Via(prev)->left = tmp;
  165.     }
  166.     } else {
  167.     Via(table)->_head = tmp;
  168.     }
  169.     return tmp;
  170. }
  171.  
  172. void
  173. GenOneSeg(LabSYMVia_t cursym, InstListVia_t Codes)
  174. {
  175.     if (!(Via(cursym)->SymbolFlags & CODEOUTPUT)) {
  176.         Via(cursym)->SymbolFlags |= CODEOUTPUT;
  177.     GenInst(M68op_DEFSEG, M68sz_none, BuildLabelLoc(MakeSysLabel(Via(cursym)->name)), NULL, Codes);
  178.     }
  179. }
  180.  
  181. void GenSegmentsRecurse(LabSYMVia_t cur, InstListVia_t Codes)
  182. {
  183.     if (cur) {
  184.         GenSegmentsRecurse(Via(cur)->left,Codes);
  185.         GenOneSeg(cur,Codes);
  186.         GenSegmentsRecurse(Via(cur)->right,Codes);
  187.     }
  188. }
  189.  
  190. void
  191. GenSegments(InstListVia_t Codes)
  192. {
  193.     GenSegmentsRecurse(Via(SegmentNames)->_head,Codes);
  194. }
  195.  
  196. LabSYMVia_t
  197. LabTableTailAdd(LabSymListVia_t table, char *name)
  198. /*
  199.  * General routine for adding a symbol to a symbol table.  The symbol table
  200.  * data structures are used for many purposes.  Note that currently, a number
  201.  * of routines depend on these tables being kept in order.
  202.  */
  203. {
  204.     return LabTableAdd(table, name);
  205. }
  206.  
  207. void
  208. LabTableIndexSearch(LabSYMVia_t root, int ndx, LabSYMVia_t * out)
  209. {
  210.     if (root) {
  211.     if (Via(root)->IndexInserted == ndx)
  212.         *out = root;
  213.     else {
  214.         if (!(*out)) {
  215.         LabTableIndexSearch(Via(root)->left, ndx, out);
  216.         }
  217.         if (!(*out)) {
  218.         LabTableIndexSearch(Via(root)->right, ndx, out);
  219.         }
  220.     }
  221.     }
  222. }
  223.  
  224. LabSYMVia_t
  225. LabTableGetNum(LabSymListVia_t table, int num)
  226. /*
  227.  * This table returns symbol record # num from the given table.  If the table
  228.  * does not contains num records, then NULL.  The first record in a table is
  229.  * numbered 1.
  230.  */
  231. {
  232.     LabSYMVia_t                     tmp;
  233.     if (num > Via(table)->count)
  234.     return NULL;
  235.     tmp = NULL;
  236.     LabTableIndexSearch(Via(table)->_head, num, &tmp);
  237.     return tmp;
  238. }
  239.  
  240. LabSYMVia_t
  241. LabTableSearch(LabSymListVia_t table, char *name)
  242. /*
  243.  * This routine searches a table for the given name, returning the symbol
  244.  * record for that name if it was found, otherwise NULL.
  245.  */
  246. {
  247.     register LabSYMVia_t            tmp;
  248.     unsigned long                   hashval;
  249.     hashval = TableHash(name);
  250.     tmp = Via(table)->_head;
  251.     while (tmp) {
  252.     if (Via(tmp)->HashKey == hashval) {
  253.         if (!strcmp(Via(tmp)->name, name)) {
  254.         return tmp;
  255.         } else {
  256.         if (Via(tmp)->HashKey < hashval)
  257.             tmp = Via(tmp)->right;
  258.         else
  259.             tmp = Via(tmp)->left;
  260.         }
  261.     } else {
  262.         if (Via(tmp)->HashKey < hashval)
  263.         tmp = Via(tmp)->right;
  264.         else
  265.         tmp = Via(tmp)->left;
  266.     }
  267.     }
  268.     return NULL;
  269. }
  270.