void SymbolTable::insertSymbol(const Symbol& symbol) { if (symbolExists(symbol)) { throw RedeclarationException(symbol); } else { checkAmbiguity(symbol); } _table[symbol.scope()].push_back(symbol); }
void Context::setConstantSymbols() { if (_declarations == NULL) return; // We first add normal constants, then actors and verbs which are treated as constants also for (int i = 0; i < _declarations->size(); i++) if ((*_declarations)[i]->getType() == DECLARATION_CONST) { string name = (*_declarations)[i]->getName(); if (symbolExists(name)) Log::write(LOG_ERROR, "Symbol \"%s\" already declared !\n", name.c_str()); _constantSymbols[name] = (*_declarations)[i]->getValue(); } else if ((*_declarations)[i]->getType() == DECLARATION_ACTOR) { string name = (*_declarations)[i]->getName(); if (symbolExists(name)) Log::write(LOG_ERROR, "Symbol \"%s\" already declared !\n", name.c_str()); _constantSymbols[name] = _currentActor++; if (_currentActor > Game::N_DEFAULT_ACTORS) Log::write(LOG_ERROR, "Too many actors declared !\n"); } else if ((*_declarations)[i]->getType() == DECLARATION_VERB) { string name = (*_declarations)[i]->getName(); if (symbolExists(name)) Log::write(LOG_ERROR, "Symbol \"%s\" already declared !\n", name.c_str()); _constantSymbols[name] = _currentVerb++; } else if ((*_declarations)[i]->getType() == DECLARATION_CLASS) { if (_currentClass > MAX_CLASSES) Log::write(LOG_ERROR, "Too many classes declared !\n"); string name = (*_declarations)[i]->getName(); if (symbolExists(name)) Log::write(LOG_ERROR, "Symbol \"%s\" already declared !\n", name.c_str()); _constantSymbols[name] = _currentClass++; } }
void Context::setFunctionSymbols() { if (_functions == NULL) return; for (int i = 0; i < _functions->size(); i++) { string name = (*_functions)[i]->getName(); if (symbolExists(name)) Log::write(LOG_ERROR, "Function \"%s\" already declared !\n", name.c_str()); _functionSymbols[name] = (*_functions)[i]->getID(); } }
void Context::setVariableSymbols(bool fixedAddresses) { // No need to look for variables with fixed addresses when the context type is not global if (_declarations == NULL || ((_type != CONTEXT_GAME) && fixedAddresses)) return; for (int i = 0; i < _declarations->size(); i++) if ((*_declarations)[i]->getType() == DECLARATION_VAR) { if ((*_declarations)[i]->hasFixedAddress() != fixedAddresses) { if (_type != CONTEXT_GAME) Log::write(LOG_ERROR, "Cannot specify the address of local variable !\n"); continue; } string name = (*_declarations)[i]->getName(); uint32_t address; // Check if symbol doesn't exist already if (symbolExists(name)) Log::write(LOG_ERROR, "Symbol \"%s\" already declared !\n", name.c_str()); // Check if address is not already taken in case it's a fixed address map<string, uint32_t>::const_iterator iterator = _variableSymbols.begin(); if (fixedAddresses) { address = (*_declarations)[i]->getValue(); if (isAddressUsed(address)) Log::write(LOG_ERROR, "Symbol \"%s\" can't be mapped as this address is already used !\n", name.c_str()); } // Search through the map to get the smallest available address else { address = (_type == CONTEXT_GAME) ? 0 : LOCAL_VARIABLE_MASK; while (isAddressUsed(address)) address++; } // Check wether the address fits in the autorized range // (and make sure we reserve the last local variable for temporary arrays) if ((_type == CONTEXT_GAME && address >= Game::MAX_WORD_VARIABLES) || (_type != CONTEXT_GAME && (address < LOCAL_VARIABLE_MASK || address >= ((Game::MAX_LOCAL_VARIABLES - 1) | LOCAL_VARIABLE_MASK)))) Log::write(LOG_ERROR, "Symbol \"%s\" can't be mapped as this address is invalid !\n", name.c_str()); _variableSymbols[name] = address; } }
bool SymbolTable::addEquation(const std::wstring& name, int file, int section, size_t referenceIndex) { if (isValidSymbolName(name) == false) return false; if (symbolExists(name,file,section)) return false; setFileSectionValues(name,file,section); SymbolKey key = { name, file, section }; SymbolInfo value = { EquationSymbol, referenceIndex }; symbols[key] = value; equationsCount++; return true; }
bool SymbolTable::addEquation(const std::wstring& name, unsigned int file, unsigned int section, std::wstring& replacement) { if (isValidSymbolName(name) == false) return false; if (symbolExists(name,file,section)) return false; setFileSectionValues(name,file,section); SymbolKey key = { name, file, section }; SymbolInfo value = { EquationSymbol, equations.size() }; symbols[key] = value; Equation equation = { name, replacement, file, section }; equations.push_back(equation); return true; }