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.