void closeScope() { if(symbolTable.currentLevel < 0) { printf("void closeScope(): Error: current level < 0. No scope can be close.\n"); return; } SymbolTableEntry* scopeChain = symbolTable.scopeDisplay[symbolTable.currentLevel]; SymbolTableEntry* nextScopeChain = NULL; while(scopeChain) { int hashIndex = HASH(scopeChain->name); removeFromHashTrain(hashIndex, scopeChain); if(scopeChain->sameNameInOuterLevel) { enterIntoHashTrain(hashIndex, scopeChain->sameNameInOuterLevel); } nextScopeChain = scopeChain->nextInSameLevel; scopeChain = nextScopeChain; } // symbolTable.scopeDisplay[symbolTable.currentLevel] = NULL; // --symbolTable.currentLevel; }
//remove the symbol from the current scope void removeSymbol(char* symbolName) { int hashIndex = HASH(symbolName); SymbolTableEntry* hashChain = symbolTable.hashTable[hashIndex]; while(hashChain) { if(strcmp(hashChain->name, symbolName) == 0) { if(hashChain->nestingLevel != symbolTable.currentLevel) { printf("void removeSymbol(...) Error: try to removed ID \'%s\' from the scope other than currentScope.\n", symbolName); return; } else { removeFromHashTrain(hashIndex, hashChain); if(hashChain->sameNameInOuterLevel) { enterIntoHashTrain(hashIndex, hashChain->sameNameInOuterLevel); } break; } } else { hashChain = hashChain->nextInHashChain; } } if(!hashChain) { printf("void removeSymbol(...) Error: try to removed ID \'%s\' not in the symbol table.\n", symbolName); return; } SymbolTableEntry* tmpPrev = NULL; SymbolTableEntry* scopeChain = symbolTable.scopeDisplay[symbolTable.currentLevel]; while(scopeChain) { if(strcmp(scopeChain->name, symbolName) == 0) { if(tmpPrev) { tmpPrev->nextInSameLevel = scopeChain->nextInSameLevel; } else { symbolTable.scopeDisplay[symbolTable.currentLevel] = scopeChain->nextInSameLevel; } free(scopeChain); break; } else { tmpPrev = scopeChain; scopeChain = scopeChain->nextInSameLevel; } } }
SymbolTableEntry* enterSymbol(char* symbolName, SymbolAttribute* attribute) { int hashIndex = HASH(symbolName); SymbolTableEntry* hashChain = symbolTable.hashTable[hashIndex]; SymbolTableEntry* newEntry = newSymbolTableEntry(symbolTable.currentLevel); newEntry->attribute = attribute; newEntry->name = symbolName; if(attribute->attributeKind == VARIABLE_ATTRIBUTE) { if(symbolTable.currentLevel != 0) { if(attribute->attr.typeDescriptor->kind == SCALAR_TYPE_DESCRIPTOR) { ARoffset -= 4; }else { int i, size = 4; ArrayProperties temp = attribute->attr.typeDescriptor->properties.arrayProperties; for(i=0; i<temp.dimension; i++) size *= temp.sizeInEachDimension[i]; ARoffset -= size; } } newEntry->offset = ARoffset; } while(hashChain) { if(strcmp(hashChain->name, symbolName) == 0) { if(hashChain->nestingLevel == symbolTable.currentLevel) { printf("void enterSymbol(...): ID \'%s\' is redeclared(at the same level#%d).\n", symbolName, symbolTable.currentLevel); free(newEntry); return NULL; } else { removeFromHashTrain(hashIndex, hashChain); newEntry->sameNameInOuterLevel = hashChain; break; } } else { hashChain = hashChain->nextInHashChain; } } enterIntoHashTrain(hashIndex, newEntry); newEntry->nextInSameLevel = symbolTable.scopeDisplay[symbolTable.currentLevel]; symbolTable.scopeDisplay[symbolTable.currentLevel] = newEntry; return newEntry; }
SymbolTableEntry* enterSymbol(char* symbolName, SymbolAttribute* attribute) { SymbolTableEntry* oldsym = retrieveSymbol(symbolName); if(oldsym != NULL && oldsym.nestingLevel == sybolTable.currentLevel) { printf("Error: %s has been redecalred!"); g_anyErrorOccur = 1; return oldsym; } //new entry SymbolTableEntry* newsym = newSymbolTableEntry(symbolName, sybolTable.currentLevel); newsym.attribute = attribute;//the space of attribute may be changed,need to be careful. //add to scope display newsym.nextInSameLevel = symbolTable.scopeDisplay[symbolTable.currentLevel]; symbolTable.scopeDisplay[symbolTable.currentLevel] = newsym; //add to hash table if(oldsym == NULL) enterIntoHashTrain(newsym); else { removeFromHashTrain(oldsym); enterIntoHashTrain(newsym); } newsym.sameNameInOuterLevel = oldsym; }
void closeScope() { SymbolTableEntry* sym; sym = sybolTable.scopeDisplay[sybolTable.currentLevel]; while(sym!=NULL) { SymbolTableEntry* nextInSameLevel = sym.nextInSameLevel; SymbolTableEntry* prevsym = sym. removeFromHashTrain(sym); if(prevsym != NULL) enterIntoHashTrain(prevsym); sym=nextInSameLevel; } symbolTable.currentLevel--; }
SymbolTableEntry* enterSymbol(char* symbolName, SymbolAttribute* attribute) { int hashIndex = HASH(symbolName); SymbolTableEntry* hashChain = symbolTable.hashTable[hashIndex]; SymbolTableEntry* newEntry = newSymbolTableEntry(symbolTable.currentLevel); newEntry->attribute = attribute; newEntry->name = symbolName; if(attribute->attributeKind == VARIABLE_ATTRIBUTE) { newEntry->offset = ARoffset; ARoffset -= calc_size(attribute->attr.typeDescriptor); } while(hashChain) { if(strcmp(hashChain->name, symbolName) == 0) { if(hashChain->nestingLevel == symbolTable.currentLevel) { printf("void enterSymbol(...): ID \'%s\' is redeclared(at the same level#%d).\n", symbolName, symbolTable.currentLevel); free(newEntry); return NULL; } else { removeFromHashTrain(hashIndex, hashChain); newEntry->sameNameInOuterLevel = hashChain; break; } } else { hashChain = hashChain->nextInHashChain; } } enterIntoHashTrain(hashIndex, newEntry); newEntry->nextInSameLevel = symbolTable.scopeDisplay[symbolTable.currentLevel]; symbolTable.scopeDisplay[symbolTable.currentLevel] = newEntry; return newEntry; }