ExpressionLayout * GlobalContext::expressionLayoutForSymbol(const Symbol * symbol) { if (symbol->isMatrixSymbol()) { int index = symbolIndex(symbol); if (m_matrixLayout[index] == nullptr && m_matrixExpressions[index] != nullptr) { m_matrixLayout[index] = m_matrixExpressions[index]->createLayout(); } return m_matrixLayout[index]; } return nullptr; }
/** * Returns the index where the `key` is stored in `info`, or returns `-1` if * not found. */ static zint infoFind(SymbolTableInfo *info, zvalue key) { zint arraySize = info->arraySize; zmapping *array = info->array; zint index = symbolIndex(key) % arraySize; for (int i = 0; i < DAT_SYMTAB_MAX_PROBES; i++) { zvalue foundKey = array[index].key; if (foundKey == NULL) { // As keys are never deleted, `NULL` means that we can't possibly // find the key at a later index. return -1; } else if (key == foundKey) { return index; } index = (index + 1) % arraySize; } return -1; }
void GlobalContext::setExpressionForSymbolName(const Expression * expression, const Symbol * symbol, Context & context) { int index = symbolIndex(symbol); if (symbol->isMatrixSymbol()) { int indexMatrix = symbol->name() - (char)Symbol::SpecialSymbols::M0; assert(indexMatrix >= 0 && indexMatrix < k_maxNumberOfMatrixExpressions); Expression * evaluation = expression ? expression->approximate<double>(context) : nullptr; // evaluate before deleting anything (to be able to evaluate M1+2->M1) if (m_matrixExpressions[indexMatrix] != nullptr) { delete m_matrixExpressions[indexMatrix]; m_matrixExpressions[indexMatrix] = nullptr; } if (m_matrixLayout[indexMatrix] != nullptr) { delete m_matrixLayout[indexMatrix]; m_matrixLayout[indexMatrix] = nullptr; } if (evaluation != nullptr) { if (evaluation->type() == Expression::Type::Complex) { m_matrixExpressions[indexMatrix] = new Matrix(&evaluation, 1, 1, false); } else { m_matrixExpressions[indexMatrix] = static_cast<Matrix *>(evaluation); } } return; } if (index < 0 || index >= k_maxNumberOfScalarExpressions) { return; } Expression * evaluation = expression ? expression->approximate<double>(context) : nullptr; // evaluate before deleting anything (to be able to evaluate A+2->A) if (m_expressions[index] != nullptr) { delete m_expressions[index]; m_expressions[index] = nullptr; } if (evaluation == nullptr) { return; } if (evaluation->type() == Expression::Type::Complex) { m_expressions[index] = static_cast<Complex<double> *>(evaluation); } else { m_expressions[index] = new Complex<double>(Complex<double>::Float(NAN)); delete evaluation; } }
/** * Mutates an instance, putting a mapping into it, possibly reallocating it * (hence the pointer arguments). As a minor convenience, this function * returns early (doing nothing) if given `NULL` for `elem.key`. */ static void putInto(zvalue *result, SymbolTableInfo **info, zmapping elem) { if (elem.key == NULL) { return; } zint arraySize = (*info)->arraySize; zmapping *array = (*info)->array; zint index = symbolIndex(elem.key) % arraySize; for (int i = 0; i < DAT_SYMTAB_MAX_PROBES; i++) { zvalue foundKey = array[index].key; if (foundKey == NULL) { array[index] = elem; (*info)->size++; return; } else if (foundKey == elem.key) { // Update a pre-existing mapping for the key. array[index].value = elem.value; return; } index = (index + 1) % arraySize; } // Too many collisions! Reallocate, and then add the originally-requested // pair. zvalue newResult = allocInstance(arraySize); // This grows `array`. SymbolTableInfo *newInfo = getInfo(newResult); for (int i = 0; i < arraySize; i++) { putInto(&newResult, &newInfo, array[i]); } putInto(&newResult, &newInfo, elem); *result = newResult; *info = newInfo; }
const Expression * GlobalContext::expressionForSymbol(const Symbol * symbol) { if (symbol->name() == Ion::Charset::SmallPi) { return &m_pi; } if (symbol->name() == Ion::Charset::Exponential) { return &m_e; } if (symbol->name() == Ion::Charset::IComplex) { return &m_i; } int index = symbolIndex(symbol); if (symbol->isMatrixSymbol()) { return m_matrixExpressions[index]; } if (index < 0 || index >= k_maxNumberOfScalarExpressions) { return nullptr; } if (m_expressions[index] == nullptr) { return defaultExpression(); } return m_expressions[index]; }
patternSymbolIndex symbolChooser::getSymbol(const triC& color, int symbolDim) { const QRgb rgbColor = color.qrgb(); symbolDimension_ = symbolDim; if (symbolMap_.contains(rgbColor)) { if (symbolMap_[rgbColor].borderWidth() == borderDimension_ && symbolMap_[rgbColor].symbolDimension() == symbolDimension_) { return symbolMap_[rgbColor]; } else { // right symbol, wrong size const int index = symbolMap_[rgbColor].index(); patternSymbolIndex symbolIndex(createSymbol(index, rgbColor), index, borderDimension_, symbolDimension_); symbolMap_.insert(rgbColor, symbolIndex); return symbolIndex; } } else { return createNewSymbolCurDims(rgbColor); } }