home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 116.lha / SmallTalk / Sources / NAMES.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-20  |  5.9 KB  |  218 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.     (putting things INTO the table is all done in Smalltalk code,
  17.     using the methods from class Dictionary)
  18.  
  19.     One complication of instances of class Symbol is that all
  20.     symbols must be unique, not only so that == will work as expected,
  21.     but so that memory does not get overly clogged up with symbols.
  22.     Thus all symbols are kept in a hash table, and when new symbols
  23.     are created (via newSymbol(), below) they are inserted into this
  24.     table, if not already there.
  25.  
  26.     This module also manages the definition of various symbols that are
  27.     given fixed values for efficiency sake.  These include the objects
  28.     nil, true, false, and various classes.
  29. */
  30.  
  31. # include <stdio.h>
  32. # include "env.h"
  33. # include "memory.h"
  34. # include "names.h"
  35.  
  36. /* global variables used to avoid repeated examinations of the global symbol table */
  37. object trueobj = nilobj;    /* the pseudo variable true */
  38. object falseobj = nilobj;    /* the pseudo variable false */
  39. object smallobj = nilobj;    /* the pseudo variable smalltalk */
  40. object arrayclass = nilobj;    /* the class ``Array'' */
  41. object blockclass = nilobj;    /* the class ``Block'' */
  42. object contextclass = nilobj;    /* the class ``Context'' */
  43. object intclass = nilobj;    /* the class ``Integer'' */
  44. object intrclass = nilobj;    /* the class ``Interpreter'' */
  45. object symbolclass = nilobj;    /* the class ``Symbol'' */
  46. object stringclass = nilobj;    /* the class ``String'' */
  47.  
  48. /*
  49.     some messages are encoded in concise bytecode format -
  50. to reduce the size of the compiled methods
  51. (also, in some cases, to more efficiently detect special cases
  52. handled in the interpreter, rather than by methods)
  53. */
  54.  
  55. char *binStrs[] = {"+", "-", "<", ">", "<=", ">=", "=", "~=", "*", 
  56. "quo:", "rem:", "bitAnd:", "bitXor:", 
  57. "==", ",", "at:", "basicAt:", "do:", "coerce:", "error:", "includesKey:",
  58. "isMemberOf:", "new:", "to:", "value:", "whileTrue:", "addFirst:", "addLast:",
  59. 0};
  60.  
  61. object binSyms[28];
  62.  
  63. char *unStrs[] = {"isNil", "notNil", "new", "value", "class", "size",
  64. "basicSize", "print", "printString", 0};
  65.  
  66. object unSyms[9];
  67.  
  68. char *keyStrs[] = {"at:ifAbsent:", "at:put:", "basicAt:put:", "between:and:",
  69. 0};
  70.  
  71. object keySyms[4];
  72.  
  73. object nameTableLookup(dict, symbol)
  74. object dict, symbol;
  75. {    int hash, tablesize;
  76.     object table, link;
  77.  
  78.     /* first get hash table */
  79.     table = basicAt(dict, 1);
  80.  
  81.     /* now see if table is valid */
  82.     if ((tablesize = objectSize(table)) < 3)
  83.         sysError("system error","lookup on null table");
  84.     else {
  85.         hash = 3 * ( symbol % (tablesize / 3));
  86.         if (basicAt(table, hash+1) == symbol)
  87.             return(basicAt(table, hash+2));
  88.  
  89.         /* otherwise look along the chain of links */
  90.         for (link=basicAt(table, hash+3); link != nilobj; 
  91.                     link=basicAt(link, 3))
  92.             if (basicAt(link, 1) == symbol)
  93.                 return(basicAt(link, 2));
  94.  
  95.     }
  96.     return (nilobj);
  97. }
  98.  
  99. object getClass(obj)
  100. object obj;
  101. {
  102.     if (isInteger(obj))
  103.         return(intclass);
  104.     return (classField(obj));
  105. }
  106.  
  107. static object globalGet(name)
  108. char *name;
  109. {    object newobj;
  110.  
  111.     newobj = globalSymbol(name);
  112.     if (newobj == nilobj)
  113.         sysError("symbol not found in image", name);
  114.     return(newobj);
  115. }
  116.  
  117. noreturn initCommonSymbols()
  118. {    int i;
  119.  
  120.     trueobj = globalGet("true");
  121.     falseobj = globalGet("false");
  122.     smallobj  = globalGet("smalltalk");
  123.     arrayclass = globalGet("Array");
  124.     blockclass = globalGet("Block");
  125.     contextclass = globalGet("Context");
  126.     intclass = globalGet("Integer");
  127.     symbolclass = globalGet("Symbol");
  128.     stringclass = globalGet("String");
  129.     /* interpreter may or may not be there */
  130.     intrclass = globalSymbol("Interpreter");
  131.  
  132.     for (i = 0; i < 28; i++)
  133.         binSyms[i] = newSymbol(binStrs[i]);
  134.  
  135.     for (i = 0; i < 9; i++)
  136.         unSyms[i] = newSymbol(unStrs[i]);
  137.  
  138.     for (i = 0; i < 4; i++)
  139.         keySyms[i] = newSymbol(keyStrs[i]);
  140. }
  141.  
  142. object newArray(size)
  143. int size;
  144. {    object newobj;
  145.  
  146.     if (arrayclass == nilobj) {
  147.         arrayclass = globalSymbol("Array");
  148.         if (arrayclass == nilobj) 
  149.             sysError("can't find global symbol","Array");
  150.         }
  151.     newobj = allocObject(size);
  152.     setClass(newobj, arrayclass);
  153.     return(newobj);
  154. }
  155.  
  156. object newSymbol(str)
  157. char *str;
  158. {    int hash;
  159.     object newSym, link;
  160.     char *p;
  161.  
  162.     /* first compute hash value of string text */
  163.     /* this is duplicated in image.c - make sure any changes match there */
  164.     hash = 0;
  165.     for (p = str; *p; p++)
  166.         hash += *p;
  167.     if (hash < 0) hash = - hash;
  168.     hash = 2 * ( hash % (objectSize(symbols) / 2));
  169.  
  170.     /* next look to see if it is in symbols - note that this
  171.        text duplicates that found in nameTableLookup, only using
  172.        string comparison instead of symbol comparison */
  173.     newSym = basicAt(symbols, hash+1);
  174.     if (newSym && streq(str, charPtr(newSym)))
  175.         return(newSym);
  176.  
  177.     /* not in table, look along links */
  178.     for (link=basicAt(symbols, hash+2); link != nilobj; link=basicAt(link,2)) {
  179.         newSym = basicAt(link, 1);
  180.         if (streq(str, charPtr(newSym)))
  181.             return(newSym);
  182.         }
  183.  
  184.     /* not found, make a new symbol */
  185.     newSym = allocSymbol(str);
  186.     setClass(newSym, symbolclass);
  187.  
  188.     /* now insert new symbol in table, so next time we will find it */
  189.     if (basicAt(symbols, hash+1) == nilobj)
  190.         basicAtPut(symbols, hash+1, newSym);
  191.     else {        /* insert along links */
  192.         link = allocObject(2);
  193.         basicAtPut(link, 1, newSym);
  194.         basicAtPut(link, 2, basicAt(symbols, hash+2));
  195.         basicAtPut(symbols, hash+2, link);
  196.         }
  197.  
  198.     return(newSym);
  199. }
  200.  
  201. object newStString(value)
  202. char *value;
  203. {    object newobj;
  204.  
  205.     newobj = allocSymbol(value);
  206.     setClass(newobj, stringclass);
  207.     return(newobj);
  208. }
  209.  
  210. object newFloat(d)
  211. double d;
  212. {    object newobj;
  213.  
  214.     newobj = allocFloat(d);
  215.     setClass(newobj, globalSymbol("Float"));
  216.     return(newobj);
  217. }
  218.