diff --git a/poincare/include/poincare/constant.h b/poincare/include/poincare/constant.h index c0754357c..9f09fbbe1 100644 --- a/poincare/include/poincare/constant.h +++ b/poincare/include/poincare/constant.h @@ -55,7 +55,7 @@ private: class Constant final : public SymbolAbstract { public: Constant(const ConstantNode * node) : SymbolAbstract(node) {} - static Constant Builder(char name); + static Constant Builder(char name) { return SymbolAbstract::Builder(&name, 1); } // Constant properties bool isPi() const { return node()->isPi(); } diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index 776498cac..fbe668d84 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -64,8 +64,8 @@ public: UnknownX = 1, }; Symbol(const SymbolNode * node) : SymbolAbstract(node) {} - static Symbol Builder(const char * name, int length); - static Symbol Builder(char name); + static Symbol Builder(const char * name, int length) { return SymbolAbstract::Builder(name, length); } + static Symbol Builder(char name) { return Symbol::Builder(&name, 1); } static Symbol Ans() { return Symbol::Builder(k_ans, k_ansLength); } static Expression UntypedBuilder(const char * name, size_t length, Context * context) { // create an expression only if it is not in the context or defined as a symbol diff --git a/poincare/include/poincare/symbol_abstract.h b/poincare/include/poincare/symbol_abstract.h index f92732549..2c2e10a13 100644 --- a/poincare/include/poincare/symbol_abstract.h +++ b/poincare/include/poincare/symbol_abstract.h @@ -75,6 +75,9 @@ public: protected: SymbolAbstract(const SymbolAbstractNode * node) : Expression(node) {} + template + static T Builder(const char * name, int length); + SymbolAbstractNode * node() const { return static_cast(Expression::node()); } private: static Expression Expand(const SymbolAbstract & symbol, Context & context, bool clone); diff --git a/poincare/src/constant.cpp b/poincare/src/constant.cpp index d8b4ec7d9..6c4039c03 100644 --- a/poincare/src/constant.cpp +++ b/poincare/src/constant.cpp @@ -76,14 +76,6 @@ Expression ConstantNode::shallowReduce(Context & context, Preferences::ComplexFo return Constant(this).shallowReduce(context, complexFormat, angleUnit, target); } -Constant Constant::Builder(char name) { - size_t size = sizeof(ConstantNode) + 1 + 1; - void * bufferNode = TreePool::sharedPool()->alloc(size); - ConstantNode * node = new (bufferNode) ConstantNode(&name, 1); - TreeHandle h = TreeHandle::BuildWithBasicChildren(node); - return static_cast(h); -} - Expression Constant::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { Expression result; if (complexFormat == Preferences::ComplexFormat::Real && isIComplex()) { diff --git a/poincare/src/function.cpp b/poincare/src/function.cpp index d9ce48d2a..ec7910c85 100644 --- a/poincare/src/function.cpp +++ b/poincare/src/function.cpp @@ -92,14 +92,12 @@ Evaluation FunctionNode::templatedApproximate(Context& context, Preferences:: return e.node()->approximate(T(), context, complexFormat, angleUnit); } -Function Function::Builder(const char * name, size_t length, Expression child) { - size_t size = sizeof(FunctionNode) + length + 1; - void * bufferNode = TreePool::sharedPool()->alloc(size); - FunctionNode * node = new (bufferNode) FunctionNode(name, length); - Expression * childPointer = child.isUninitialized() ? nullptr : &child; - int numberOfChild = child.isUninitialized() ? 0 : 1; - TreeHandle h = TreeHandle::BuildWithBasicChildren(node, childPointer, numberOfChild); - return static_cast(h); +Function Function::Builder(const char * name, size_t length, Expression child) { + Function f = SymbolAbstract::Builder(name, length); + if (!child.isUninitialized()) { + f.replaceChildAtIndexInPlace(0, child); + } + return f; } Expression Function::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { diff --git a/poincare/src/symbol.cpp b/poincare/src/symbol.cpp index 3fcf7ff80..f4225c05a 100644 --- a/poincare/src/symbol.cpp +++ b/poincare/src/symbol.cpp @@ -139,16 +139,6 @@ Evaluation SymbolNode::templatedApproximate(Context& context, Preferences::Co return e.node()->approximate(T(), context, complexFormat, angleUnit); } -Symbol Symbol::Builder(const char * name, int length) { - size_t size = sizeof(SymbolNode) + length + 1; - void * bufferNode = TreePool::sharedPool()->alloc(size); - SymbolNode * node = new (bufferNode) SymbolNode(name, length); - TreeHandle h = TreeHandle::BuildWithBasicChildren(node); - return static_cast(h); -} - -Symbol Symbol::Builder(char name) { return Symbol::Builder(&name, 1); } - bool Symbol::isSeriesSymbol(const char * c) { // [NV][1-3] if (c[2] == 0 && (c[0] == 'N' || c[0] == 'V') && c[1] >= '1' && c[1] <= '3') { diff --git a/poincare/src/symbol_abstract.cpp b/poincare/src/symbol_abstract.cpp index 8cd30ea73..59bdf55f6 100644 --- a/poincare/src/symbol_abstract.cpp +++ b/poincare/src/symbol_abstract.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include @@ -34,6 +36,15 @@ int SymbolAbstractNode::simplificationOrderSameType(const ExpressionNode * e, bo return strcmp(name(), static_cast(e)->name()); } +template +T SymbolAbstract::Builder(const char * name, int length) { + size_t size = sizeof(U) + length + 1; + void * bufferNode = TreePool::sharedPool()->alloc(size); + U * node = new (bufferNode) U(name, length); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + size_t SymbolAbstract::TruncateExtension(char * dst, const char * src, size_t len) { const char * cur = src; const char * end = src+len-1; @@ -71,4 +82,8 @@ bool SymbolAbstract::isReal(const SymbolAbstract & symbol, Context & context) { return e.isReal(context); } +template Constant SymbolAbstract::Builder(char const*, int); +template Function SymbolAbstract::Builder(char const*, int); +template Symbol SymbolAbstract::Builder(char const*, int); + }