TinyPy dict.c part 2
Let’s start with the next function up the call chain, tp_hash.
int tp_hash(TP,tp_obj v) {
switch (v.type) {
case TP_NONE: return 0;
case TP_NUMBER: return tp_lua_hash(&v.number.val,sizeof(tp_num));
case TP_STRING: return tp_lua_hash(v.string.val,v.string.len);
case TP_DICT: return tp_lua_hash(&v.dict.val,sizeof(void*));
case TP_LIST: {
int r = v.list.val->len; int n; for(n=0; nlen; n++) {
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;
}
case TP_FNC: return tp_lua_hash(&v.fnc.info,sizeof(void*));
case TP_DATA: return tp_lua_hash(&v.data.val,sizeof(void*));
}
tp_raise(0,tp_string(”(tp_hash) TypeError: value unhashable”));
}
Reformatting the lines we get:
int tp_hash(TP,tp_obj v) {
switch (v.type) {
case TP_NONE: return 0;
case TP_NUMBER: return tp_lua_hash(&v.number.val,sizeof(tp_num));
case TP_STRING: return tp_lua_hash(v.string.val,v.string.len);
case TP_DICT: return tp_lua_hash(&v.dict.val,sizeof(void*));
case TP_LIST: {
int r = v.list.val->len;
int n;
for(n=0; nlen; n++) {
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;
}
case TP_FNC: return tp_lua_hash(&v.fnc.info,sizeof(void*));
case TP_DATA: return tp_lua_hash(&v.data.val,sizeof(void*));
}
tp_raise(0,tp_string(”(tp_hash) TypeError: value unhashable”));
}
Freshman style:
int tp_hash(TP,tp_obj v) {
// Switch on type of pointer
switch (v.type) {
// None type has hash of 0
case TP_NONE: return 0;
// Hash number based on value and size of tp_num struct
case TP_NUMBER: return tp_lua_hash(&v.number.val,sizeof(tp_num));
// Hash string based on value and length of specified string
case TP_STRING: return tp_lua_hash(v.string.val,v.string.len);
// Hash dictionary based on value of dictionary and size of void
// pointer.
case TP_DICT: return tp_lua_hash(&v.dict.val,sizeof(void*));
case TP_LIST: {
// Start r at length of list.
int r = v.list.val->len;
int n;
// Iterate n through all items in list.
for(n=0; nlen; n++) {
// grab each item in list.
tp_obj vv = v.list.val->items[n];
// For each item, add hash to r if item not
// isn’t a list.
r += vv.type != TP_LIST ? tp_hash(tp, v.list.val->items[n])
: tp_lua_hash(&vv.list.val,
sizeof(void*));
}
// Return hash for list.
return r;
}
// Return hash of function object based on info
case TP_FNC: return tp_lua_hash(&v.fnc.info,sizeof(void*));
// Return hash of ??? object ?? based on value.
case TP_DATA: return tp_lua_hash(&v.data.val,sizeof(void*));
}
// Otherwise, raise an exception.
tp_raise(0,tp_string(”(tp_hash) TypeError: value unhashable”));
}
Finally, high level description.
/* Hash an arbitrary TinyPy object. * * None hashes to zero, dictionaries are hashable and lists are hashed * non-recursively. * */