/* Look up an entry in a symhashtable, returning either a pointer to the symnode for the entry or NULL. slot is where to look; if slot == NOHASHSLOT, then apply the hash function to figure it out. */ symnode_t *lookup_symhashtable(symhashtable_t *hashtable, char *name, int slot) { symnode_t *node; assert(hashtable); if (slot == NOHASHSLOT) slot = hashPJW(name, hashtable->size); for (node = hashtable->table[slot]; node != NULL && !name_is_equal(node, name); node = node->next) ; return node; }
/* Insert a new entry into a symhashtable, but only if it is not already present. */ symnode_t *insert_into_symhashtable(symhashtable_t *hashtable, var_lookup_type type, char *name, int lineno, var_type vType) { assert(hashtable); int slot = hashPJW(name, hashtable->size); symnode_t *node = lookup_symhashtable(hashtable, name, slot); /* error check if node already existed! */ if (node == NULL) { node = create_symnode(name, type, hashtable, lineno); node->vType = vType; node->next = hashtable->table[slot]; hashtable->table[slot] = node; } return node; }
void collect_literals(ast_node root, symboltable_t *symtab){ ast_node child; symnode_t *node; symhashtable_t *collection = symtab->literal_collection; assert(collection != NULL); char* name; int slot = 0; /* Recursively call the function to traverse the tree in a preorder way */ for(child = root->left_child; child != NULL; child = child->right_sibling){ collect_literals(child, symtab); } switch (root->node_type) { case STRING_LITERAL_N: name = root->value_string; // Calculate slot for this node, try to find the current node in the symbol table slot = hashPJW(name, collection->size); node = lookup_symhashtable(collection, name, slot); if(node == NULL){ insert_into_symhashtable(collection, root); } break; /* Need to hash the value differently so as to not to mistake strings and ints, (e.g. 1 vs "1") */ case INT_LITERAL_N: name = calloc(DEFAULTSTRSIZE, sizeof(char)); sprintf(name, "__%d", root->value_int); root->value_string = strdup(name); slot = hashPJW(name, collection->size); node = lookup_symhashtable(collection, name, slot); if(node == NULL){ insert_into_symhashtable(collection, root); } break; case RETURN_N: // Empty return. Create a new symnode to add to // the collection because otherwise it will give us // trouble later when trying to create quads, since // the function to create quads takes symnodes and there // is currently no symnode for this empty return. if(root->left_child != NULL){ if(root->left_child->node_type == VOID_TYPE_N){ name = calloc(DEFAULTSTRSIZE, sizeof(char)); sprintf(name, "__%s", "void"); root->left_child->value_string = calloc(DEFAULTSTRSIZE, sizeof(char)); strcpy(root->left_child->value_string, name); slot = hashPJW(name, collection->size); node = lookup_symhashtable(collection, name, slot); if(node == NULL){ insert_into_symhashtable(collection, root->left_child); } } } default: break; } }
/* Insert a new entry into a symhashtable, but only if it is not already present. Return*/ symnode_t *insert_into_symhashtable(symhashtable_t *hashtable, ast_node astnode) { char* name = astnode->value_string; assert(hashtable); int slot = hashPJW(name, hashtable->size); symnode_t *node = lookup_symhashtable(hashtable, name, slot); /* error check if node already existed! */ if (node == NULL) { node = create_symnode(name, hashtable); node->abnode = astnode; astnode->snode = node; if(astnode->node_type == INT_LITERAL_N){ node->num_val = astnode->value_int; } if(astnode->node_type == ARRAY_TYPE_N) { if(astnode->left_child != NULL ){ astnode->array_length = astnode->left_child->value_int; node->array_length = astnode->array_length; } } if(astnode->node_type == STRING_LITERAL_N){ node->type = STRING_T; } if(astnode->node_type == FUNC_DECLARATION_N) { //printf("FUNC_DEC detected!"); if(astnode->return_type == INT_TYPE_N) { node->type = FUNC_INT_T; //printf(" %s\n", TYPE_NAME(node->type)); } else if(astnode->return_type == VOID_TYPE_N) { node->type = FUNC_VOID_T; //printf(" %s\n", TYPE_NAME(node->type)); } ast_node anode; int i = 0; assert(astnode->left_child != NULL); for(anode = astnode->left_child->left_child; anode != NULL; anode = anode->right_sibling) { i++; } node->num_parameters = i; node->parameters = calloc(sizeof(decl_type), i); assert(node->parameters); i = 0; for(anode = astnode->left_child->left_child; anode != NULL; anode = anode->right_sibling) { if(anode->return_type == INT_TYPE_N) { node->parameters[i] = VAR_INT_T; } else if(anode->return_type == ARRAY_TYPE_N){ node->parameters[i] = VAR_ARRAY_INT_T; } i++; } } else if(astnode->node_type == ID_N) { //printf("VAR detected!"); if(astnode->return_type == INT_TYPE_N) { node->type = VAR_INT_T; //printf(" %s\n", TYPE_NAME(node->type)); } } else if(astnode->node_type == ARRAY_TYPE_N){ if(astnode->return_type == INT_TYPE_N) { node->type = VAR_ARRAY_INT_T; //printf(" %s\n", TYPE_NAME(node->type)); } } node->next = hashtable->table[slot]; hashtable->table[slot] = node; } else{ if(node->abnode->node_type == ARRAY_TYPE_N || node->abnode->return_type == ARRAY_TYPE_N) { node->abnode->array_length = node->array_length; } } return node; }