/** * Gets (and returns) a symbol from the token file. * * The idx is the hash of the symbol. See symbol_hash in pl0-compiler.c. * * @param input_file the token file * @param is_new specifies whether or not we're getting a new symbol * @return a pointer to the symbol table after creating a new symbol */ symbol *get_symbol(FILE *input_file, int is_new) { char symbol_name[12]; int idx = -1; if(fscanf(input_file, "%11s", symbol_name) == 1 && strlen(symbol_name) > 0) { if(DEBUG) printf("DEBUG: symbol_name = %s\n", symbol_name); int tmp_l = curr_l; do { idx = symbol_hash(symbol_name, tmp_l--); } while(!is_new && (idx < 0 || idx >= MAX_SYMBOL_TABLE_SIZE || !symbol_table[idx].kind) && tmp_l >= 0); if(DEBUG) printf("DEBUG: idx = %d\n", idx); if(idx >= 0 && idx < MAX_SYMBOL_TABLE_SIZE) { if(is_new) { strcpy(symbol_table[idx].name, symbol_name); if(DEBUG) printf("DEBUG: BRAND NEW SYMBOL!!!!!!!!!!!\n"); } if(DEBUG) printf("DEBUG: ********************************\n"); if(DEBUG) printf("DEBUG: symbol_table[%d].kind = %d\n", idx, symbol_table[idx].kind); if(DEBUG) printf("DEBUG: symbol_table[%d].name = %s\n", idx, symbol_table[idx].name); if(DEBUG) printf("DEBUG: symbol_table[%d].val = %d\n", idx, symbol_table[idx].val); if(DEBUG) printf("DEBUG: symbol_table[%d].level = %d\n", idx, symbol_table[idx].level); if(DEBUG) printf("DEBUG: symbol_table[%d].addr = %d\n", idx, symbol_table[idx].addr); if(DEBUG) printf("DEBUG: ********************************\n"); return &symbol_table[idx]; } } return NULL; }
/** @todo implement this function */ struct node* symbol_search (sym_table_t* symTab, const char* name, int* hash, int* index) { *hash = symbol_hash(name); *index = *hash % SYMBOL_SIZE; // printf("%d\n",*index); if(symTab->hash_table[*index] == NULL) { return NULL; } else { // printf("symTab->hash_table[index]->symbol.name = %s \n",symTab->hash_table[*index]->symbol.name); node_t *tmpNode = malloc(sizeof(node_t)); tmpNode = symTab->hash_table[*index]; while(tmpNode != NULL) { symbol_t *tmpSymbol = malloc(sizeof(symbol_t)); *tmpSymbol = tmpNode->symbol; // printf("hash %d \n", *hash); // printf("tmpNode->hash %d \n", tmpNode->hash); if (tmpNode->hash == *hash) { // printf("tmpNode->hash == *hash\n"); // printf("tmpSymbol->name = %s \n", tmpSymbol->name); // printf("tmpSymbol->addr = %d \n", tmpSymbol->addr); if (strcasecmp(tmpNode->symbol.name, name) == 0) { return tmpNode; } } free(tmpSymbol); tmpNode = tmpNode->next; } free(tmpNode); // printf("not null\n"); } return NULL; }
closure *table_lookup(closure *symbol, symbol_table *table) { // TODO resize array here when load too great. int hash = symbol_hash(symbol, table); closure *chain = table->array[hash]; if (chain == NULL) return nil(); return assoc(symbol, chain); }
void table_insert(closure *symbol, closure *value, symbol_table *table) { int hash = symbol_hash(symbol, table); closure *chain = table->array[hash]; if (chain == NULL) chain = nil(); closure *prev = assoc(symbol, chain); if (!nilp(prev)){ prev->in->cons->car = value; } else { table->array[hash] = cheap_cons(cheap_list(2, symbol, value), chain); } table->entries++; }
/** @todo implement this function */ int symbol_add (sym_table_t* symTab, const char* name, int addr) { int hash; int index; char* cpyName = (char *) name; if(symbol_search(symTab, name, &hash, &index) == NULL) { node_t *newNode = malloc(sizeof(struct node)); struct symbol *newSymbol = malloc(sizeof(struct symbol)); newSymbol->name = malloc(sizeof(char *)); strcpy(newSymbol->name, cpyName); newSymbol->addr = addr; newNode->symbol = *newSymbol; newNode->hash = symbol_hash(cpyName); int newIndex = symbol_hash(cpyName) % SYMBOL_SIZE; newNode->next = symTab->hash_table[newIndex]; symTab->hash_table[newIndex] = newNode; if(addr < SYMBOL_SIZE) { strcpy(symTab->addr_table[addr], cpyName); } return 1; } else { return 0; } }
static void add_cache_symbol(Context * ctx, ULONG64 pc, PCSTR name, Symbol * sym, int error) { unsigned h = symbol_hash(pc, name); ContextExtensionWinSym * ext = EXT(ctx->mem); SymbolCacheEntry * entry = (SymbolCacheEntry *)loc_alloc_zero(sizeof(SymbolCacheEntry)); assert(!ctx->mem->exited); entry->pc = pc; strcpy(entry->name, name); entry->error = get_error_report(error); if (!error) { entry->frame_relative = sym->frame > 0; entry->sym_class = sym->sym_class; entry->module = sym->module; entry->index = sym->index; } if (ext->symbol_cache == NULL) ext->symbol_cache = (SymbolCacheEntry **)loc_alloc_zero(sizeof(SymbolCacheEntry *) * SYMBOL_CACHE_SIZE); entry->next = ext->symbol_cache[h]; ext->symbol_cache[h] = entry; }
/** @todo implement this function */ struct node* symbol_search (sym_table_t* symTab, const char* name, int* hash, int* index) { *hash = symbol_hash(name); *index = (*hash % SYMBOL_SIZE); // node_t* nodepointer = symTab -> hash_table[*index]; if(symTab -> hash_table[*index] == NULL){ return NULL; } else{ for(node_t* nodepointer = symTab -> hash_table[*index]; nodepointer != NULL; nodepointer = nodepointer -> next){ int compare = strcmp(name,nodepointer -> symbol.name); if(compare == 0){ return nodepointer; } } } return NULL; }
static int find_cache_symbol(Context * ctx, int frame, ULONG64 pc, PCSTR name, Symbol * sym) { ContextExtensionWinSym * ext = EXT(ctx->mem); if (ext->symbol_cache != NULL) { int cnt = 0; SymbolCacheEntry * entry = ext->symbol_cache[symbol_hash(pc, name)]; while (entry != NULL) { if (entry->pc == pc && strcmp(entry->name, name) == 0) { if (entry->error == NULL) { if (entry->frame_relative) { assert(frame >= 0); sym->frame = frame - STACK_NO_FRAME; } else { ctx = ctx->mem; } sym->ctx = ctx; sym->sym_class = entry->sym_class; sym->module = entry->module; sym->index = entry->index; } set_error_report_errno(entry->error); return 1; } else if (cnt > 32) { while (entry->next) { SymbolCacheEntry * next = entry->next; entry->next = next->next; release_error_report(next->error); loc_free(next); } return 0; } entry = entry->next; cnt++; } } return 0; }