[poincare] Factorize Symbol and Function code in SymbolAbstract

This commit is contained in:
Émilie Feral
2018-10-29 17:49:14 +01:00
parent 0cc7052d45
commit 138e955cfd
6 changed files with 31 additions and 50 deletions

View File

@@ -12,8 +12,6 @@ public:
const char * name() const override { return m_name; }
// TreeNode
void initToMatchSize(size_t goalSize) override;
size_t size() const override;
int numberOfChildren() const override { return 1; } //TODO allow any number of children? Needs templating
#if POINCARE_TREE_LOG
virtual void logNodeName(std::ostream & stream) const override {
@@ -33,6 +31,7 @@ public:
private:
char m_name[0]; // MUST be the last member variable
size_t nodeSize() const override { return sizeof(FunctionNode); }
VariableContext xContext(Context & parentContext) const;
// Layout
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;

View File

@@ -10,8 +10,6 @@ public:
const char * name() const override { return m_name; }
// TreeNode
void initToMatchSize(size_t goalSize) override;
size_t size() const override;
int numberOfChildren() const override { return 0; }
#if POINCARE_TREE_LOG
virtual void logNodeName(std::ostream & stream) const override {
@@ -47,6 +45,7 @@ public:
private:
char m_name[0]; // MUST be the last member variable
size_t nodeSize() const override { return sizeof(SymbolNode); }
template<typename T> Evaluation<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
bool isSymbolChar(char c) const { const char symbolName[2] = {c, 0}; return strcmp(m_name, symbolName) == 0; }
};

View File

@@ -28,6 +28,8 @@ class SymbolAbstractNode : public ExpressionNode {
public:
virtual const char * name() const = 0;
void setName(const char * newName, int length);
size_t size() const override;
void initToMatchSize(size_t goalSize) override;
// ExpressionNode
int simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const override;
@@ -43,10 +45,13 @@ public:
#endif
protected:
void initName(size_t nameSize);
virtual size_t nodeSize() const = 0;
};
class SymbolAbstract : public Expression {
friend class Function;
friend class Symbol;
friend class SymbolAbstractNode;
public:
const char * name() const { return node()->name(); }
static size_t TruncateExtension(char * dst, const char * src, size_t len);
@@ -54,6 +59,8 @@ public:
protected:
SymbolAbstract(const SymbolAbstractNode * node) : Expression(node) {}
SymbolAbstractNode * node() const { return static_cast<SymbolAbstractNode *>(Expression::node()); }
private:
static size_t AlignedNodeSize(size_t nameLength, size_t nodeSize);
};
}

View File

@@ -1,5 +1,4 @@
#include <poincare/function.h>
#include <poincare/helpers.h>
#include <poincare/layout_helper.h>
#include <poincare/parenthesis.h>
#include <poincare/rational.h>
@@ -10,25 +9,6 @@
namespace Poincare {
/* TreePool uses adresses and sizes that are multiples of 4 in order to make
* node moves faster.*/
static size_t NodeSize(size_t nameLength) {
return Helpers::AlignedSize(sizeof(FunctionNode)+nameLength+1, 4);
}
void FunctionNode::initToMatchSize(size_t goalSize) {
// TODO Factorize with symbol
assert(goalSize != sizeof(FunctionNode));
assert(goalSize > sizeof(FunctionNode));
size_t nameSize = goalSize - sizeof(FunctionNode);
SymbolAbstractNode::initName(nameSize);
assert(size() == goalSize);
}
size_t FunctionNode::size() const {
return NodeSize(strlen(m_name));
}
Expression FunctionNode::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) {
return Function(this).replaceSymbolWithExpression(symbol, expression);
}
@@ -108,7 +88,7 @@ Evaluation<T> FunctionNode::templatedApproximate(Context& context, Preferences::
}
Function::Function(const char * name) :
Function(TreePool::sharedPool()->createTreeNode<FunctionNode>(NodeSize(strlen(name))))
Function(TreePool::sharedPool()->createTreeNode<FunctionNode>(SymbolAbstract::AlignedNodeSize(strlen(name), sizeof(FunctionNode))))
{
static_cast<FunctionNode *>(Expression::node())->setName(name, strlen(name));
}

