1 #include "Cello/Map.h"
2 
3 #include "Cello/List.h"
4 #include "Cello/Bool.h"
5 #include "Cello/None.h"
6 #include "Cello/Exception.h"
7 
8 #include <string.h>
9 
10 struct MapNode {
11   var leaf_key;
12   var leaf_val;
13   struct MapNode* left;
14   struct MapNode* right;
15 };
16 
17 data {
18   var type;
19   var keys;
20   struct MapNode* root;
21 } MapData;
22 
23 var Map = type_data {
24   type_begin(Map),
25   type_entry(Map, New),
26   type_entry(Map, Assign),
27   type_entry(Map, Copy),
28   type_entry(Map, Eq),
29   type_entry(Map, Collection),
30   type_entry(Map, Dict),
31   type_entry(Map, Iter),
32   type_entry(Map, Show),
33   type_end(Map),
34 };
35 
Map_New(var self,var_list vl)36 var Map_New(var self, var_list vl) {
37   MapData* md = cast(self, Map);
38   md->keys = new(List);
39   md->root = NULL;
40   return self;
41 }
42 
Map_Delete(var self)43 var Map_Delete(var self) {
44   MapData* md = cast(self, Map);
45   clear(self);
46   delete(md->keys);
47   return self;
48 }
49 
Map_Size(void)50 size_t Map_Size(void) {
51   return sizeof(MapData);
52 }
53 
Map_Assign(var self,var obj)54 void Map_Assign(var self, var obj) {
55   MapData* other = cast(obj, Map);
56   clear(self);
57 
58   foreach(key in other) {
59     var val = get(other, key);
60     put(self, key, val);
61   }
62 }
63 
Map_Copy(var self)64 var Map_Copy(var self) {
65   var newmap = new(Map);
66   foreach(key in self) {
67     var val = get(self, key);
68     put(newmap, key, val);
69   }
70   return newmap;
71 }
72 
Map_Eq(var self,var obj)73 var Map_Eq(var self, var obj) {
74 	MapData* md = cast(self, Map);
75   if_neq(type_of(obj), Map) { return False; }
76 
77   foreach(key in obj) {
78 		if (not contains(self, key)) { return False; }
79 		if_neq(get(obj, key), get(self, key)) { return False; }
80 	}
81 
82   foreach(key in self) {
83     if (not contains(obj, key)) { return False; }
84 		if_neq(get(self, key), get(obj, key)) { return False; }
85   }
86 
87 	return True;
88 }
89 
Map_Len(var self)90 int Map_Len(var self) {
91   MapData* md = cast(self, Map);
92   return len(md->keys);
93 }
94 
Map_Clear(var self)95 void Map_Clear(var self) {
96   MapData* md = cast(self, Map);
97 
98   while(not is_empty(self)) {
99     discard(self, at(md->keys,0));
100   }
101 }
102 
Map_Contains(var self,var key)103 var Map_Contains(var self, var key) {
104   MapData* md = cast(self, Map);
105   return contains(md->keys, key);
106 }
107 
108 local bool inorder_opt = true;
109 
Map_Next_Inorder(struct MapNode * node)110 local var Map_Next_Inorder(struct MapNode* node) {
111 
112   inorder_opt = not inorder_opt;
113 
114   if (inorder_opt) {
115 
116     struct MapNode* rnode = node->left;
117 
118     while(1) {
119       if (rnode->right is NULL) return rnode->leaf_key;
120       else rnode = rnode->right;
121     }
122 
123   } else {
124 
125     struct MapNode* lnode = node->right;
126 
127     while(1) {
128       if (lnode->left is NULL) return lnode->leaf_key;
129       else lnode = lnode->left;
130     }
131 
132   }
133 
134 }
135 
Map_Discard(var self,var key)136 void Map_Discard(var self, var key) {
137   MapData* md = cast(self, Map);
138 
139   struct MapNode** parent = &md->root;
140   struct MapNode* node = md->root;
141 
142   while(node != NULL) {
143 
144     if_eq(node->leaf_key, key) {
145 
146       if ((node->left is NULL) and
147           (node->right is NULL)) {
148         *parent = NULL;
149         free(node);
150         discard(md->keys, key);
151         return;
152       }
153 
154       if ((node->left is NULL) and
155           not (node->right is NULL)) {
156         *parent = node->right;
157         free(node);
158         discard(md->keys, key);
159         return;
160       }
161 
162       if ((node->right is NULL) and
163           not (node->left is NULL)) {
164         *parent = node->left;
165         free(node);
166         discard(md->keys, key);
167         return;
168       }
169 
170       if (not (node->right is NULL) and
171           not (node->left is NULL)) {
172         var inorder_key = Map_Next_Inorder(node);
173         var inorder_val = get(self, inorder_key);
174 
175         discard(self, inorder_key);
176 
177         node->leaf_key = inorder_key;
178         node->leaf_val = inorder_val;
179 
180         discard(md->keys, key);
181         return;
182       }
183 
184     }
185 
186     if_lt(node->leaf_key, key) {
187       parent = &node->left;
188       node = node->left;
189     } else {
190       parent = &node->right;
191       node = node->right;
192     }
193 
194   }
195 
196 }
197 
Map_Get(var self,var key)198 var Map_Get(var self, var key) {
199   MapData* md = cast(self, Map);
200 
201   struct MapNode* node = md->root;
202 
203   while(node != NULL) {
204     if_eq(node->leaf_key, key) return node->leaf_val;
205     if_lt(node->leaf_key, key) node = node->left;
206     else node = node->right;
207   }
208 
209   return throw(KeyError, "Key '%$' not in Map!", key);
210 }
211 
Map_Node_New(var key,var val)212 local struct MapNode* Map_Node_New(var key, var val) {
213   struct MapNode* node = malloc(sizeof(struct MapNode));
214 
215   if (node == NULL) { throw(OutOfMemoryError, "Cannot create new Map Node. Out of memory!"); }
216 
217   node->leaf_key = key;
218   node->leaf_val = val;
219   node->left = NULL;
220   node->right = NULL;
221   return node;
222 }
223 
Map_Put(var self,var key,var val)224 void Map_Put(var self, var key, var val) {
225   MapData* md = cast(self, Map);
226 
227   struct MapNode** parent = &md->root;
228   struct MapNode* node = md->root;
229 
230   while (node != NULL) {
231 
232     if_eq(node->leaf_key, key) {
233       node->leaf_val = val;
234       return;
235     }
236 
237     if_lt(node->leaf_key, key) {
238       parent = &node->left;
239       node = node->left;
240     } else {
241       parent = &node->right;
242       node = node->right;
243     }
244 
245   }
246 
247   *parent = Map_Node_New(key, val);
248   push(md->keys, key);
249   return;
250 
251 }
252 
Map_Iter_Start(var self)253 var Map_Iter_Start(var self) {
254   MapData* md = cast(self, Map);
255   return iter_start(md->keys);
256 }
257 
Map_Iter_End(var self)258 var Map_Iter_End(var self) {
259   MapData* md = cast(self, Map);
260   return iter_end(md->keys);
261 }
262 
Map_Iter_Next(var self,var curr)263 var Map_Iter_Next(var self, var curr) {
264   MapData* md = cast(self, Map);
265   return iter_next(md->keys, curr);
266 }
267 
Map_Show(var self,var output,int pos)268 int Map_Show(var self, var output, int pos) {
269   MapData* md = cast(self, Map);
270 
271   pos = print_to(output, pos, "<'Map' At 0x%p {", self);
272 
273   for(int i = 0; i < len(self); i++) {
274     var key = at(md->keys, i);
275     var val = get(self, key);
276     pos = print_to(output, pos, "%$:%$", key, get(self, key));
277     if (i < len(self)-1) { pos = print_to(output, pos, ", "); }
278   }
279 
280   pos = print_to(output, pos, "}>");
281 
282   return pos;
283 }
284 
285