Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
dict.cpp@0:4ab1392a0142, 2012-10-07 (annotated)
- Committer:
- gignops
- Date:
- Sun Oct 07 11:49:09 2012 +0000
- Revision:
- 0:4ab1392a0142
This project is an adaptation of tinypy code. The aim is to run python code on Mbed.; ; Have fun !
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| gignops | 0:4ab1392a0142 | 1 | #include "dict.h" |
| gignops | 0:4ab1392a0142 | 2 | |
| gignops | 0:4ab1392a0142 | 3 | int tp_lua_hash(void const *v,int l) { |
| gignops | 0:4ab1392a0142 | 4 | int i,step = (l>>5)+1; |
| gignops | 0:4ab1392a0142 | 5 | int h = l + (l >= 4?*(int*)v:0); |
| gignops | 0:4ab1392a0142 | 6 | for (i=l; i>=step; i-=step) { |
| gignops | 0:4ab1392a0142 | 7 | h = h^((h<<5)+(h>>2)+((unsigned char *)v)[i-1]); |
| gignops | 0:4ab1392a0142 | 8 | } |
| gignops | 0:4ab1392a0142 | 9 | return h; |
| gignops | 0:4ab1392a0142 | 10 | } |
| gignops | 0:4ab1392a0142 | 11 | void _tp_dict_free(_tp_dict *self) { |
| gignops | 0:4ab1392a0142 | 12 | tp_free(self->items); |
| gignops | 0:4ab1392a0142 | 13 | tp_free(self); |
| gignops | 0:4ab1392a0142 | 14 | } |
| gignops | 0:4ab1392a0142 | 15 | |
| gignops | 0:4ab1392a0142 | 16 | /* void _tp_dict_reset(_tp_dict *self) { |
| gignops | 0:4ab1392a0142 | 17 | memset(self->items,0,self->alloc*sizeof(tp_item)); |
| gignops | 0:4ab1392a0142 | 18 | self->len = 0; |
| gignops | 0:4ab1392a0142 | 19 | self->used = 0; |
| gignops | 0:4ab1392a0142 | 20 | self->cur = 0; |
| gignops | 0:4ab1392a0142 | 21 | }*/ |
| gignops | 0:4ab1392a0142 | 22 | |
| gignops | 0:4ab1392a0142 | 23 | int tp_hash(TP,tp_obj v) { |
| gignops | 0:4ab1392a0142 | 24 | switch (v.type) { |
| gignops | 0:4ab1392a0142 | 25 | case TP_NONE: return 0; |
| gignops | 0:4ab1392a0142 | 26 | case TP_NUMBER: return tp_lua_hash(&v.number.val,sizeof(tp_num)); |
| gignops | 0:4ab1392a0142 | 27 | case TP_STRING: return tp_lua_hash(v.string.val,v.string.len); |
| gignops | 0:4ab1392a0142 | 28 | case TP_DICT: return tp_lua_hash(&v.dict.val,sizeof(void*)); |
| gignops | 0:4ab1392a0142 | 29 | case TP_LIST: { |
| gignops | 0:4ab1392a0142 | 30 | int r = v.list.val->len; int n; for(n=0; n<v.list.val->len; n++) { |
| gignops | 0:4ab1392a0142 | 31 | tp_obj vv = v.list.val->items[n]; r += vv.type != TP_LIST?tp_hash(tp,v.list.val->items[n]):tp_lua_hash(&vv.list.val,sizeof(void*)); } return r; |
| gignops | 0:4ab1392a0142 | 32 | } |
| gignops | 0:4ab1392a0142 | 33 | case TP_FNC: return tp_lua_hash(&v.fnc.info,sizeof(void*)); |
| gignops | 0:4ab1392a0142 | 34 | case TP_DATA: return tp_lua_hash(&v.data.val,sizeof(void*)); |
| gignops | 0:4ab1392a0142 | 35 | } |
| gignops | 0:4ab1392a0142 | 36 | tp_raise(0,"tp_hash(%s)",TP_CSTR(v)); |
| gignops | 0:4ab1392a0142 | 37 | } |
| gignops | 0:4ab1392a0142 | 38 | |
| gignops | 0:4ab1392a0142 | 39 | void _tp_dict_hash_set(TP,_tp_dict *self, int hash, tp_obj k, tp_obj v) { |
| gignops | 0:4ab1392a0142 | 40 | tp_item item; |
| gignops | 0:4ab1392a0142 | 41 | int i,idx = hash&self->mask; |
| gignops | 0:4ab1392a0142 | 42 | for (i=idx; i<idx+self->alloc; i++) { |
| gignops | 0:4ab1392a0142 | 43 | int n = i&self->mask; |
| gignops | 0:4ab1392a0142 | 44 | if (self->items[n].used > 0) { continue; } |
| gignops | 0:4ab1392a0142 | 45 | if (self->items[n].used == 0) { self->used += 1; } |
| gignops | 0:4ab1392a0142 | 46 | item.used = 1; |
| gignops | 0:4ab1392a0142 | 47 | item.hash = hash; |
| gignops | 0:4ab1392a0142 | 48 | item.key = k; |
| gignops | 0:4ab1392a0142 | 49 | item.val = v; |
| gignops | 0:4ab1392a0142 | 50 | self->items[n] = item; |
| gignops | 0:4ab1392a0142 | 51 | self->len += 1; |
| gignops | 0:4ab1392a0142 | 52 | return; |
| gignops | 0:4ab1392a0142 | 53 | } |
| gignops | 0:4ab1392a0142 | 54 | tp_raise(,"_tp_dict_hash_set(%d,%d,%s,%s)",self,hash,TP_CSTR(k),TP_CSTR(v)); |
| gignops | 0:4ab1392a0142 | 55 | } |
| gignops | 0:4ab1392a0142 | 56 | |
| gignops | 0:4ab1392a0142 | 57 | void _tp_dict_tp_realloc(TP,_tp_dict *self,int len) { |
| gignops | 0:4ab1392a0142 | 58 | tp_item *items = self->items; |
| gignops | 0:4ab1392a0142 | 59 | int i,alloc = self->alloc; |
| gignops | 0:4ab1392a0142 | 60 | len = _tp_max(8,len); |
| gignops | 0:4ab1392a0142 | 61 | |
| gignops | 0:4ab1392a0142 | 62 | self->items = (tp_item*)tp_malloc(len*sizeof(tp_item)); |
| gignops | 0:4ab1392a0142 | 63 | self->alloc = len; self->mask = len-1; |
| gignops | 0:4ab1392a0142 | 64 | self->len = 0; self->used = 0; |
| gignops | 0:4ab1392a0142 | 65 | |
| gignops | 0:4ab1392a0142 | 66 | for (i=0; i<alloc; i++) { |
| gignops | 0:4ab1392a0142 | 67 | if (items[i].used != 1) { continue; } |
| gignops | 0:4ab1392a0142 | 68 | _tp_dict_hash_set(tp,self,items[i].hash,items[i].key,items[i].val); |
| gignops | 0:4ab1392a0142 | 69 | } |
| gignops | 0:4ab1392a0142 | 70 | tp_free(items); |
| gignops | 0:4ab1392a0142 | 71 | } |
| gignops | 0:4ab1392a0142 | 72 | |
| gignops | 0:4ab1392a0142 | 73 | int _tp_dict_hash_find(TP,_tp_dict *self, int hash, tp_obj k) { |
| gignops | 0:4ab1392a0142 | 74 | int i,idx = hash&self->mask; |
| gignops | 0:4ab1392a0142 | 75 | for (i=idx; i<idx+self->alloc; i++) { |
| gignops | 0:4ab1392a0142 | 76 | int n = i&self->mask; |
| gignops | 0:4ab1392a0142 | 77 | if (self->items[n].used == 0) { break; } |
| gignops | 0:4ab1392a0142 | 78 | if (self->items[n].used < 0) { continue; } |
| gignops | 0:4ab1392a0142 | 79 | if (self->items[n].hash != hash) { continue; } |
| gignops | 0:4ab1392a0142 | 80 | if (tp_cmp(tp,self->items[n].key,k) != 0) { continue; } |
| gignops | 0:4ab1392a0142 | 81 | return n; |
| gignops | 0:4ab1392a0142 | 82 | } |
| gignops | 0:4ab1392a0142 | 83 | return -1; |
| gignops | 0:4ab1392a0142 | 84 | } |
| gignops | 0:4ab1392a0142 | 85 | int _tp_dict_find(TP,_tp_dict *self,tp_obj k) { |
| gignops | 0:4ab1392a0142 | 86 | return _tp_dict_hash_find(tp,self,tp_hash(tp,k),k); |
| gignops | 0:4ab1392a0142 | 87 | } |
| gignops | 0:4ab1392a0142 | 88 | |
| gignops | 0:4ab1392a0142 | 89 | void _tp_dict_setx(TP,_tp_dict *self,tp_obj k, tp_obj v) { |
| gignops | 0:4ab1392a0142 | 90 | int hash = tp_hash(tp,k); int n = _tp_dict_hash_find(tp,self,hash,k); |
| gignops | 0:4ab1392a0142 | 91 | if (n == -1) { |
| gignops | 0:4ab1392a0142 | 92 | if (self->len >= (self->alloc/2)) { |
| gignops | 0:4ab1392a0142 | 93 | _tp_dict_tp_realloc(tp,self,self->alloc*2); |
| gignops | 0:4ab1392a0142 | 94 | } else if (self->used >= (self->alloc*3/4)) { |
| gignops | 0:4ab1392a0142 | 95 | _tp_dict_tp_realloc(tp,self,self->alloc); |
| gignops | 0:4ab1392a0142 | 96 | } |
| gignops | 0:4ab1392a0142 | 97 | _tp_dict_hash_set(tp,self,hash,k,v); |
| gignops | 0:4ab1392a0142 | 98 | } else { |
| gignops | 0:4ab1392a0142 | 99 | self->items[n].val = v; |
| gignops | 0:4ab1392a0142 | 100 | } |
| gignops | 0:4ab1392a0142 | 101 | } |
| gignops | 0:4ab1392a0142 | 102 | |
| gignops | 0:4ab1392a0142 | 103 | void _tp_dict_set(TP,_tp_dict *self,tp_obj k, tp_obj v) { |
| gignops | 0:4ab1392a0142 | 104 | _tp_dict_setx(tp,self,k,v); |
| gignops | 0:4ab1392a0142 | 105 | tp_grey(tp,k); tp_grey(tp,v); |
| gignops | 0:4ab1392a0142 | 106 | } |
| gignops | 0:4ab1392a0142 | 107 | |
| gignops | 0:4ab1392a0142 | 108 | tp_obj _tp_dict_get(TP,_tp_dict *self,tp_obj k, const char *error) { |
| gignops | 0:4ab1392a0142 | 109 | int n = _tp_dict_find(tp,self,k); |
| gignops | 0:4ab1392a0142 | 110 | if (n < 0) { |
| gignops | 0:4ab1392a0142 | 111 | tp_raise(tp_None,"%s: KeyError: %s\n",error,TP_CSTR(k)); |
| gignops | 0:4ab1392a0142 | 112 | } |
| gignops | 0:4ab1392a0142 | 113 | return self->items[n].val; |
| gignops | 0:4ab1392a0142 | 114 | } |
| gignops | 0:4ab1392a0142 | 115 | |
| gignops | 0:4ab1392a0142 | 116 | void _tp_dict_del(TP,_tp_dict *self,tp_obj k, const char *error) { |
| gignops | 0:4ab1392a0142 | 117 | int n = _tp_dict_find(tp,self,k); |
| gignops | 0:4ab1392a0142 | 118 | if (n < 0) { tp_raise(,"%s: KeyError: %s\n",error,TP_CSTR(k)); } |
| gignops | 0:4ab1392a0142 | 119 | self->items[n].used = -1; |
| gignops | 0:4ab1392a0142 | 120 | self->len -= 1; |
| gignops | 0:4ab1392a0142 | 121 | } |
| gignops | 0:4ab1392a0142 | 122 | |
| gignops | 0:4ab1392a0142 | 123 | _tp_dict *_tp_dict_new(void) { |
| gignops | 0:4ab1392a0142 | 124 | _tp_dict *self = (_tp_dict*)tp_malloc(sizeof(_tp_dict)); |
| gignops | 0:4ab1392a0142 | 125 | return self; |
| gignops | 0:4ab1392a0142 | 126 | } |
| gignops | 0:4ab1392a0142 | 127 | tp_obj _tp_dict_copy(TP,tp_obj rr) { |
| gignops | 0:4ab1392a0142 | 128 | tp_obj obj = {TP_DICT}; |
| gignops | 0:4ab1392a0142 | 129 | _tp_dict *o = rr.dict.val; |
| gignops | 0:4ab1392a0142 | 130 | _tp_dict *r = _tp_dict_new(); |
| gignops | 0:4ab1392a0142 | 131 | *r = *o; r->gci = 0; |
| gignops | 0:4ab1392a0142 | 132 | r->items = (tp_item*)tp_malloc(sizeof(tp_item)*o->alloc); |
| gignops | 0:4ab1392a0142 | 133 | memcpy(r->items,o->items,sizeof(tp_item)*o->alloc); |
| gignops | 0:4ab1392a0142 | 134 | obj.dict.val = r; |
| gignops | 0:4ab1392a0142 | 135 | return tp_track(tp,obj); |
| gignops | 0:4ab1392a0142 | 136 | } |
| gignops | 0:4ab1392a0142 | 137 | |
| gignops | 0:4ab1392a0142 | 138 | int _tp_dict_next(TP,_tp_dict *self) { |
| gignops | 0:4ab1392a0142 | 139 | if (!self->len) { tp_raise(0,"_tp_dict_next(...)",0); } |
| gignops | 0:4ab1392a0142 | 140 | while (1) { |
| gignops | 0:4ab1392a0142 | 141 | self->cur = ((self->cur + 1) & self->mask); |
| gignops | 0:4ab1392a0142 | 142 | if (self->items[self->cur].used > 0) { |
| gignops | 0:4ab1392a0142 | 143 | return self->cur; |
| gignops | 0:4ab1392a0142 | 144 | } |
| gignops | 0:4ab1392a0142 | 145 | } |
| gignops | 0:4ab1392a0142 | 146 | } |
| gignops | 0:4ab1392a0142 | 147 | |
| gignops | 0:4ab1392a0142 | 148 | tp_obj tp_merge(TP) { |
| gignops | 0:4ab1392a0142 | 149 | tp_obj self = TP_OBJ(); |
| gignops | 0:4ab1392a0142 | 150 | tp_obj v = TP_OBJ(); |
| gignops | 0:4ab1392a0142 | 151 | int i; for (i=0; i<v.dict.val->len; i++) { |
| gignops | 0:4ab1392a0142 | 152 | int n = _tp_dict_next(tp,v.dict.val); |
| gignops | 0:4ab1392a0142 | 153 | _tp_dict_set(tp,self.dict.val, |
| gignops | 0:4ab1392a0142 | 154 | v.dict.val->items[n].key,v.dict.val->items[n].val); |
| gignops | 0:4ab1392a0142 | 155 | } |
| gignops | 0:4ab1392a0142 | 156 | return tp_None; |
| gignops | 0:4ab1392a0142 | 157 | } |
| gignops | 0:4ab1392a0142 | 158 | |
| gignops | 0:4ab1392a0142 | 159 | tp_obj tp_dict(TP) { |
| gignops | 0:4ab1392a0142 | 160 | tp_obj r = {TP_DICT}; |
| gignops | 0:4ab1392a0142 | 161 | r.dict.val = _tp_dict_new(); |
| gignops | 0:4ab1392a0142 | 162 | return tp ? tp_track(tp,r) : r; |
| gignops | 0:4ab1392a0142 | 163 | } |
| gignops | 0:4ab1392a0142 | 164 | |
| gignops | 0:4ab1392a0142 | 165 | tp_obj tp_dict_n(TP,int n, tp_obj* argv) { |
| gignops | 0:4ab1392a0142 | 166 | tp_obj r = tp_dict(tp); |
| gignops | 0:4ab1392a0142 | 167 | int i; for (i=0; i<n; i++) { tp_set(tp,r,argv[i*2],argv[i*2+1]); } |
| gignops | 0:4ab1392a0142 | 168 | return r; |
| gignops | 0:4ab1392a0142 | 169 | } |
| gignops | 0:4ab1392a0142 | 170 | |
| gignops | 0:4ab1392a0142 | 171 |