mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-29 03:29:58 +02:00
[poincare] Fix Function::size()
This commit is contained in:
@@ -9,7 +9,7 @@ namespace Poincare {
|
||||
class FunctionNode : public SymbolNode {
|
||||
public:
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(FunctionNode); }
|
||||
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 {
|
||||
|
||||
@@ -8,6 +8,15 @@ namespace Poincare {
|
||||
/* TODO: should we keep the size of SymbolNode as a member to speed up TreePool
|
||||
* scan? */
|
||||
|
||||
/* Symbol Node contains an empty member variable "m_name", which is used to get
|
||||
* the string that follows. This means that a SymbolNode's size is sizeo
|
||||
* (SymbolNode) + strlen(string).
|
||||
*
|
||||
* Seen by TreePool: |SymbolNode |
|
||||
* SymbolNode layout: |ExpressionNode|m_name| |
|
||||
* Memory content: |ExpressionNode|S |y|m|b|o|l|N|a|m|e|0|
|
||||
* */
|
||||
|
||||
class SymbolNode final : public ExpressionNode {
|
||||
friend class Store;
|
||||
public:
|
||||
@@ -54,11 +63,11 @@ public:
|
||||
bool isPi() const { return isSymbolChar(Ion::Charset::SmallPi); }
|
||||
bool isExponential() const { return isSymbolChar(Ion::Charset::Exponential); }
|
||||
bool isIComplex() const { return isSymbolChar(Ion::Charset::IComplex); }
|
||||
protected:
|
||||
char m_name[0]; // MUST be the last member variable
|
||||
private:
|
||||
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; }
|
||||
|
||||
char m_name[0];
|
||||
};
|
||||
|
||||
class Symbol final : public Expression {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <poincare/function.h>
|
||||
#include <poincare/helpers.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/parenthesis.h>
|
||||
#include <poincare/rational.h>
|
||||
@@ -8,6 +9,16 @@
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
size_t FunctionNode::size() const {
|
||||
return NodeSize(strlen(m_name));
|
||||
}
|
||||
|
||||
Expression FunctionNode::replaceSymbolWithExpression(const Symbol & symbol, const Expression & expression) {
|
||||
return Function(this).replaceSymbolWithExpression(symbol, expression);
|
||||
}
|
||||
@@ -87,7 +98,7 @@ Evaluation<double> FunctionNode::approximate(DoublePrecision p, Context& context
|
||||
}
|
||||
|
||||
Function::Function(const char * name) :
|
||||
Function(TreePool::sharedPool()->createTreeNode<FunctionNode>())
|
||||
Function(TreePool::sharedPool()->createTreeNode<FunctionNode>(NodeSize(strlen(name))))
|
||||
{
|
||||
static_cast<FunctionNode *>(Expression::node())->setName(name, strlen(name));
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include <poincare/symbol.h>
|
||||
#include <poincare/context.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/parenthesis.h>
|
||||
#include <poincare/layout_helper.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>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/vertical_offset_layout.h>
|
||||
#include <ion.h>
|
||||
#include <cmath>
|
||||
@@ -16,17 +17,12 @@ constexpr char Symbol::k_ans[];
|
||||
|
||||
/* TreePool uses adresses and sizes that are multiples of 4 in order to make
|
||||
* node moves faster.*/
|
||||
size_t SymbolSize(size_t nameLength) {
|
||||
size_t realSize = sizeof(SymbolNode)+nameLength+1;
|
||||
size_t alignment = 4;
|
||||
size_t modulo = realSize % alignment;
|
||||
size_t result = realSize + (modulo == 0 ? 0 : alignment - modulo);
|
||||
assert(result % 4 == 0);
|
||||
return result;
|
||||
static size_t NodeSize(size_t nameLength) {
|
||||
return Helpers::AlignedSize(sizeof(SymbolNode)+nameLength+1, 4);
|
||||
}
|
||||
|
||||
size_t SymbolNode::size() const {
|
||||
return SymbolSize(strlen(m_name));
|
||||
return NodeSize(strlen(m_name));
|
||||
}
|
||||
|
||||
ExpressionNode::Sign SymbolNode::sign() const {
|
||||
@@ -166,7 +162,7 @@ Evaluation<T> SymbolNode::templatedApproximate(Context& context, Preferences::An
|
||||
return e.approximateToEvaluation<T>(context, angleUnit);
|
||||
}
|
||||
|
||||
Symbol::Symbol(const char * name, int length) : Expression(TreePool::sharedPool()->createTreeNode<SymbolNode>(SymbolSize(length))) {
|
||||
Symbol::Symbol(const char * name, int length) : Expression(TreePool::sharedPool()->createTreeNode<SymbolNode>(NodeSize(length))) {
|
||||
node()->setName(name, length);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user