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