diff --git a/ion/include/ion/charset.h b/ion/include/ion/charset.h index fb463525f..333c2c4c6 100644 --- a/ion/include/ion/charset.h +++ b/ion/include/ion/charset.h @@ -24,7 +24,8 @@ enum Charset : char { GreaterEqual = (char)146, MultiplicationSign = (char)147, MiddleDot = (char)148, - AlmostEqual = (char)149 + AlmostEqual = (char)149, + Empty = (char)150 // This char is used to be parsed into EmptyExpression. }; } diff --git a/poincare/Makefile b/poincare/Makefile index 9a1cc88da..a04201309 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -26,6 +26,7 @@ objs += $(addprefix poincare/src/,\ division_remainder.o\ division.o\ dynamic_hierarchy.o\ + empty_expression.o\ expression_layout_cursor.o\ expression_lexer.o\ expression_parser.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 9c2e8e8f1..88826ff40 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/empty_expression.h b/poincare/include/poincare/empty_expression.h new file mode 100644 index 000000000..e56ecc47a --- /dev/null +++ b/poincare/include/poincare/empty_expression.h @@ -0,0 +1,29 @@ +#ifndef POINCARE_EMPTY_EXPRESSION_H +#define POINCARE_EMPTY_EXPRESSION_H + +#include +#include + +namespace Poincare { + +/* An empty expression awaits completion by the user. */ + +class EmptyExpression : public StaticHierarchy<0> { +public: + Type type() const override { + return Type::EmptyExpression; + } + Expression * clone() const override; + int writeTextInBuffer(char * buffer, int bufferSize) const override;private: + /* Layout */ + ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override; + /* Evaluation */ + Expression * privateApproximate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate(context, angleUnit); } + Expression * privateApproximate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return templatedApproximate(context, angleUnit); } + template Complex * templatedApproximate(Context& context, AngleUnit angleUnit) const; +}; + +} + +#endif + diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index e29dc0309..4436bce4c 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -74,6 +74,7 @@ class Expression { friend class Trigonometry; friend class ApproximationEngine; friend class SimplificationEngine; + friend class EmptyExpression; public: enum class Type : uint8_t { @@ -136,6 +137,7 @@ public: MatrixTranspose, PredictionInterval, SimplificationRoot, + EmptyExpression }; enum class FloatDisplayMode { Decimal = 0, diff --git a/poincare/src/empty_expression.cpp b/poincare/src/empty_expression.cpp new file mode 100644 index 000000000..b9d7ae2fd --- /dev/null +++ b/poincare/src/empty_expression.cpp @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +extern "C" { +#include +} + +namespace Poincare { + +Expression * EmptyExpression::clone() const { + return new EmptyExpression(); +} + +int EmptyExpression::writeTextInBuffer(char * buffer, int bufferSize) const { + return LayoutEngine::writeOneCharInBuffer(buffer, bufferSize, Ion::Charset::Empty); +} + +ExpressionLayout * EmptyExpression::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const { + return new EmptyVisibleLayout(); +} + +template Complex * EmptyExpression::templatedApproximate(Context& context, AngleUnit angleUnit) const { + return new Complex(Complex::Float(NAN)); +} + +} diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index b2d04483e..577e71acc 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -156,6 +156,7 @@ inf { poincare_expression_yylval.expression = new Undefined(); return UNDEFINED; \, { return COMMA; } \. { return DOT; } \_ { return UNDERSCORE; } +\x96 { poincare_expression_yylval.expression = new EmptyExpression(); return EMPTY; } [ ]+ /* Ignore whitespaces */ . { return UNDEFINED_SYMBOL; } diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y index e48a16e0c..0f53054f1 100644 --- a/poincare/src/expression_parser.y +++ b/poincare/src/expression_parser.y @@ -51,6 +51,7 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char %token SYMBOL %token FUNCTION %token UNDEFINED +%token EMPTY /* Operator tokens */ %token PLUS @@ -114,6 +115,7 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char %nonassoc ICOMPLEX %nonassoc UNDEFINED %nonassoc SYMBOL +%nonassoc EMPTY /* The "exp" symbol uses the "expression" part of the union. */ %type final_exp; @@ -129,7 +131,7 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char * have some heap-allocated data that need to be discarded. */ %destructor { delete $$; } FUNCTION -%destructor { delete $$; } UNDEFINED final_exp exp number +%destructor { delete $$; } UNDEFINED final_exp exp number EMPTY %destructor { delete $$; } lstData /* MATRICES_ARE_DEFINED */ %destructor { delete $$; } mtxData @@ -180,6 +182,7 @@ symb: * "exp MINUS exp". */ exp: UNDEFINED { $$ = $1; } + | EMPTY { $$ = $1; } | exp BANG { $$ = new Poincare::Factorial($1, false); } | number { $$ = $1; } | symb { $$ = $1; }