mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[apps] Clean GLobalContext
This commit is contained in:
@@ -15,61 +15,91 @@ constexpr char GlobalContext::expExtension[];
|
||||
constexpr char GlobalContext::funcExtension[];
|
||||
//constexpr char GlobalContext::seqExtension[];
|
||||
|
||||
/* Storage memory full */
|
||||
|
||||
static bool sStorageMemoryFull = false;
|
||||
|
||||
bool GlobalContext::RecordBaseNameIsFree(const char * baseName) {
|
||||
return RecordWithBaseName(baseName).isNull();
|
||||
}
|
||||
|
||||
bool GlobalContext::storageMemoryFull() {
|
||||
return sStorageMemoryFull;
|
||||
}
|
||||
|
||||
Poincare::Expression GlobalContext::ExpressionFromRecord(Ion::Storage::Record record) {
|
||||
if (record.isNull() || record.value().size == 0) {
|
||||
return Expression();
|
||||
}
|
||||
if (Ion::Storage::FullNameHasExtension(record.fullName(), expExtension, strlen(expExtension))) {
|
||||
return ExpressionFromSymbolRecord(record);
|
||||
}
|
||||
assert(Ion::Storage::FullNameHasExtension(record.fullName(), funcExtension, strlen(funcExtension)));
|
||||
return ExpressionFromFunctionRecord(record);
|
||||
}
|
||||
|
||||
Poincare::Expression GlobalContext::ExpressionFromSymbolRecord(Ion::Storage::Record record) {
|
||||
if (record.isNull() || record.value().size == 0) {
|
||||
return Expression();
|
||||
}
|
||||
assert(Ion::Storage::FullNameHasExtension(record.fullName(), expExtension, strlen(expExtension)));
|
||||
// An expression record value is the expression itself
|
||||
Ion::Storage::Record::Data d = record.value();
|
||||
return Expression::ExpressionFromAddress(d.buffer, d.size);
|
||||
}
|
||||
Poincare::Expression GlobalContext::ExpressionFromFunctionRecord(Ion::Storage::Record record) {
|
||||
if (record.isNull() || record.value().size == 0) {
|
||||
return Expression();
|
||||
}
|
||||
assert(Ion::Storage::FullNameHasExtension(record.fullName(), funcExtension, strlen(funcExtension)));
|
||||
/* An function record value has metadata before the expression. To get the
|
||||
* expression, use the funciton record handle. */
|
||||
StorageCartesianFunction f = StorageCartesianFunction(record);
|
||||
return f.expression();
|
||||
}
|
||||
|
||||
const Expression GlobalContext::expressionForSymbol(const SymbolAbstract & symbol) {
|
||||
Ion::Storage::Record r = RecordWithName(symbol.name());
|
||||
return expressionForSymbolAndRecord(symbol, r);
|
||||
Ion::Storage::Record r = RecordWithBaseName(symbol.name());
|
||||
return ExpressionForSymbolAndRecord(symbol, r);
|
||||
}
|
||||
|
||||
void GlobalContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) {
|
||||
sStorageMemoryFull = false;
|
||||
/* If the new expression contains the symbol, replace it because it will be
|
||||
* destroyed afterwards (to be able to do A+2->A) */
|
||||
Ion::Storage::Record record = RecordWithName(symbol.name());
|
||||
Expression e = expressionForSymbolAndRecord(symbol, record);
|
||||
Ion::Storage::Record record = RecordWithBaseName(symbol.name());
|
||||
Expression e = ExpressionFromRecord(record);
|
||||
if (e.isUninitialized()) {
|
||||
e = Undefined();
|
||||
}
|
||||
Expression finalExpression = expression.clone().replaceSymbolWithExpression(symbol, e);
|
||||
|
||||
// Set the expression in the storage depending on the symbol type
|
||||
Ion::Storage::Record::ErrorStatus err = Ion::Storage::Record::ErrorStatus::None;
|
||||
if (symbol.type() == ExpressionNode::Type::Symbol) {
|
||||
err = setExpressionForActualSymbol(finalExpression, symbol, record);
|
||||
err = SetExpressionForActualSymbol(finalExpression, symbol, record);
|
||||
} else {
|
||||
assert(symbol.type() == ExpressionNode::Type::Function);
|
||||
err = setExpressionForFunction(finalExpression, symbol, record);
|
||||
err = SetExpressionForFunction(finalExpression, symbol, record);
|
||||
}
|
||||
|
||||
// Handle a storage error
|
||||
if (err != Ion::Storage::Record::ErrorStatus::None) {
|
||||
assert(err == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable);
|
||||
sStorageMemoryFull = true;
|
||||
}
|
||||
}
|
||||
|
||||
Ion::Storage::Record GlobalContext::RecordWithName(const char * name) {
|
||||
const char * extensions[2] = {expExtension, funcExtension/*, seqExtension*/};
|
||||
return Ion::Storage::sharedStorage()->recordBaseNamedWithExtensions(name, extensions, 2);
|
||||
}
|
||||
|
||||
const Expression GlobalContext::expressionForSymbolAndRecord(const SymbolAbstract & symbol, Ion::Storage::Record r) {
|
||||
const Expression GlobalContext::ExpressionForSymbolAndRecord(const SymbolAbstract & symbol, Ion::Storage::Record r) {
|
||||
if (r.isNull()) {
|
||||
return Expression();
|
||||
}
|
||||
if (symbol.type() == ExpressionNode::Type::Symbol) {
|
||||
return expressionForActualSymbol(symbol, r);
|
||||
return ExpressionForActualSymbol(symbol, r);
|
||||
}
|
||||
assert(symbol.type() == ExpressionNode::Type::Function);
|
||||
return expressionForFunction(symbol, r);
|
||||
return ExpressionForFunction(symbol, r);
|
||||
}
|
||||
|
||||
const Expression GlobalContext::expressionForActualSymbol(const SymbolAbstract & symbol, Ion::Storage::Record r) {
|
||||
const Expression GlobalContext::ExpressionForActualSymbol(const SymbolAbstract & symbol, Ion::Storage::Record r) {
|
||||
assert(symbol.type() == ExpressionNode::Type::Symbol);
|
||||
// Constant symbols
|
||||
Symbol s = static_cast<const Symbol &>(symbol);
|
||||
@@ -80,38 +110,28 @@ const Expression GlobalContext::expressionForActualSymbol(const SymbolAbstract &
|
||||
return Float<double>(M_E);
|
||||
}
|
||||
// Look up the file system for symbol
|
||||
return Expression::ExpressionFromRecord(r);
|
||||
return ExpressionFromSymbolRecord(r);
|
||||
}
|
||||
|
||||
const Expression GlobalContext::expressionForFunction(const SymbolAbstract & symbol, Ion::Storage::Record r) {
|
||||
assert(symbol.type() == ExpressionNode::Type::Function);
|
||||
StorageCartesianFunction f = StorageCartesianFunction(r);
|
||||
return f.expression();
|
||||
}
|
||||
|
||||
Ion::Storage::Record::ErrorStatus GlobalContext::setExpressionForActualSymbol(const Expression & expression, const SymbolAbstract & symbol, Ion::Storage::Record previousRecord) {
|
||||
Ion::Storage::Record::ErrorStatus GlobalContext::SetExpressionForActualSymbol(const Expression & expression, const SymbolAbstract & symbol, Ion::Storage::Record previousRecord) {
|
||||
// Delete any record with same name (as it is going to be overriden)
|
||||
previousRecord.destroy();
|
||||
return Ion::Storage::sharedStorage()->createRecordWithExtension(symbol.name(), expExtension, expression.addressInPool(), expression.size());
|
||||
}
|
||||
|
||||
Ion::Storage::Record::ErrorStatus GlobalContext::setExpressionForFunction(const Expression & expressionToStore, const SymbolAbstract & symbol, Ion::Storage::Record previousRecord) {
|
||||
Ion::Storage::Record::ErrorStatus GlobalContext::SetExpressionForFunction(const Expression & expressionToStore, const SymbolAbstract & symbol, Ion::Storage::Record previousRecord) {
|
||||
size_t expressionToStoreSize = expressionToStore.isUninitialized() ? 0 : expressionToStore.size();
|
||||
size_t newDataSize = sizeof(StorageCartesianFunction::CartesianFunctionRecordData) + expressionToStoreSize;
|
||||
Ion::Storage::Record::ErrorStatus error = Ion::Storage::Record::ErrorStatus::None;
|
||||
if (Ion::Storage::FullNameHasExtension(previousRecord.fullName(), funcExtension, strlen(funcExtension))) {
|
||||
// The previous record was also a function: we want to keep its metadata
|
||||
// Prepare the new data to store
|
||||
Ion::Storage::Record::Data newData = previousRecord.value();
|
||||
newData.size = newDataSize;
|
||||
// Set the data
|
||||
error = previousRecord.setValue(newData);
|
||||
} else {
|
||||
// The previous record was not a function. Destroy it and create the new record.
|
||||
previousRecord.destroy();
|
||||
// Prepare the new data to store
|
||||
StorageCartesianFunction::CartesianFunctionRecordData newData;
|
||||
// Create the record
|
||||
error = Ion::Storage::sharedStorage()->createRecordWithExtension(symbol.name(), funcExtension, &newData, newDataSize);
|
||||
}
|
||||
if (error == Ion::Storage::Record::ErrorStatus::None && !expressionToStore.isUninitialized()) {
|
||||
@@ -121,4 +141,9 @@ Ion::Storage::Record::ErrorStatus GlobalContext::setExpressionForFunction(const
|
||||
return error;
|
||||
}
|
||||
|
||||
Ion::Storage::Record GlobalContext::RecordWithBaseName(const char * name) {
|
||||
const char * extensions[2] = {expExtension, funcExtension/*, seqExtension*/};
|
||||
return Ion::Storage::sharedStorage()->recordBaseNamedWithExtensions(name, extensions, 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <poincare/decimal.h>
|
||||
#include <poincare/symbol.h>
|
||||
#include <ion/storage.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace Shared {
|
||||
|
||||
@@ -14,23 +15,41 @@ class Integer;
|
||||
|
||||
class GlobalContext final : public Poincare::Context {
|
||||
public:
|
||||
// TODO: should this be store elsewhere?
|
||||
static constexpr char funcExtension[] = "func";
|
||||
static constexpr char expExtension[] = "exp";
|
||||
/* The expression recorded in global context is already a expression.
|
||||
static constexpr char funcExtension[] = "func"; // TODO: store this elsewhere?
|
||||
static constexpr char expExtension[] = "exp"; // TODO: store this elsewhere?
|
||||
//static constexpr char seqExtension[] = "seq";
|
||||
|
||||
// Storage information
|
||||
static bool RecordBaseNameIsFree(const char * baseName);
|
||||
static bool storageMemoryFull();
|
||||
|
||||
// Expression from record
|
||||
static Poincare::Expression ExpressionFromRecord(Ion::Storage::Record record);
|
||||
static Poincare::Expression ExpressionFromSymbolRecord(Ion::Storage::Record record);
|
||||
static Poincare::Expression ExpressionFromFunctionRecord(Ion::Storage::Record record);
|
||||
|
||||
/* Expression for symbol
|
||||
* The expression recorded in global context is already an expression.
|
||||
* Otherwise, we would need the context and the angle unit to evaluate it */
|
||||
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override;
|
||||
void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context & context) override;
|
||||
static Ion::Storage::Record RecordWithName(const char * name);
|
||||
static bool storageMemoryFull();
|
||||
//TODO static constexpr uint16_t k_maxNumberOfSequences = 10;
|
||||
void setExpressionForSymbol(
|
||||
const Poincare::Expression & expression,
|
||||
const Poincare::SymbolAbstract & symbol,
|
||||
Poincare::Context & context) override;
|
||||
|
||||
private:
|
||||
//static constexpr char seqExtension[] = "seq";
|
||||
const Poincare::Expression expressionForSymbolAndRecord(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r);
|
||||
const Poincare::Expression expressionForActualSymbol(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r);
|
||||
const Poincare::Expression expressionForFunction(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r);
|
||||
Ion::Storage::Record::ErrorStatus setExpressionForActualSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Ion::Storage::Record previousRecord);
|
||||
Ion::Storage::Record::ErrorStatus setExpressionForFunction(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Ion::Storage::Record previousRecord);
|
||||
// Expression getters
|
||||
static const Poincare::Expression ExpressionForSymbolAndRecord(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r);
|
||||
static const Poincare::Expression ExpressionForActualSymbol(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r);
|
||||
static const Poincare::Expression ExpressionForFunction(const Poincare::SymbolAbstract & symbol, Ion::Storage::Record r) {
|
||||
assert(symbol.type() == Poincare::ExpressionNode::Type::Function);
|
||||
return ExpressionFromFunctionRecord(r);
|
||||
}
|
||||
// Expression setters
|
||||
static Ion::Storage::Record::ErrorStatus SetExpressionForActualSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Ion::Storage::Record previousRecord);
|
||||
static Ion::Storage::Record::ErrorStatus SetExpressionForFunction(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Ion::Storage::Record previousRecord);
|
||||
// Record getter
|
||||
static Ion::Storage::Record RecordWithBaseName(const char * name);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ void StorageCartesianFunction::DefaultName(char buffer[], size_t bufferSize) {
|
||||
int dotCharIndex = -1;
|
||||
while (currentNumber < bufferSize - constantNameSize) {
|
||||
dotCharIndex = 1 + Poincare::Integer(currentNumber).serialize(&buffer[1], bufferSize - constantNameSize + 1);
|
||||
if (GlobalContext::RecordWithName(buffer).isNull()) {
|
||||
if (GlobalContext::RecordBaseNameIsFree(buffer)) {
|
||||
// Name found
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ Layout VariableBoxController::expressionLayoutForRecord(Storage::Record record,
|
||||
}
|
||||
assert(index-m_firstMemoizedLayoutIndex < k_maxNumberOfDisplayedRows);
|
||||
if (m_layouts[index-m_firstMemoizedLayoutIndex].isUninitialized()) {
|
||||
m_layouts[index-m_firstMemoizedLayoutIndex] = Expression::ExpressionFromRecord(record).createLayout(Poincare::Preferences::sharedPreferences()->displayMode(), Constant::ShortNumberOfSignificantDigits);
|
||||
m_layouts[index-m_firstMemoizedLayoutIndex] = GlobalContext::ExpressionFromRecord(record).createLayout(Poincare::Preferences::sharedPreferences()->displayMode(), Constant::ShortNumberOfSignificantDigits);
|
||||
}
|
||||
return m_layouts[index-m_firstMemoizedLayoutIndex];
|
||||
}
|
||||
|
||||
@@ -92,7 +92,6 @@ public:
|
||||
Expression() : TreeHandle() {}
|
||||
Expression clone() const;
|
||||
static Expression parse(char const * string);
|
||||
static const Expression ExpressionFromRecord(const Ion::Storage::Record & record);
|
||||
static const Expression ExpressionFromAddress(const void * address, size_t size);
|
||||
|
||||
/* Circuit breaker */
|
||||
|
||||
@@ -43,14 +43,6 @@ Expression Expression::parse(char const * string) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
const Expression Expression::ExpressionFromRecord(const Ion::Storage::Record & record) {
|
||||
if (record.isNull() || record.value().size == 0) {
|
||||
return Expression();
|
||||
}
|
||||
Ion::Storage::Record::Data d = record.value();
|
||||
return ExpressionFromAddress(d.buffer, d.size);
|
||||
}
|
||||
|
||||
const Expression Expression::ExpressionFromAddress(const void * address, size_t size) {
|
||||
if (address == nullptr || size == 0) {
|
||||
return Expression();
|
||||
|
||||
Reference in New Issue
Block a user