From 2273951fcc53312ec28dcb46c4f643cd69ee4ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 28 Aug 2018 16:14:21 +0200 Subject: [PATCH] [poincare] Fix Randint --- poincare/Makefile | 1 + poincare/include/poincare.h | 1 + poincare/include/poincare/randint.h | 42 ++++++++++++++++++++++------- poincare/src/expression_lexer.l | 3 +-- poincare/src/randint.cpp | 28 +++++++++---------- poincare/test/function.cpp | 5 ---- 6 files changed, 49 insertions(+), 31 deletions(-) diff --git a/poincare/Makefile b/poincare/Makefile index 53ac66cd6..ccc06e7ba 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -100,6 +100,7 @@ objs += $(addprefix poincare/src/,\ print_float.o\ preferences.o\ product.o\ + randint.o\ random.o\ rational.o\ real_part.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 38ec77a65..37f12fa5a 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -145,6 +145,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/randint.h b/poincare/include/poincare/randint.h index 9449dc0d9..bfe2edf3d 100644 --- a/poincare/include/poincare/randint.h +++ b/poincare/include/poincare/randint.h @@ -1,32 +1,54 @@ #ifndef POINCARE_RANDINT_H #define POINCARE_RANDINT_H -#include #include +#include +#include namespace Poincare { -class Randint : public StaticHierarchy<2> { - using StaticHierarchy<2>::StaticHierarchy; +class RandintNode : public ExpressionNode { public: - Type type() const override; -private: - /* Layout */ - LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { - return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, name()); + // Allocation Failure + static RandintNode * FailedAllocationStaticNode(); + RandintNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); } + + // TreeNode + size_t size() const override { return sizeof(RandintNode); } + int numberOfChildren() const override { return 2; } +#if POINCARE_TREE_LOG + virtual void logNodeName(std::ostream & stream) const override { + stream << "Randint"; } +#endif + + // Properties + Type type() const override { return Type::Randint; } +private: + // Layout + LayoutReference createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name()); } const char * name() const { return "randint"; } - /* Evaluation */ + // Evaluation Evaluation approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templateApproximate(context, angleUnit); } Evaluation approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templateApproximate(context, angleUnit); } - template Evaluation templateApproximate()Context& context, Preferences::AngleUnit angleUnit) const; + template Evaluation templateApproximate(Context& context, Preferences::AngleUnit angleUnit) const; +}; + +class Randint : public Expression { +friend class RandintNode; +public: + Randint() : Expression(TreePool::sharedPool()->createTreeNode()) {} + Randint(const RandintNode * n) : Expression(n) {} + + template static T random(); +private: }; } diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index ef18c7115..e5ab1686f 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -146,8 +146,7 @@ prediction { poincare_expression_yylval.expression = SimplePredictionInterval(); product { poincare_expression_yylval.expression = Product(); return FUNCTION; } quo { poincare_expression_yylval.expression = DivisionQuotient(); return FUNCTION; } random { poincare_expression_yylval.expression = Random(); return FUNCTION; } - /*randint { poincare_expression_yylval.expression = new Randint(); return FUNCTION; } -*/ +randint { poincare_expression_yylval.expression = Randint(); return FUNCTION; } re { poincare_expression_yylval.expression = RealPart(); return FUNCTION; } rem { poincare_expression_yylval.expression = DivisionRemainder(); return FUNCTION; } root { poincare_expression_yylval.expression = NthRoot(); return FUNCTION; } diff --git a/poincare/src/randint.cpp b/poincare/src/randint.cpp index 6e10442bd..cbe511096 100644 --- a/poincare/src/randint.cpp +++ b/poincare/src/randint.cpp @@ -1,5 +1,6 @@ #include #include +#include #include extern "C" { @@ -9,28 +10,27 @@ extern "C" { namespace Poincare { -ExpressionNode::Type Randint::type() const { - return Type::Randint; +RandintNode * RandintNode::FailedAllocationStaticNode() { + static AllocationFailureExpressionNode failure; + TreePool::sharedPool()->registerStaticNodeIfRequired(&failure); + return &failure; } -Expression * Randint::clone() const { - Randint * a = new Randint(m_operands, true); - return a; +LayoutReference RandintNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { + return LayoutHelper::Prefix(Randint(this), floatDisplayMode, numberOfSignificantDigits, name()); } -template Evaluation * Randint::templateApproximate(Context & context, Preferences::AngleUnit angleUnit) const { - Evaluation * aInput = childAtIndex(0)->approximate(T(), context, angleUnit); - Evaluation * bInput = childAtIndex(1)->approximate(T(), context, angleUnit); - T a = aInput->toScalar(); - T b = bInput->toScalar(); - delete aInput; - delete bInput; +template Evaluation RandintNode::templateApproximate(Context & context, Preferences::AngleUnit angleUnit) const { + Evaluation aInput = childAtIndex(0)->approximate(T(), context, angleUnit); + Evaluation bInput = childAtIndex(1)->approximate(T(), context, angleUnit); + T a = aInput.toScalar(); + T b = bInput.toScalar(); if (std::isnan(a) || std::isnan(b) || a != std::round(a) || b != std::round(b) || a > b) { - return new Complex(Complex::Undefined()); + return Complex::Undefined(); } T result = std::floor(Random::random()*(b+1.0-a)+a); - return new Complex(result); + return Complex(result); } } diff --git a/poincare/test/function.cpp b/poincare/test/function.cpp index eeef8eda5..3407c6014 100644 --- a/poincare/test/function.cpp +++ b/poincare/test/function.cpp @@ -50,9 +50,7 @@ QUIZ_CASE(poincare_parse_function) { assert_parsed_expression_type("quo(29, 10)", ExpressionNode::Type::DivisionQuotient); assert_parsed_expression_type("random()", ExpressionNode::Type::Random); -#if 0 assert_parsed_expression_type("randint(1, 2)", ExpressionNode::Type::Randint); -#endif assert_parsed_expression_type("re(2+I)", ExpressionNode::Type::RealPart); assert_parsed_expression_type("rem(29, 10)", ExpressionNode::Type::DivisionRemainder); @@ -230,12 +228,9 @@ QUIZ_CASE(poincare_function_evaluate) { assert_exp_is_bounded(exp, 0.0f, 1.0f); assert_exp_is_bounded(exp, 0.0, 1.0); -#if 0 exp = parse_expression("randint(4,45)"); assert_exp_is_bounded(exp, 4.0f, 45.0f, true); assert_exp_is_bounded(exp, 4.0, 45.0, true); - delete exp; -#endif } QUIZ_CASE(poincare_function_simplify) {