uint32_t hash_value(value_t val) { #if NANTAG if (IS_PTR(val)) { return hash_ptr(AS_PTR(val)); } else { value_conv_t data; data.bits = val; return hash_number(data.bits); } #else // ! NANTAG switch (val.type) { case V_NIL: return 0; case V_TRUE: return 1; case V_FALSE: return 2; case V_UNDEFINED: return 3; case V_NUM: return hash_number(AS_NUM(val)); case V_PTR: return hash_ptr(AS_PTR(val)); default: return 0; } #endif // NANTAG }
/* * hash_complex - hash a COMPLEX * * given: * type - hash type (see hash.h) * c - the COMPLEX * state - the state to hash or NULL * * returns: * the new state */ HASH * hash_complex(int type, void *c, HASH *state) { COMPLEX *complex = (COMPLEX *)c; /* c as a COMPLEX pointer */ /* * initialize if state is NULL */ if (state == NULL) { state = hash_init(type, NULL); } /* * setup for the COMPLEX hash */ (state->chkpt)(state); state->bytes = FALSE; /* * catch the zero special case */ if (ciszero(complex)) { /* note a zero numeric value and return */ (state->note)(HASH_ZERO(state->base), state); return state; } /* * process the real value if not pure imaginary * * We will ignore the real part if the value is of the form 0+xi. */ if (!qiszero(complex->real)) { state = hash_number(type, complex->real, state); } /* * if the NUMBER is not real, process the imaginary value * * We will ignore the imaginary part of the value is of the form x+0i. */ if (!cisreal(complex)) { /* note the sqrt(-1) */ (state->note)(HASH_COMPLEX(state->base), state); /* hash the imaginary value */ state = hash_number(type, complex->imag, state); } /* * all done */ return state; }
int insert(char *beg, int type) {// insert name and type into symbol table int hash = hash_number(beg); while (!stl->tab.sym[hash].empty) HASH(hash); stl->tab.sym[hash].empty = false; stl->tab.sym[hash].type = type; stl->tab.sym[hash].name = (char *)malloc((strlen(beg) + 1) * sizeof(char)); strcpy(stl->tab.sym[hash].name, beg); return hash; }
Func* function_info(char *beg, const int line) { int hash = hash_number(beg); int pre_hash = hash; symbol_table_list *curr = stl; while (curr) { while (!curr->tab.sym[hash].empty && strcmp(beg, curr->tab.sym[hash].name)) HASH(hash); if (curr->tab.sym[hash].empty) { curr = curr->pre; } else if (curr->tab.sym[hash].type != Fun) { PANIC("conflicting types", line); } else return curr->tab.sym[hash].fun; hash = pre_hash; } return 0; }
Struct* struct_info(char *beg, const int line) {// get array's dimension int hash = hash_number(beg); int pre_hash = hash; symbol_table_list *curr = stl; while (curr) { while (!curr->tab.sym[hash].empty && strcmp(beg, curr->tab.sym[hash].name)) HASH(hash); if (curr->tab.sym[hash].empty) { curr = curr->pre; } else if (curr->tab.sym[hash].type != Stru) { PANIC("conflicting types", line); } else return curr->tab.sym[hash].stru; hash = pre_hash; } return 0; }
PUBLIC void *HTHashtable_object (HTHashtable * me, const char *key) { if(me) { int size = me->size; int i = hash_number(key,size); HTList * l = (HTList *)me->table[i]; if (l) { HTList *cur = l; keynode *kn; while ((kn = (keynode *) HTList_nextObject(cur))) { if(!strcmp(key,kn->key)) return kn->object; } } } return NULL; }
int lookup(char *beg, const int type, const int line, bool flag) {// lookup variable in symbol table int hash = hash_number(beg); int pre_hash = hash; symbol_table_list *curr = stl; while (curr) { while (!curr->tab.sym[hash].empty && strcmp(beg, curr->tab.sym[hash].name)) HASH(hash); if (curr->tab.sym[hash].empty) { if (flag) return -1; else curr = curr->pre; } else if (curr->tab.sym[hash].type != type) { PANIC("conflicting types", line); } else return hash; hash = pre_hash; } return -1; }
PUBLIC BOOL HTHashtable_addObject (HTHashtable *me, const char *key, void *newObject) { if(me) { int size = me->size; int i = hash_number(key,size); HTList *l = (HTList *)me->table[i]; keynode *kn; if(!l) l = me->table[i] = HTList_new(); if ((kn = (keynode *) HT_CALLOC(1, sizeof (keynode))) == NULL) HT_OUTOFMEM("HTHashtable_addObject"); StrAllocCopy(kn->key,key); kn->object = newObject; HTList_addObject(l,kn); me->count++; return YES; } return NO; }
PUBLIC BOOL HTHashtable_removeObject (HTHashtable *me, const char *key) { if(me) { int size = me->size; int i = hash_number(key,size); HTList *l = (HTList *)me->table[i]; if(l) { HTList *cur = l; keynode *kn; while ((kn = (keynode *) HTList_nextObject(cur))) { if(!strcmp(key,kn->key)) { HTList_removeObject(l,kn); me->count--; return YES; } } } } return NO; }
/* * hash_value - hash a value * * given: * type - hash type (see hash.h) * v - the value * state - the state to hash or NULL * * returns: * the new state */ HASH * hash_value(int type, void *v, HASH *state) { LISTELEM *ep; /* list element pointer */ ASSOCELEM **assochead; /* association chain head */ ASSOCELEM *aep; /* current association value */ ASSOCELEM *nextaep; /* next association value */ VALUE *value = (VALUE *)v; /* v cast to a VALUE */ VALUE *vp; /* pointer to next OBJ table value */ ZVALUE fileval; /* size, position, dev, inode of a file */ int i; /* * initialize if state is NULL */ if (state == NULL) { state = hash_init(type, NULL); } /* * process the value type */ switch (value->v_type) { case V_NULL: (state->chkpt)(state); state->bytes = TRUE; break; case V_INT: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); /* hash as if we have a 64 bit value */ state = hash_int(type, value->v_int, state); break; case V_NUM: /* hash this type */ state = hash_number(type, value->v_num, state); break; case V_COM: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); /* hash this type */ state = hash_complex(type, value->v_com, state); break; case V_ADDR: /* there is nothing to setup, simply hash what we point at */ state = hash_value(type, value->v_addr, state); break; case V_STR: /* strings have no setup */ /* hash this type */ state = hash_STR(type, value->v_str, state); break; case V_MAT: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); state->bytes = TRUE; /* hash all the elements of the matrix */ for (i=0; i < value->v_mat->m_size; ++i) { /* hash the next matrix value */ state = hash_value(type, value->v_mat->m_table+i, state); state->bytes = FALSE; /* as if reading words */ } break; case V_LIST: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); /* hash all the elements of the list */ for (i=0, ep = value->v_list->l_first; ep != NULL && i < value->v_list->l_count; ++i, ep = ep->e_next) { /* hash the next list value */ state = hash_value(type, &ep->e_value, state); state->bytes = FALSE; /* as if reading words */ } break; case V_ASSOC: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); state->bytes = TRUE; /* hash the association */ assochead = value->v_assoc->a_table; for (i = 0; i < value->v_assoc->a_size; i++) { nextaep = *assochead; while (nextaep) { aep = nextaep; nextaep = aep->e_next; /* hash the next association value */ state = hash_value(type, &aep->e_value, state); state->bytes = FALSE; /* as if reading words */ } assochead++; } break; case V_OBJ: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); state->bytes = TRUE; /* reading bytes */ /* hash the object name and then the element values */ state = hash_str(type, objtypename( value->v_obj->o_actions->oa_index), state); (state->chkpt)(state); for (i=value->v_obj->o_actions->oa_count, vp=value->v_obj->o_table; i-- > 0; vp++) { /* hash the next object value */ state = hash_value(type, vp, state); state->bytes = FALSE; /* as if reading words */ } break; case V_FILE: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); /* hash file length if possible */ if (getsize(value->v_file, &fileval) == 0) { state = hash_zvalue(type, fileval, state); zfree(fileval); } else { /* hash -1 for invalid length */ state = hash_long(type, (long)-1, state); } /* hash the file position if possible */ if (getloc(value->v_file, &fileval) == 0) { state = hash_zvalue(type, fileval, state); zfree(fileval); } else { /* hash -1 for invalid location */ state = hash_long(type, (long)-1, state); } /* hash the file device if possible */ if (get_device(value->v_file, &fileval) == 0) { state = hash_zvalue(type, fileval, state); zfree(fileval); } else { /* hash -1 for invalid device */ state = hash_long(type, (long)-1, state); } /* hash the file inode if possible */ if (get_inode(value->v_file, &fileval) == 0) { state = hash_zvalue(type, fileval, state); zfree(fileval); } else { /* hash -1 for invalid inode */ state = hash_long(type, (long)-1, state); } break; case V_RAND: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); /* hash the RAND state */ state = hash_int(type, value->v_rand->seeded, state); state = hash_int(type, value->v_rand->bits, state); (state->update)(state, (USB8 *)value->v_rand->buffer, SLEN*FULL_BITS/8); state = hash_int(type, value->v_rand->j, state); state = hash_int(type, value->v_rand->k, state); state = hash_int(type, value->v_rand->need_to_skip, state); (state->update)(state, (USB8 *)value->v_rand->slot, SCNT*FULL_BITS/8); (state->update)(state, (USB8*)value->v_rand->shuf, SHUFLEN*FULL_BITS/8); state->bytes = FALSE; /* as if reading words */ break; case V_RANDOM: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); /* hash the RANDOM state */ state = hash_int(type, value->v_random->seeded, state); state = hash_int(type, value->v_random->bits, state); (state->update)(state, (USB8 *)&(value->v_random->buffer), BASEB/8); state = hash_zvalue(type, value->v_random->r, state); state = hash_zvalue(type, value->v_random->n, state); state->bytes = FALSE; /* as if reading words */ break; case V_CONFIG: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); /* hash the CONFIG state */ state = hash_int(type, value->v_config->outmode, state); state = hash_int(type, value->v_config->outmode2, state); state = hash_long(type,(long)value->v_config->outdigits, state); state = hash_number(type, value->v_config->epsilon, state); state = hash_long(type, (long)value->v_config->epsilonprec, state); state = hash_flag(type, value->v_config->traceflags, state); state = hash_long(type, (long)value->v_config->maxprint, state); state = hash_len(type, value->v_config->mul2, state); state = hash_len(type, value->v_config->sq2, state); state = hash_len(type, value->v_config->pow2, state); state = hash_len(type, value->v_config->redc2, state); state = hash_bool(type, value->v_config->tilde_ok, state); state = hash_bool(type, value->v_config->tab_ok, state); state = hash_long(type, (long)value->v_config->quomod, state); state = hash_long(type, (long)value->v_config->quo, state); state = hash_long(type, (long)value->v_config->mod, state); state = hash_long(type, (long)value->v_config->sqrt, state); state = hash_long(type, (long)value->v_config->appr, state); state = hash_long(type, (long)value->v_config->cfappr, state); state = hash_long(type, (long)value->v_config->cfsim, state); state = hash_long(type, (long)value->v_config->outround, state); state = hash_long(type, (long)value->v_config->round, state); state = hash_bool(type, value->v_config->leadzero, state); state = hash_bool(type, value->v_config->fullzero, state); state = hash_long(type, (long)value->v_config->maxscancount, state); state = hash_str(type, value->v_config->prompt1, state); state->bytes = FALSE; /* as if just read words */ state = hash_str(type, value->v_config->prompt2, state); state->bytes = FALSE; /* as if just read words */ state = hash_int(type, value->v_config->blkmaxprint, state); state = hash_bool(type, value->v_config->blkverbose, state); state = hash_int(type, value->v_config->blkbase, state); state = hash_int(type, value->v_config->blkfmt, state); state = hash_long(type, (long)value->v_config->resource_debug, state); state = hash_long(type, (long)value->v_config->calc_debug, state); state = hash_long(type, (long)value->v_config->user_debug, state); state = hash_bool(type, value->v_config->verbose_quit, state); state = hash_int(type, value->v_config->ctrl_d, state); state = hash_str(type, value->v_config->program, state); state = hash_str(type, value->v_config->base_name, state); state = hash_bool(type, value->v_config->windows, state); state = hash_bool(type, value->v_config->cygwin, state); state = hash_bool(type, value->v_config->compile_custom, state); if (value->v_config->allow_custom != NULL && *(value->v_config->allow_custom)) { state = hash_bool(type, TRUE, state); } else { state = hash_bool(type, FALSE, state); } state = hash_str(type, value->v_config->version, state); state = hash_int(type, value->v_config->baseb, state); state = hash_bool(type, value->v_config->redecl_warn, state); state = hash_bool(type, value->v_config->dupvar_warn, state); break; case V_HASH: /* setup for the this value type */ (state->chkpt)(state); (state->type)(value->v_type, state); /* hash the HASH state */ state = hash_int(type, value->v_hash->type, state); state = hash_bool(type, value->v_hash->bytes,state); state = hash_int(type, value->v_hash->base, state); state = hash_int(type, value->v_hash->chunksize, state); state = hash_int(type, value->v_hash->unionsize, state); (state->update)(state, value->v_hash->h_union.data, state->unionsize); state->bytes = FALSE; /* as if reading words */ break; case V_BLOCK: /* there is no setup for a BLOCK */ /* hash the octets in the BLOCK */ if (value->v_block->datalen > 0) { state = hash_usb8(type, value->v_block->data, value->v_block->datalen, state); } break; case V_OCTET: /* there is no setup for an OCTET */ /* hash the OCTET */ state = hash_usb8(type, value->v_octet, 1, state); break; case V_NBLOCK: /* there is no setup for a NBLOCK */ /* hash the octets in the NBLOCK */ if (value->v_nblock->blk->datalen > 0) { state = hash_usb8(type, value->v_nblock->blk->data, value->v_nblock->blk->datalen, state); } break; default: math_error("hashing an unknown value"); /*NOTREACHED*/ } return state; }
const hash_number operator/( const hash_number& number_a, const hash_number& number_b) { return hash_number(number_a) /= number_b; }
const hash_number operator<<(const hash_number& number_a, int shift) { return hash_number(number_a) <<= shift; }