lac : dab27f6a03077dacd66e325476ee103c8f783aac

     1: #include "private.h"
     2: #include <gc/gc.h>
     3: #include <string.h>
     4: 
     5: /*
     6:  * Utterly simple hash table implementation
     7:  */
     8: 
     9: static unsigned ht_hashf(lreg_t key)
    10: {
    11:   return ((uintptr_t)lreg_raw_ptr(key) >> 5) % HT_SIZE;
    12: }
    13: 
    14: static int _ht_findptr(struct ht_entry *hte, lreg_t key, struct ht_entry **e)
    15: {
    16:   int i = 0;
    17:   struct ht_entry *ptr;
    18: 
    19:   for (ptr = hte; ptr != NULL; ptr = ptr->next) {
    20:     i++;
    21:     if ( ptr->key == key )
    22:       {
    23:         *e = ptr;
    24:         return 0;
    25:       }
    26:   }
    27:   return 1;
    28: }
    29: 
    30: /* Ret values: < 0 => error, 0 => found, 1 not found */
    31: static int ht_findptr(ht_t *ht, lreg_t key, struct ht_entry **e)
    32: {
    33:   unsigned n = ht_hashf(key);
    34:   return _ht_findptr(ht->table[n], key, e);
    35: }
    36: 
    37: /* Ret values: < 0 => error, 0 => found, 1 not found */
    38: static int ht_find(ht_t *ht, lreg_t key, lreg_t *res)
    39: {
    40:   int n;
    41:   struct ht_entry *hte;
    42:   n = ht_findptr(ht, key, &hte);
    43:   if ( n == 0 )
    44:     *res = hte->value;
    45:   return n;
    46: }
    47: 
    48: static int _ht_insert(struct ht_entry **htep, lreg_t key, lreg_t value)
    49: {
    50:   struct ht_entry *hte = *htep;
    51:   struct ht_entry *e = GC_malloc(sizeof(struct ht_entry));
    52:   e->key = key;
    53:   e->value = value;
    54:   e->next = hte;
    55:   *htep = e;
    56:   return 0;
    57: }
    58: 
    59: static int ht_insert(ht_t *ht, lreg_t key, lreg_t value)
    60: {
    61:   unsigned n = ht_hashf(key);
    62:   assert(n < HT_SIZE);
    63:   return _ht_insert(ht->table + n, key, value);
    64: }
    65: 
    66: 
    67: /*
    68:  * Environment stacks. Mostly Activation Records.
    69:  */
    70: 
    71: /* Ret values: < 0 => error, 0 => found, 1 not found */
    72: lreg_t env_lookup(lenv_t *env, lreg_t key)
    73: {
    74:   int r;
    75:   lreg_t res;
    76: 
    77:   r = ht_find(&env->htable, key, &res);
    78:   if (r == 1) {
    79:     raise_exception("Symbol not found", key);
    80:   }
    81:   if (r) {
    82:     raise_exception("Internal error", key);
    83:   }
    84:   return res;
    85: }
    86: 
    87: int env_define(lenv_t *env, lreg_t key, lreg_t value)
    88: {
    89:   return ht_insert(&env->htable, key, value);
    90: }
    91: 
    92: /* Ret values: < 0 => error, 0 => found, 1 not found */
    93: int env_set(lenv_t *env, lreg_t key, lreg_t value)
    94: {
    95:   int r;
    96:   struct ht_entry *hte;
    97:   r = ht_findptr(&env->htable, key, &hte);
    98:   if ( r == 0 )
    99:       hte->value = value;
   100:   return r;
   101: }
   102: 
   103: void env_pushnew(lenv_t *env, lenv_t *new)
   104: {
   105:     new->htable = env->htable;
   106: }
   107: 
   108: #if 0
   109: 
   110: static lenv_t le;
   111: int main ()
   112: {
   113:   int n1, n2;
   114:   lreg_t res = 0;
   115:   lenv_t *le2;
   116:   GC_INIT();
   117: 
   118:   le.htable = GC_malloc(sizeof(ht_t));
   119:   
   120:   n1 = env_set(&le, LREG(0x505000, 5), LREG(0xa0a000, 0xa));
   121:   printf("n1 = %d\n", n1);
   122:   n1 = env_lookup(&le, LREG(0x505000, 5), &res);
   123:   printf("%llx: %d\n", res, n1);
   124:   n1 = env_define(&le, LREG(0x505000, 5), LREG(0xa0a000, 0xa));
   125:   printf("n1 = %d\n", n1);
   126:   n1 = env_lookup(&le, LREG(0x505000, 5), &res);
   127:   printf("%llx: %d\n", res, n1);
   128: 
   129:   printf("Creating new env\n");
   130: 
   131:   le2 = env_pushnew(&le);
   132:   n1 = env_lookup(le2, LREG(0x505000, 5), &res);
   133:   printf("%llx: %d\n", res, n1);
   134:   n1 = env_define(le2, LREG(0x505000, 5), LREG(0xb0b000, 0xa));
   135:   printf("n1 = %d\n", n1);
   136:   n1 = env_lookup(le2, LREG(0x505000, 5), &res);
   137:   printf("%llx: %d\n", res, n1);
   138: 
   139:   printf("Back to old env\n");
   140: 
   141:   n1 = env_lookup(&le, LREG(0x505000, 5), &res);
   142:   printf("%llx: %d\n", res, n1);
   143: 
   144: 
   145: }
   146: 
   147: #endif 

Generated by git2html.