View File

@@ -1,7 +1,6 @@
#include <poincare/symbol.h>
#include <poincare/char_layout.h>
#include <poincare/context.h>
#include <poincare/helpers.h>
#include <poincare/horizontal_layout.h>
#include <poincare/layout_helper.h>
#include <poincare/parenthesis.h>
@@ -15,24 +14,6 @@ namespace Poincare {
constexpr char Symbol::k_ans[];
void SymbolNode::initToMatchSize(size_t goalSize) {
assert(goalSize != sizeof(SymbolNode));
assert(goalSize > sizeof(SymbolNode));
size_t nameSize = goalSize - sizeof(SymbolNode);
SymbolAbstractNode::initName(nameSize);
assert(size() == goalSize);
}
/* TreePool uses adresses and sizes that are multiples of 4 in order to make
* node moves faster.*/
static size_t NodeSize(size_t nameLength) {
return Helpers::AlignedSize(sizeof(SymbolNode)+nameLength+1, 4);
}
size_t SymbolNode::size() const {
return NodeSize(strlen(m_name));
}
ExpressionNode::Sign SymbolNode::sign() const {
/* TODO: Maybe, we will want to know that from a context given in parameter:
if (context.expressionForSymbol(this) != nullptr) {
@@ -165,7 +146,7 @@ Evaluation<T> SymbolNode::templatedApproximate(Context& context, Preferences::An
return e.approximateToEvaluation<T>(context, angleUnit);
}
Symbol::Symbol(const char * name, int length) : SymbolAbstract(TreePool::sharedPool()->createTreeNode<SymbolNode>(NodeSize(length))) {
Symbol::Symbol(const char * name, int length) : SymbolAbstract(TreePool::sharedPool()->createTreeNode<SymbolNode>(SymbolAbstract::AlignedNodeSize(length, sizeof(SymbolNode)))) {
node()->setName(name, length);
}

View File

@@ -1,4 +1,5 @@
#include <poincare/symbol_abstract.h>
#include <poincare/helpers.h>
#include <string.h>
namespace Poincare {
@@ -7,17 +8,31 @@ void SymbolAbstractNode::setName(const char * newName, int length) {
strlcpy(const_cast<char*>(name()), newName, length+1);
}
int SymbolAbstractNode::simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const {
assert(e->type() == Type::Symbol || e->type() == Type::Function);
return strcmp(name(), static_cast<const SymbolAbstractNode *>(e)->name());
size_t SymbolAbstractNode::size() const {
return SymbolAbstract::AlignedNodeSize(strlen(name()), nodeSize());
}
void SymbolAbstractNode::initName(size_t nameSize) {
void SymbolAbstractNode::initToMatchSize(size_t goalSize) {
assert(goalSize != nodeSize());
assert(goalSize > nodeSize());
size_t nameSize = goalSize - nodeSize();
char * modifiableName = const_cast<char *>(name());
for (size_t i = 0; i < nameSize - 1; i++) {
modifiableName[i] = 'a';
}
modifiableName[nameSize-1] = 0;
assert(size() == goalSize);
}
int SymbolAbstractNode::simplificationOrderSameType(const ExpressionNode * e, bool canBeInterrupted) const {
assert(e->type() == Type::Symbol || e->type() == Type::Function);
return strcmp(name(), static_cast<const SymbolAbstractNode *>(e)->name());
}
/* TreePool uses adresses and sizes that are multiples of 4 in order to make
* node moves faster.*/
size_t SymbolAbstract::AlignedNodeSize(size_t nameLength, size_t nodeSize) {
return Helpers::AlignedSize(nodeSize+nameLength+1, 4);
}
size_t SymbolAbstract::TruncateExtension(char * dst, const char * src, size_t len) {