home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / smalltk / src / names.c < prev    next >
C/C++ Source or Header  |  1991-10-12  |  5KB  |  173 lines

  1. /*
  2.     Little Smalltalk, version 2
  3.     Written by Tim Budd, Oregon State University, July 1987
  4.  
  5.     Name Table module
  6.  
  7.     A name table is the term used for a Dictionary indexed by symbols.
  8.     There are two name tables used internally by the bytecode interpreter.
  9.     The first is the table, contained in the variable globalNames,
  10.     that contains the names and values of all globally accessible 
  11.     identifiers.  The second is the table of methods associated with
  12.     every class.  Notice that in neither of these cases does the
  13.     system ever put anything INTO the tables, thus there are only
  14.     routines here for reading FROM tables.
  15.  
  16.     One complication of instances of class Symbol is that all
  17.     symbols must be unique, not only so that == will work as expected,
  18.     but so that memory does not get overly clogged up with symbols.
  19.     Thus all symbols are kept in a hash table, and when new symbols
  20.     are created (via newSymbol(), below) they are inserted into this
  21.     table, if not already there.
  22.  
  23.     This module also manages the definition of various symbols that are
  24.     given fixed values for efficiency sake.  These include the objects
  25.     nil, true, false, and various classes.
  26. */
  27.  
  28. # include <stdio.h>
  29. # include "env.h"
  30. # include "memory.h"
  31. # include "names.h"
  32.  
  33. noreturn nameTableInsert(dict, hash, key, value)
  34. object dict, key, value;
  35. int hash;
  36. {    object table, link, nwLink, nextLink, tablentry;
  37.  
  38.     /* first get the hash table */
  39.     table = basicAt(dict, 1);
  40.  
  41.     if (sizeField(table) < 3)
  42.         sysError("attempt to insert into","too small name table");
  43.     else {
  44.         hash = 3 * ( hash % (sizeField(table) / 3));
  45.         tablentry = basicAt(table, hash+1);
  46.         if ((tablentry == nilobj) || (tablentry == key)) {
  47.             basicAtPut(table, hash+1, key);
  48.             basicAtPut(table, hash+2, value);
  49.             }
  50.         else {
  51.             nwLink = newLink(key, value);
  52.             incr(nwLink);
  53.             link = basicAt(table, hash+3);
  54.             if (link == nilobj) {
  55.                 basicAtPut(table, hash+3, nwLink);
  56.                 }
  57.             else
  58.                 while(1)
  59.                     if (basicAt(link,1) == key) {
  60.                         basicAtPut(link, 2, value);
  61.                         break;
  62.                         }
  63.                     else if ((nextLink = basicAt(link, 3)) == nilobj) {
  64.                         basicAtPut(link, 3, nwLink);
  65.                         break;
  66.                         }
  67.                     else
  68.                         link = nextLink;
  69.             decr(nwLink);
  70.             }
  71.     }
  72. }
  73.  
  74. object hashEachElement(dict, hash, fun)
  75. object dict;
  76. register int hash;
  77. int (*fun)();
  78. {    object table, key, value, link;
  79.     register object *hp;
  80.     int tablesize;
  81.  
  82.     table = basicAt(dict, 1);
  83.  
  84.     /* now see if table is valid */
  85.     if ((tablesize = sizeField(table)) < 3)
  86.         sysError("system error","lookup on null table");
  87.     else {
  88.         hash = 1+ (3 * (hash % (tablesize / 3)));
  89.         hp = sysMemPtr(table) + (hash-1);
  90.         key = *hp++; /* table at: hash */
  91.         value = *hp++; /* table at: hash + 1 */
  92.         if ((key != nilobj) && (*fun)(key)) 
  93.             return value;
  94.         for (link = *hp; link != nilobj; link = *hp) {
  95.             hp = sysMemPtr(link);
  96.             key = *hp++; /* link at: 1 */
  97.             value = *hp++; /* link at: 2 */
  98.             if ((key != nilobj) && (*fun)(key))
  99.                 return value;
  100.             }
  101.     }
  102.     return nilobj;
  103. }
  104.  
  105. int strHash(str)    /* compute hash value of string ---- strHash */
  106. char *str;
  107. {    register int hash;
  108.     register char *p;
  109.  
  110.     hash = 0;
  111.     for (p = str; *p; p++)
  112.         hash += *p;
  113.     if (hash < 0) hash = - hash;
  114.     /* make sure it can be a smalltalk integer */
  115.     if (hash > 16384)
  116.         hash >>= 2;
  117.     return hash;
  118. }
  119.  
  120. static object objBuffer;
  121. static char   *charBuffer;
  122.  
  123. static int strTest(key)    /* test for string equality ---- strTest */
  124. object key;
  125. {
  126.     if (charPtr(key) && streq(charPtr(key), charBuffer)) {
  127.         objBuffer = key;
  128.         return 1;
  129.         }
  130.     return 0;
  131. }
  132.  
  133. object globalKey(str)    /* return key associated with global symbol */
  134. char *str;
  135. {
  136.     objBuffer = nilobj;
  137.     charBuffer = str;
  138.     ignore hashEachElement(symbols, strHash(str), strTest);
  139.     return objBuffer;
  140. }
  141.  
  142. object nameTableLookup(dict, str)
  143. object dict;
  144. char *str;
  145. {
  146.     charBuffer = str;
  147.     return hashEachElement(dict, strHash(str), strTest);
  148. }
  149.  
  150. object unSyms[12];
  151. object binSyms[30];
  152.  
  153. char *unStrs[] = {"isNil", "notNil", "value", "new", "class", "size",
  154. "basicSize", "print", "printString", 0};
  155.  
  156. char *binStrs[] = {"+", "-", "<", ">", "<=", ">=", "=", "~=", "*", 
  157. "quo:", "rem:", "bitAnd:", "bitXor:", "==",
  158. ",", "at:", "basicAt:", "do:", "coerce:", "error:", "includesKey:",
  159. "isMemberOf:", "new:", "to:", "value:", "whileTrue:", "addFirst:", "addLast:",
  160. 0};
  161.  
  162. /* initialize common symbols used by the parser and interpreter */
  163. noreturn initCommonSymbols()
  164. {    int i;
  165.  
  166.     trueobj = globalSymbol("true");
  167.     falseobj = globalSymbol("false");
  168.     for (i = 0; unStrs[i]; i++)
  169.         unSyms[i] = newSymbol(unStrs[i]);
  170.     for (i = 0; binStrs[i]; i++)
  171.         binSyms[i] = newSymbol(binStrs[i]);
  172. }
  173.