From cedecdefcf3ded931b9d8266b5e39216ef2c8cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 27 Aug 2018 16:10:52 +0200 Subject: [PATCH] [poincare] FracPart --- poincare/Makefile | 1 + poincare/include/poincare.h | 1 + poincare/include/poincare/frac_part.h | 49 ++++++++++++++++------- poincare/src/expression_lexer.l | 4 +- poincare/src/floor.cpp | 1 - poincare/src/frac_part.cpp | 56 +++++++++++++++------------ poincare/test/function.cpp | 6 +-- 7 files changed, 73 insertions(+), 45 deletions(-) diff --git a/poincare/Makefile b/poincare/Makefile index c7e678682..c38a9d4f2 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -64,6 +64,7 @@ objs += $(addprefix poincare/src/,\ factorial.o\ float.o\ floor.o\ + frac_part.o\ ghost_node.o\ global_context.o\ hyperbolic_arc_cosine.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 9670fb0ac..a33573763 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -124,6 +124,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/frac_part.h b/poincare/include/poincare/frac_part.h index 162bd892f..46f2f8656 100644 --- a/poincare/include/poincare/frac_part.h +++ b/poincare/include/poincare/frac_part.h @@ -1,29 +1,37 @@ #ifndef POINCARE_FRAC_PART_H #define POINCARE_FRAC_PART_H -#include -#include #include +#include namespace Poincare { -class FracPart : public StaticHierarchy<1> { - using StaticHierarchy<1>::StaticHierarchy; +class FracPartNode : public ExpressionNode { public: - Type type() const override; + // Allocation Failure + static FracPartNode * FailedAllocationStaticNode(); + FracPartNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); } + + // TreeNode + size_t size() const override { return sizeof(FracPartNode); } + int numberOfChildren() const override { return 1; } +#if POINCARE_TREE_LOG + virtual void logNodeName(std::ostream & stream) const override { + stream << "FracPart"; + } +#endif + + // Properties + Type type() const override { return Type::FracPart; } private: - /* Layout */ - LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { - return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, name()); - } - int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name()); - } + // Layout + LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; + int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; const char * name() const { return "frac"; } - /* Simplification */ + // Simplification Expression shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const override; - /* Evaluation */ - template static std::complex computeOnComplex(const std::complex c, Preferences::AngleUnit angleUnit); + // Evaluation + template static Complex computeOnComplex(const std::complex c, Preferences::AngleUnit angleUnit); Evaluation approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, angleUnit, computeOnComplex); } @@ -32,6 +40,17 @@ private: } }; +class FracPart : public Expression { +public: + FracPart() : Expression(TreePool::sharedPool()->createTreeNode()) {} + FracPart(const FracPartNode * n) : Expression(n) {} + FracPart(Expression operand) : FracPart() { + replaceChildAtIndexInPlace(0, operand); + } + + Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit) const; +}; + } #endif diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index ea515873e..539b89674 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -133,8 +133,8 @@ cosh { poincare_expression_yylval.expression = HyperbolicCosine(); return FUNCTI /*factor { poincare_expression_yylval.expression = new Factor(); return FUNCTION; } */ floor { poincare_expression_yylval.expression = Floor(); return FUNCTION; } - /*frac { poincare_expression_yylval.expression = new FracPart(); return FUNCTION; } -gcd { poincare_expression_yylval.expression = new GreatCommonDivisor(); return FUNCTION; } +frac { poincare_expression_yylval.expression = FracPart(); return FUNCTION; } + /*gcd { poincare_expression_yylval.expression = new GreatCommonDivisor(); return FUNCTION; } im { poincare_expression_yylval.expression = new ImaginaryPart(); return FUNCTION; } int { poincare_expression_yylval.expression = new Integral(); return FUNCTION; } inverse { poincare_expression_yylval.expression = new MatrixInverse(); return FUNCTION; } diff --git a/poincare/src/floor.cpp b/poincare/src/floor.cpp index 18533d915..032b9dec3 100644 --- a/poincare/src/floor.cpp +++ b/poincare/src/floor.cpp @@ -16,7 +16,6 @@ FloorNode * FloorNode::FailedAllocationStaticNode() { return &failure; } - LayoutRef FloorNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return FloorLayoutRef(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits)); } diff --git a/poincare/src/frac_part.cpp b/poincare/src/frac_part.cpp index 8531924a6..3d931f008 100644 --- a/poincare/src/frac_part.cpp +++ b/poincare/src/frac_part.cpp @@ -1,20 +1,36 @@ #include +#include +#include #include #include -extern "C" { -#include -} #include namespace Poincare { -ExpressionNode::Type FracPart::type() const { - return Type::FracPart; +FracPartNode * FracPartNode::FailedAllocationStaticNode() { + static AllocationFailureExpressionNode failure; + TreePool::sharedPool()->registerStaticNodeIfRequired(&failure); + return &failure; } -Expression * FracPart::clone() const { - FracPart * c = new FracPart(m_operands, true); - return c; +LayoutRef FracPartNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { + return LayoutHelper::Prefix(FracPart(this), floatDisplayMode, numberOfSignificantDigits, name()); +} + +int FracPartNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name()); +} + +Expression FracPartNode::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const { + return FracPart(this).shallowReduce(context, angleUnit); +} + +template +Complex FracPartNode::computeOnComplex(const std::complex c, Preferences::AngleUnit angleUnit) { + if (c.imag() != 0) { + return Complex::Undefined(); + } + return Complex(c.real()-std::floor(c.real())); } Expression FracPart::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const { @@ -22,26 +38,18 @@ Expression FracPart::shallowReduce(Context& context, Preferences::AngleUnit angl if (e.isUndefinedOrAllocationFailure()) { return e; } - Expression * op = childAtIndex(0); + Expression c = childAtIndex(0); #if MATRIX_EXACT_REDUCING - if (op->type() == Type::Matrix) { - return SimplificationHelper::Map(this, context, angleUnit); + if (c.type() == ExpressionNode::Type::Matrix) { + return SimplificationHelper::Map(*this, context, angleUnit); } #endif - if (op->type() != Type::Rational) { - return this; + if (c.type() != ExpressionNode::Type::Rational) { + return *this; } - Rational * r = static_cast(op); - IntegerDivision div = Integer::Division(r->numerator(), r->denominator()); - return replaceWith(new Rational(div.remainder, r->denominator()), true); -} - -template -std::complex FracPart::computeOnComplex(const std::complex c, Preferences::AngleUnit angleUnit) { - if (c.imag() != 0) { - return Complex::Undefined(); - } - return Complex(c.real()-std::floor(c.real())); + Rational r = static_cast(c); + IntegerDivision div = Integer::Division(r.signedIntegerNumerator(), r.integerDenominator()); + return Rational(div.remainder, r.integerDenominator()); } } diff --git a/poincare/test/function.cpp b/poincare/test/function.cpp index 9f898c8ca..1ff2f58fe 100644 --- a/poincare/test/function.cpp +++ b/poincare/test/function.cpp @@ -33,8 +33,8 @@ QUIZ_CASE(poincare_parse_function) { assert_parsed_expression_type("factor(23/42)", ExpressionNode::Type::Factor); #endif assert_parsed_expression_type("floor(2.3)", ExpressionNode::Type::Floor); -#if 0 assert_parsed_expression_type("frac(2.3)", ExpressionNode::Type::FracPart); +#if 0 assert_parsed_expression_type("gcd(2,3)", ExpressionNode::Type::GreatCommonDivisor); assert_parsed_expression_type("im(2+I)", ExpressionNode::Type::ImaginaryPart); assert_parsed_expression_type("int(x, 2, 3)", ExpressionNode::Type::Integral); @@ -103,9 +103,9 @@ QUIZ_CASE(poincare_function_evaluate) { assert_parsed_expression_evaluates_to("floor(2.3)", "2"); assert_parsed_expression_evaluates_to("floor(2.3)", "2"); -#if 0 assert_parsed_expression_evaluates_to("frac(2.3)", "0.3"); assert_parsed_expression_evaluates_to("frac(2.3)", "0.3"); +#if 0 assert_parsed_expression_evaluates_to("gcd(234,394)", "2"); assert_parsed_expression_evaluates_to("gcd(234,394)", "2"); @@ -272,8 +272,8 @@ QUIZ_CASE(poincare_function_simplify) { assert_parsed_expression_simplify_to("factor(10007^2)", "undef"); #endif assert_parsed_expression_simplify_to("floor(-1.3)", "-2"); -#if 0 assert_parsed_expression_simplify_to("frac(-1.3)", "7/10"); +#if 0 assert_parsed_expression_simplify_to("gcd(123,278)", "1"); assert_parsed_expression_simplify_to("gcd(11,121)", "11"); assert_parsed_expression_simplify_to("lcm(123,278)", "34194");