From 413ff834b971ba616b8a9a1ec40c856c9f839b70 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Wed, 8 Aug 2018 18:11:27 +0200 Subject: [PATCH] [poincare] Get Opposite class to build --- .../allocation_failure_expression_node.h | 7 +- ...ode.h => allocation_failure_layout_node.h} | 29 ++++---- .../poincare/allocation_failure_node.h | 23 +++++++ poincare/include/poincare/char_layout_node.h | 1 + poincare/include/poincare/division.h | 8 ++- poincare/include/poincare/empty_layout_node.h | 2 +- poincare/include/poincare/opposite.h | 8 +-- poincare/include/poincare/power.h | 39 +++++++---- poincare/src/char_layout_node.cpp | 5 ++ poincare/src/expression_parser.y | 66 ++++++++++++------- poincare/src/power.cpp | 20 ++---- 11 files changed, 136 insertions(+), 72 deletions(-) rename poincare/include/poincare/{allocation_failed_layout_node.h => allocation_failure_layout_node.h} (72%) create mode 100644 poincare/include/poincare/allocation_failure_node.h diff --git a/poincare/include/poincare/allocation_failure_expression_node.h b/poincare/include/poincare/allocation_failure_expression_node.h index bce09a521..beeeeee4f 100644 --- a/poincare/include/poincare/allocation_failure_expression_node.h +++ b/poincare/include/poincare/allocation_failure_expression_node.h @@ -4,7 +4,8 @@ #include #include #include -#include +#include +#include #include namespace Poincare { @@ -14,6 +15,7 @@ class AllocationFailureExpressionNode : public T { public: AllocationFailureExpressionNode() : T() {} AllocationFailureExpressionNode(T node) : T(node) {} + // ExpressionNode ExpressionNode::Sign sign() const override { return ExpressionNode::Sign::Unknown; } ExpressionNode::Type type() const override { return ExpressionNode::Type::AllocationFailure; } @@ -25,7 +27,8 @@ public: } return PrintFloat::convertFloatToText(NAN, buffer, bufferSize, numberOfSignificantDigits, floatDisplayMode); } - LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { return AllocationFailedLayoutRef(); } + LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { return LayoutRef(CharLayoutNode::FailedAllocationStaticNode()); } + // FIXME: Use EmptyLayoutNode here above, once EmptyLayout has been cleaned up // TreeNode size_t size() const override { return sizeof(AllocationFailureExpressionNode); } diff --git a/poincare/include/poincare/allocation_failed_layout_node.h b/poincare/include/poincare/allocation_failure_layout_node.h similarity index 72% rename from poincare/include/poincare/allocation_failed_layout_node.h rename to poincare/include/poincare/allocation_failure_layout_node.h index 82bf4997a..e209477db 100644 --- a/poincare/include/poincare/allocation_failed_layout_node.h +++ b/poincare/include/poincare/allocation_failure_layout_node.h @@ -1,30 +1,30 @@ -#ifndef POINCARE_ALLOCATION_FAILED_LAYOUT_NODE_H -#define POINCARE_ALLOCATION_FAILED_LAYOUT_NODE_H +#ifndef POINCARE_ALLOCATION_FAILURE_LAYOUT_NODE_H +#define POINCARE_ALLOCATION_FAILURE_LAYOUT_NODE_H +#include "allocation_failure_node.h" #include "layout_node.h" #include "layout_reference.h" #include "layout_cursor.h" namespace Poincare { -class AllocationFailedLayoutNode : public LayoutNode { +template +class AllocationFailureLayoutNode : public AllocationFailureNode { public: - static AllocationFailedLayoutNode * FailedAllocationStaticNode() { - return static_cast(LayoutNode::FailedAllocationStaticNode()); - } - // TreeNode - bool isAllocationFailure() const override { return true; } - size_t size() const override { return sizeof(AllocationFailedLayoutNode); } + size_t size() const override { return sizeof(AllocationFailureLayoutNode); } #if TREE_LOG - const char * description() const override { return "AllocationFailedLayout"; } + const char * description() const override { return "AllocationFailureLayout"; } #endif - int numberOfChildren() const override { return 0; } + // LayoutNode int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { assert(false); + return 0; + /* int descriptionLength = strlen(description()) + 1; return strlcpy(buffer, description(), bufferSize < descriptionLength ? bufferSize : descriptionLength); + */ } void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) override {} void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) override {} @@ -48,10 +48,13 @@ private: void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override {} }; -class AllocationFailedLayoutRef : public LayoutReference { +/* +template +class AllocationFailureLayoutRef : public LayoutReference { public: - AllocationFailedLayoutRef() : LayoutReference(TreePool::sharedPool()->createTreeNode()) {} + AllocationFailedLayoutRef() : LayoutReference(TreePool::sharedPool()->createTreeNode>()) {} }; +*/ } diff --git a/poincare/include/poincare/allocation_failure_node.h b/poincare/include/poincare/allocation_failure_node.h new file mode 100644 index 000000000..9fc6b16c1 --- /dev/null +++ b/poincare/include/poincare/allocation_failure_node.h @@ -0,0 +1,23 @@ +#ifndef POINCARE_ALLOCATION_FAILURE_NODE_H +#define POINCARE_ALLOCATION_FAILURE_NODE_H + +namespace Poincare { + +template +class AllocationFailureNode : public T { +public: + AllocationFailureNode() : T() {} + AllocationFailureNode(T node) : T(node) {} + + // TreeNode + size_t size() const override { return sizeof(AllocationFailureNode); } +#if TREE_LOG + const char * description() const override { return "AllocationFailure"; } +#endif + int numberOfChildren() const override { return 0; } + bool isAllocationFailure() const override { return true; } +}; + +} + +#endif diff --git a/poincare/include/poincare/char_layout_node.h b/poincare/include/poincare/char_layout_node.h index 5e99b6a36..cfbf5878f 100644 --- a/poincare/include/poincare/char_layout_node.h +++ b/poincare/include/poincare/char_layout_node.h @@ -27,6 +27,7 @@ public: bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const override; // TreeNode + static CharLayoutNode * FailedAllocationStaticNode(); size_t size() const override { return sizeof(CharLayoutNode); } int numberOfChildren() const override { return 0; } #if TREE_LOG diff --git a/poincare/include/poincare/division.h b/poincare/include/poincare/division.h index 61aec55e7..1a05925ae 100644 --- a/poincare/include/poincare/division.h +++ b/poincare/include/poincare/division.h @@ -11,9 +11,8 @@ class Division; class DivisionNode : public ExpressionNode { public: - static DivisionNode * FailedAllocationStaticNode(); - // TreeNode + static DivisionNode * FailedAllocationStaticNode(); size_t size() const override { return sizeof(DivisionNode); } #if TREE_LOG const char * description() const override { return "Division"; } @@ -59,7 +58,10 @@ private: class Division : public Expression { public: - Division(Expression numerator, Expression denominator); + Division(Expression numerator, Expression denominator) { + addChild(numberator); + addChild(denominator); + } Division(const DivisionNode * n) : Expression(n) {} Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit); }; diff --git a/poincare/include/poincare/empty_layout_node.h b/poincare/include/poincare/empty_layout_node.h index 80ca5063b..7c7917d69 100644 --- a/poincare/include/poincare/empty_layout_node.h +++ b/poincare/include/poincare/empty_layout_node.h @@ -73,7 +73,7 @@ private: class EmptyLayoutRef : public LayoutReference { public: EmptyLayoutRef(EmptyLayoutNode::Color color = EmptyLayoutNode::Color::Yellow, bool visible = true, KDText::FontSize fontSize = KDText::FontSize::Large, bool margins = true) : - LayoutReference(TreePool::sharedPool()->createTreeNode(), true) + LayoutReference(TreePool::sharedPool()->createTreeNode()) { if (!(node()->isAllocationFailure())) { typedNode()->setColor(color); diff --git a/poincare/include/poincare/opposite.h b/poincare/include/poincare/opposite.h index 1219585b9..9b4a1375a 100644 --- a/poincare/include/poincare/opposite.h +++ b/poincare/include/poincare/opposite.h @@ -10,11 +10,10 @@ class Opposite; class OppositeNode : public ExpressionNode { public: - static OppositeNode * FailedAllocationStaticNode(); - template static Complex compute(const std::complex c, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) { return Complex(-c); } // TreeNode + static OppositeNode * FailedAllocationStaticNode(); size_t size() const override { return sizeof(OppositeNode); } #if TREE_LOG const char * description() const override { return "Opposite"; } @@ -45,13 +44,10 @@ public: class Opposite : public Expression { public: - Opposite(Expression operand); Opposite(const OppositeNode * n) : Expression(n) {} - - /* : Expression(TreePool::sharedPool()->createTreeNode()) { + Opposite(Expression operand) : Expression(TreePool::sharedPool()->createTreeNode()) { replaceChildAtIndexInPlace(0, operand); } - */ Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit); }; diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index b551f1b4f..96f6e247a 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -9,18 +9,23 @@ namespace Poincare { -class Power : public StaticHierarchy<2> { - using StaticHierarchy<2>::StaticHierarchy; - friend class Multiplication; - friend class NthRoot; - friend class SquareRoot; - friend class Addition; - friend class Division; - friend class Round; - friend class Symbol; +class Power; + +class PowerNode : public ExpressionNode { public: - Type type() const override; - Sign sign() const override; + // TreeNode + static PowerNode * FailedAllocationStaticNode(); + size_t size() const override { return sizeof(PowerNode); } +#if TREE_LOG + const char * description() const override { return "Division"; } +#endif + int numberOfChildren() const override { return 2; } + + // Properties + virtual Type type() const override { return Type::Power; } + virtual Sign sign() const override; + virtual Expression setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override; + int polynomialDegree(char symbolName) const override; int privateGetPolynomialCoefficients(char symbolName, Expression * coefficients[]) const override; template static std::complex compute(const std::complex c, const std::complex d); @@ -28,7 +33,6 @@ private: constexpr static int k_maxNumberOfTermsInExpandedMultinome = 25; constexpr static int k_maxExactPowerMatrix = 100; /* Property */ - Expression setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) override; /* Layout */ LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; bool needsParenthesesWithParent(SerializableNode * parentNode) const override; @@ -67,6 +71,17 @@ private: } }; +class Power : public Expression { +public: + Power(Expression base, Expression exponent); + Power(const PowerNode * n) : Expression(n) {} + + Expression setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit); + Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit); + +}; + + } #endif diff --git a/poincare/src/char_layout_node.cpp b/poincare/src/char_layout_node.cpp index b03e63131..17d98b7dc 100644 --- a/poincare/src/char_layout_node.cpp +++ b/poincare/src/char_layout_node.cpp @@ -4,6 +4,11 @@ namespace Poincare { +CharLayoutNode * CharLayoutNode::FailedAllocationStaticNode() { + static AllocationFailureLayoutNode failure; + return &failure; +} + // LayoutNode void CharLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) { if (cursor->position() == LayoutCursor::Position::Right) { diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y index 9a608d29a..55a545a83 100644 --- a/poincare/src/expression_parser.y +++ b/poincare/src/expression_parser.y @@ -3,7 +3,7 @@ /* When calling the parser, we will provide yyparse with an extra parameter : a * backpointer to the resulting expression. */ -%parse-param { Poincare::Expression ** expressionOutput } +%parse-param { Poincare::Expression * expressionOutput } %{ #include @@ -14,7 +14,7 @@ /* Declare our error-handling function. Since we're making a re-entrant parser, * it takes a context parameter as its first input. */ -void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char const *msg); +void poincare_expression_yyerror(Poincare::Expression * expressionOutput, char const *msg); /* Bison expects to use __builtin_memcpy. We don't want to provide this, but * instead we do provide regular memcpy. Let's instruct Bison to use it. */ @@ -28,11 +28,14 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char * when parsing (a/b) we want to create a new Division), or a string (this will * be useful to retrieve the value of Integers for example). */ %union { - Poincare::Expression * expression; - Poincare::Symbol * symbol; + Poincare::Expression expression; + Poincare::Symbol symbol; +/* Poincare::ListData * listData; Poincare::MatrixData * matrixData; Poincare::StaticHierarchy<0> * function; +*/ + /* Caution: all the const char * are NOT guaranteed to be NULL-terminated! * While Flex guarantees that yytext is NULL-terminated when building tokens, * it does so by temporarily swapping in a NULL terminated in the input text. @@ -130,16 +133,22 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char /* MATRICES_ARE_DEFINED */ %type mtxData; +/* FIXME: no destructors, Expressions are GCed */ /* During error recovery, some symbols need to be discarded. We need to tell * Bison how to get rid of them. Depending on the type of the symbol, it may * have some heap-allocated data that need to be discarded. */ +/* + %destructor { delete $$; } FUNCTION %destructor { delete $$; } UNDEFINED final_exp exp pow factor bang term number EMPTY %destructor { delete $$; } lstData +*/ /* MATRICES_ARE_DEFINED */ +/* %destructor { delete $$; } mtxData %destructor { delete $$; } symb +*/ %% @@ -149,14 +158,18 @@ Root: } ; +/* lstData: exp { $$ = new Poincare::ListData($1); } | lstData COMMA exp { $$ = $1; $$->pushExpression($3); } ; +*/ /* MATRICES_ARE_DEFINED */ +/* mtxData: LEFT_BRACKET lstData RIGHT_BRACKET { $$ = new Poincare::MatrixData($2, false); $2->detachOperands(); delete $2; } | mtxData LEFT_BRACKET lstData RIGHT_BRACKET { if ($3->numberOfChildren() != $1->numberOfColumns()) { delete $1; delete $3; YYERROR; } ; $$ = $1; $$->pushListData($3, false); $3->detachOperands(); delete $3; } ; +*/ /* When approximating expressions to double, results are bounded by 1E308 (and * 1E-308 for small numbers). We thus accept decimals whose exponents are in @@ -167,24 +180,28 @@ mtxData: LEFT_BRACKET lstData RIGHT_BRACKET { $$ = new Poincare::MatrixData($2, * of the exponent digits is above 4 (0.00...-256 times-...01E1256=1E1000 is * accepted and 1000-...256times...-0E10000 = 1E10256, 10256 does not overflow * an int32_t). */ -number : DIGITS { $$ = new Poincare::Rational(Poincare::Integer($1.address, false)); } - | DOT DIGITS { $$ = new Poincare::Decimal(Poincare::Decimal::mantissa(nullptr, 0, $2.address, $2.length, false), Poincare::Decimal::exponent(nullptr, 0, $2.address, $2.length, nullptr, 0, false)); } - | DIGITS DOT DIGITS { $$ = new Poincare::Decimal(Poincare::Decimal::mantissa($1.address, $1.length, $3.address, $3.length, false), Poincare::Decimal::exponent($1.address, $1.length, $3.address, $3.length, nullptr, 0, false)); } - | DOT DIGITS EE DIGITS { if ($4.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent(nullptr, 0, $2.address, $2.length, $4.address, $4.length, false); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = new Poincare::Decimal(Poincare::Decimal::mantissa(nullptr, 0, $2.address, $2.length, false), exponent); } - | DIGITS DOT DIGITS EE DIGITS { if ($5.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent($1.address, $1.length, $3.address, $3.length, $5.address, $5.length, false); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = new Poincare::Decimal(Poincare::Decimal::mantissa($1.address, $1.length, $3.address, $3.length, false), exponent); } - | DIGITS EE DIGITS { if ($3.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent($1.address, $1.length, nullptr, 0, $3.address, $3.length, false); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = new Poincare::Decimal(Poincare::Decimal::mantissa($1.address, $1.length, nullptr, 0, false), exponent); } - | DOT DIGITS EE MINUS DIGITS { if ($5.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent(nullptr, 0, $2.address, $2.length, $5.address, $5.length, true); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = new Poincare::Decimal(Poincare::Decimal::mantissa(nullptr, 0, $2.address, $2.length, false), exponent); } +number : DIGITS { $$ = Poincare::Rational(Poincare::Integer($1.address, false)); } + +/* + | DOT DIGITS { $$ = Poincare::Decimal(Poincare::Decimal::mantissa(nullptr, 0, $2.address, $2.length, false), Poincare::Decimal::exponent(nullptr, 0, $2.address, $2.length, nullptr, 0, false)); } + | DIGITS DOT DIGITS { $$ = Poincare::Decimal(Poincare::Decimal::mantissa($1.address, $1.length, $3.address, $3.length, false), Poincare::Decimal::exponent($1.address, $1.length, $3.address, $3.length, nullptr, 0, false)); } + | DOT DIGITS EE DIGITS { if ($4.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent(nullptr, 0, $2.address, $2.length, $4.address, $4.length, false); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = Poincare::Decimal(Poincare::Decimal::mantissa(nullptr, 0, $2.address, $2.length, false), exponent); } + | DIGITS DOT DIGITS EE DIGITS { if ($5.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent($1.address, $1.length, $3.address, $3.length, $5.address, $5.length, false); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = Poincare::Decimal(Poincare::Decimal::mantissa($1.address, $1.length, $3.address, $3.length, false), exponent); } + | DIGITS EE DIGITS { if ($3.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent($1.address, $1.length, nullptr, 0, $3.address, $3.length, false); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = Poincare::Decimal(Poincare::Decimal::mantissa($1.address, $1.length, nullptr, 0, false), exponent); } + | DOT DIGITS EE MINUS DIGITS { if ($5.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent(nullptr, 0, $2.address, $2.length, $5.address, $5.length, true); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = Poincare::Decimal(Poincare::Decimal::mantissa(nullptr, 0, $2.address, $2.length, false), exponent); } | DIGITS DOT DIGITS EE MINUS DIGITS { if ($6.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent($1.address, $1.length, $3.address, $3.length, $6.address, $6.length, true); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = new Poincare::Decimal(Poincare::Decimal::mantissa($1.address, $1.length, $3.address, $3.length, false), exponent); } | DIGITS EE MINUS DIGITS { if ($4.length > 4) { YYERROR; }; int exponent = Poincare::Decimal::exponent($1.address, $1.length, nullptr, 0, $4.address, $4.length, true); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = new Poincare::Decimal(Poincare::Decimal::mantissa($1.address, $1.length, nullptr, 0, false), exponent); } ; +*/ -symb : SYMBOL { $$ = new Poincare::Symbol($1); } +symb : SYMBOL { $$ = Poincare::Symbol($1); } ; term : EMPTY { $$ = $1; } | symb { $$ = $1; } | UNDEFINED { $$ = $1; } | number { $$ = $1; } +/* | FUNCTION UNDERSCORE LEFT_BRACE lstData RIGHT_BRACE LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { $$ = $1; int totalNumberOfArguments = $4->numberOfChildren()+$7->numberOfChildren(); if (!$1->hasValidNumberOfOperands(totalNumberOfArguments)) { delete $1; delete $4; delete $7; YYERROR; }; Poincare::ListData * arguments = new Poincare::ListData(); @@ -194,36 +211,41 @@ $1->setArgument(arguments, totalNumberOfArguments, false); $4->detachOperands(); delete $4; $7->detachOperands(); delete $7; arguments->detachOperands(); delete arguments;} | FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { $$ = $1; if (!$1->hasValidNumberOfOperands($3->numberOfChildren())) { delete $1; delete $3; YYERROR; } ; $1->setArgument($3, $3->numberOfChildren(), false); $3->detachOperands(); delete $3; } | FUNCTION LEFT_PARENTHESIS RIGHT_PARENTHESIS { $$ = $1; if (!$1->hasValidNumberOfOperands(0)) { delete $1; YYERROR; } ; } - | LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { Poincare::Expression * terms[1] = {$2}; $$ = new Poincare::Parenthesis(terms, false); } +*/ + | LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = Poincare::Parenthesis($2); } /* MATRICES_ARE_DEFINED */ +/* | LEFT_BRACKET mtxData RIGHT_BRACKET { $$ = new Poincare::Matrix($2); delete $2; } +*/ ; bang : term { $$ = $1; } - | term BANG { $$ = new Poincare::Factorial($1, false); } + | term BANG { $$ = Poincare::Factorial($1); } ; factor : bang { $$ = $1; } - | bang pow %prec IMPLICIT_MULTIPLY { Poincare::Expression * terms[2] = {$1,$2}; $$ = new Poincare::Multiplication(terms, 2, false); } + | bang pow %prec IMPLICIT_MULTIPLY { $$ = Poincare::Multiplication($1, $2); } ; pow : factor { $$ = $1; } - | bang POW pow { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Power(terms, false); } - | bang POW MINUS pow { Poincare::Expression * terms1[1] = {$4}; Poincare::Expression * terms[2] = {$1,new Poincare::Opposite(terms1, false)}; $$ = new Poincare::Power(terms, false); } + | bang POW pow { $$ = Poincare::Power($1,$3); } + | bang POW MINUS pow { $$ = Poincare::Power($1,Poincare::Opposite($4)); } ; exp : pow { $$ = $1; } - | exp DIVIDE exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Division(terms, false); } - | exp MULTIPLY exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Multiplication(terms, 2, false); } - | exp MINUS exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Subtraction(terms, false); } - | MINUS exp %prec UNARY_MINUS { Poincare::Expression * terms[1] = {$2}; $$ = new Poincare::Opposite(terms, false); } - | exp PLUS exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Addition(terms, 2, false); } + | exp DIVIDE exp { $$ = Poincare::Division($1,$3); } + | exp MULTIPLY exp { $$ = Poincare::Multiplication($1,$3); } + | exp MINUS exp { $$ = Poincare::Subtraction($1,$3); } + | MINUS exp %prec UNARY_MINUS { $$ = Poincare::Opposite($2); } + | exp PLUS exp { $$ = Poincare::Addition($1;$3); } ; final_exp : exp { $$ = $1; } +/* | exp STO symb { if ($3->name() == Poincare::Symbol::SpecialSymbols::Ans) { delete $1; delete $3; YYERROR; } ; Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Store(terms, false); } | exp EQUAL exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Equal(terms, false); } ; +*/ %% void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, const char * msg) { diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index a4212a676..aa23a29c2 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -29,17 +29,8 @@ extern "C" { #include } - namespace Poincare { -Expression::Type Power::type() const { - return Type::Power; -} - -Expression * Power::clone() const { - return new Power(m_operands, true); -} - Expression::Sign Power::sign() const { if (shouldStopProcessing()) { return Sign::Unknown; @@ -110,11 +101,14 @@ int Power::getPolynomialCoefficients(char symbolName, Expression coefficients[]) return -1; } -Expression * Power::setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) { +Expression PowerNode::setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) { + return Power(this).setSign(s, context, angleUnit); +} + +Expression Power::setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) { assert(s == Sign::Positive); - assert(operand(0)->sign() == Sign::Negative); - editableOperand(0)->setSign(Sign::Positive, context, angleUnit); - return this; + assert(childAtIndex(0).sign() == Sign::Negative); + return Power(childAtIndex(0).setSign(Sign::Positive, context, angleUnit), childAtIndex(1)); } template