mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare] Add parsing tests
This commit is contained in:
committed by
Émilie Feral
parent
9c5ea70c24
commit
603e672cf3
@@ -186,7 +186,7 @@ QUIZ_CASE(poincare_function_evaluate) {
|
||||
assert_parsed_expression_evaluates_to<double>("root(3, 3+I)", "1.3820069623326-0.1524427794159*I");
|
||||
|
||||
assert_parsed_expression_evaluates_to<float>("root(5^((-I)3^9),I)", "3.504", Degree, Cartesian, 4);
|
||||
assert_parsed_expression_evaluates_to<double>("root(5^(-I)3^9,I)", "3.5039410843", Degree, Cartesian, 11);
|
||||
assert_parsed_expression_evaluates_to<double>("root(5^((-I)3^9),I)", "3.5039410843", Degree, Cartesian, 11);
|
||||
|
||||
assert_parsed_expression_evaluates_to<float>("R(3+I)", "1.755317+0.2848488*I");
|
||||
assert_parsed_expression_evaluates_to<double>("R(3+I)", "1.7553173018244+2.8484878459314E-1*I");
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include <quiz.h>
|
||||
#include <apps/shared/global_context.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <string.h>
|
||||
#include <ion.h>
|
||||
#include <stdlib.h>
|
||||
@@ -62,12 +60,10 @@ void translate_in_ASCII_chars(char * expression) {
|
||||
}
|
||||
|
||||
Expression parse_expression(const char * expression) {
|
||||
quiz_print(expression);
|
||||
char buffer[500];
|
||||
strlcpy(buffer, expression, sizeof(buffer));
|
||||
translate_in_special_chars(buffer);
|
||||
Expression result = Expression::parse(buffer);
|
||||
quiz_assert(!result.isUninitialized());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -78,7 +74,16 @@ void assert_parsed_expression_type(const char * expression, Poincare::Expression
|
||||
|
||||
void assert_parsed_expression_is(const char * expression, Poincare::Expression r) {
|
||||
Expression e = parse_expression(expression);
|
||||
quiz_assert(e.isIdenticalTo(r));
|
||||
bool identical = e.isIdenticalTo(r);
|
||||
#if POINCARE_TREE_LOG
|
||||
if (!identical) {
|
||||
std::cout << "Expecting" << std::endl;
|
||||
r.log();
|
||||
std::cout << "Got" << std::endl;
|
||||
e.log();
|
||||
}
|
||||
#endif
|
||||
quiz_assert(identical);
|
||||
}
|
||||
|
||||
void assert_parsed_expression_polynomial_degree(const char * expression, int degree, const char * symbolName) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/preferences.h>
|
||||
#include <poincare_nodes.h>
|
||||
#include <quiz.h>
|
||||
#include "poincare/src/parsing/parser.h"
|
||||
|
||||
// Expressions
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
#include <quiz.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/decimal.h>
|
||||
#include <poincare/addition.h>
|
||||
#include <poincare/init.h>
|
||||
#include <poincare/exception_checkpoint.h>
|
||||
#include <ion.h>
|
||||
@@ -13,7 +8,76 @@
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
QUIZ_CASE(poincare_parser) {
|
||||
void assert_tokenizes_as(const Token::Type * tokenTypes, const char * string) {
|
||||
char buffer[500];
|
||||
strlcpy(buffer, string, sizeof(buffer));
|
||||
translate_in_special_chars(buffer);
|
||||
Tokenizer tokenizer(buffer);
|
||||
while (true) {
|
||||
Token token = tokenizer.popToken();
|
||||
quiz_assert(token.type() == *tokenTypes);
|
||||
if (token.type() == Token::EndOfStream) {
|
||||
return;
|
||||
}
|
||||
tokenTypes++;
|
||||
}
|
||||
}
|
||||
|
||||
void assert_tokenizes_as_number(const char * string) {
|
||||
const Token::Type types[] = {Token::Number, Token::EndOfStream};
|
||||
assert_tokenizes_as(types, string);
|
||||
}
|
||||
|
||||
void assert_tokenizes_as_undefined_token(const char * string) {
|
||||
char buffer[500];
|
||||
strlcpy(buffer, string, sizeof(buffer));
|
||||
translate_in_special_chars(buffer);
|
||||
Tokenizer tokenizer(buffer);
|
||||
while (true) {
|
||||
Token token = tokenizer.popToken();
|
||||
if (token.type() == Token::Undefined) {
|
||||
return;
|
||||
}
|
||||
if (token.type() == Token::EndOfStream) {
|
||||
quiz_assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assert_raises_parsing_error(const char * text) {
|
||||
char buffer[500];
|
||||
strlcpy(buffer, text, sizeof(buffer));
|
||||
translate_in_special_chars(buffer);
|
||||
Parser p(buffer);
|
||||
Expression result = p.parse();
|
||||
quiz_assert(p.getStatus() != Parser::Status::Success);
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_tokenize_numbers) {
|
||||
assert_tokenizes_as_number("1");
|
||||
assert_tokenizes_as_number("12");
|
||||
assert_tokenizes_as_number("123");
|
||||
assert_tokenizes_as_number("1.3");
|
||||
assert_tokenizes_as_number(".3");
|
||||
assert_tokenizes_as_number("1.3E3");
|
||||
assert_tokenizes_as_number("12.34E56");
|
||||
assert_tokenizes_as_number(".3E-32");
|
||||
assert_tokenizes_as_number("12.");
|
||||
assert_tokenizes_as_number(".999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
|
||||
assert_tokenizes_as_number("0.");
|
||||
assert_tokenizes_as_number("1.E-4");
|
||||
assert_tokenizes_as_number("1.E9999");
|
||||
|
||||
assert_tokenizes_as_undefined_token("1E");
|
||||
assert_tokenizes_as_undefined_token("1..");
|
||||
assert_tokenizes_as_undefined_token("..");
|
||||
assert_tokenizes_as_undefined_token("1.EE");
|
||||
assert_tokenizes_as_undefined_token("1.E");
|
||||
assert_tokenizes_as_undefined_token("1E--4");
|
||||
assert_tokenizes_as_undefined_token("1.EE4");
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_parse_numbers) {
|
||||
int initialPoolSize = pool_size();
|
||||
assert_parsed_expression_type("2+3", ExpressionNode::Type::Addition);
|
||||
assert_pool_size(initialPoolSize);
|
||||
@@ -31,7 +95,292 @@ QUIZ_CASE(poincare_parser) {
|
||||
assert_parsed_expression_is("0.1E-2", Decimal(0.001));
|
||||
assert_parsed_expression_is("1.E-2", Decimal(0.01));
|
||||
assert_parsed_expression_is(".1E-2", Decimal(0.001));
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_memory_exhaustion) {
|
||||
int initialPoolSize = pool_size();
|
||||
int memoryFailureHasBeenHandled = false;
|
||||
{
|
||||
Poincare::ExceptionCheckpoint ecp;
|
||||
if (ExceptionRun(ecp)) {
|
||||
Addition a = Addition();
|
||||
while (true) {
|
||||
Expression e = Expression::parse("1+2+3+4+5+6+7+8+9+10");
|
||||
a.addChildAtIndexInPlace(e, 0, a.numberOfChildren());
|
||||
}
|
||||
} else {
|
||||
Poincare::Tidy();
|
||||
memoryFailureHasBeenHandled = true;
|
||||
}
|
||||
}
|
||||
|
||||
quiz_assert(memoryFailureHasBeenHandled);
|
||||
assert_pool_size(initialPoolSize);
|
||||
Expression e = Expression::parse("1+1");
|
||||
/* Stupid check to make sure the global variable generated by Bison is not
|
||||
* ruining everything */
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_parse) {
|
||||
assert_parsed_expression_is("1", Rational(1));
|
||||
assert_parsed_expression_is("(1)", Parenthesis(Rational(1)));
|
||||
assert_parsed_expression_is("((1))", Parenthesis((Expression)Parenthesis(Rational(1))));
|
||||
assert_parsed_expression_is("1+2", Addition(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("(1)+2", Addition(Parenthesis(Rational(1)),Rational(2)));
|
||||
assert_parsed_expression_is("(1+2)", Parenthesis(Addition(Rational(1),Rational(2))));
|
||||
assert_parsed_expression_is("1+2+3", Addition(Addition(Rational(1),Rational(2)),Rational(3)));
|
||||
assert_parsed_expression_is("1+2+(3+4)", Addition(Addition(Rational(1),Rational(2)),Parenthesis(Addition(Rational(3),Rational(4)))));
|
||||
assert_parsed_expression_is("1*2", Multiplication(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("1*2*3", Multiplication(Multiplication(Rational(1),Rational(2)),Rational(3)));
|
||||
assert_parsed_expression_is("1+2*3", Addition(Rational(1), Multiplication(Rational(2), Rational(3))));
|
||||
assert_parsed_expression_is("1/2", Division(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("(1/2)", Parenthesis(Division(Rational(1),Rational(2))));
|
||||
assert_parsed_expression_is("1/2/3", Division(Division(Rational(1),Rational(2)),Rational(3)));
|
||||
assert_parsed_expression_is("1/2*3", Multiplication(Division(Rational(1),Rational(2)),Rational(3)));
|
||||
assert_parsed_expression_is("(1/2*3)", Parenthesis(Multiplication(Division(Rational(1),Rational(2)),Rational(3))));
|
||||
assert_parsed_expression_is("1*2/3", Multiplication(Rational(1),Division(Rational(2),Rational(3))));
|
||||
assert_parsed_expression_is("(1*2/3)", Parenthesis(Multiplication(Rational(1),Division(Rational(2),Rational(3)))));
|
||||
assert_parsed_expression_is("(1/2/3)", Parenthesis(Division(Division(Rational(1),Rational(2)),Rational(3))));
|
||||
assert_parsed_expression_is("1^2", Power(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("1^2^3", Power(Rational(1),Power(Rational(2),Rational(3))));
|
||||
assert_parsed_expression_is("1=2", Equal(Rational(1),Rational(2)));
|
||||
assert_raises_parsing_error("1=2=3");
|
||||
assert_parsed_expression_is("-1", Opposite(Rational(1)));
|
||||
assert_parsed_expression_is("(-1)", Parenthesis(Opposite(Rational(1))));
|
||||
assert_parsed_expression_is("1-2", Subtraction(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("-1-2", Subtraction(Opposite(Rational(1)),Rational(2)));
|
||||
assert_parsed_expression_is("1-2-3", Subtraction(Subtraction(Rational(1),Rational(2)),Rational(3)));
|
||||
assert_parsed_expression_is("(1-2)", Parenthesis(Subtraction(Rational(1),Rational(2))));
|
||||
assert_parsed_expression_is("1+-2", Addition(Rational(1),Opposite(Rational(2))));
|
||||
assert_parsed_expression_is("--1", Opposite((Expression)Opposite(Rational(1))));
|
||||
assert_parsed_expression_is("(1+2)-3", Subtraction(Parenthesis(Addition(Rational(1),Rational(2))),Rational(3)));
|
||||
assert_parsed_expression_is("(2*-3)", Parenthesis(Multiplication(Rational(2),Opposite(Rational(3)))));
|
||||
assert_parsed_expression_is("1^(2)-3", Subtraction(Power(Rational(1),Parenthesis(Rational(2))),Rational(3)));
|
||||
assert_parsed_expression_is("1^2-3", Subtraction(Power(Rational(1),Rational(2)),Rational(3)));
|
||||
assert_parsed_expression_is("2^-3", Power(Rational(2),Opposite(Rational(3))));
|
||||
assert_parsed_expression_is("2--2+-1", Addition(Subtraction(Rational(2),Opposite(Rational(2))),Opposite(Rational(1))));
|
||||
assert_parsed_expression_is("2--2*-1", Subtraction(Rational(2),Multiplication(Opposite(Rational(2)),Opposite(Rational(1)))));
|
||||
assert_parsed_expression_is("-1^2", Opposite(Power(Rational(1),Rational(2))));
|
||||
assert_parsed_expression_is("2/-3/-4", Division(Division(Rational(2),Opposite(Rational(3))),Opposite(Rational(4))));
|
||||
assert_parsed_expression_is("1*2-3*4", Subtraction(Multiplication(Rational(1),Rational(2)),Multiplication(Rational(3),Rational(4))));
|
||||
assert_parsed_expression_is("-1*2", Multiplication(Opposite(Rational(1)), Rational(2))); // Unary minus shall have precedence
|
||||
assert_parsed_expression_is("1!", Factorial(Rational(1)));
|
||||
assert_parsed_expression_is("1+2!", Addition(Rational(1),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("1!+2", Addition(Factorial(Rational(1)),Rational(2)));
|
||||
assert_parsed_expression_is("1!+2!", Addition(Factorial(Rational(1)),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("1*2!", Multiplication(Rational(1),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("1!*2", Multiplication(Factorial(Rational(1)),Rational(2)));
|
||||
assert_parsed_expression_is("1!*2!", Multiplication(Factorial(Rational(1)),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("1-2!", Subtraction(Rational(1),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("1!-2", Subtraction(Factorial(Rational(1)),Rational(2)));
|
||||
assert_parsed_expression_is("1!-2!", Subtraction(Factorial(Rational(1)),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("1/2!", Division(Rational(1),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("1!/2", Division(Factorial(Rational(1)),Rational(2)));
|
||||
assert_parsed_expression_is("1!/2!", Division(Factorial(Rational(1)),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("1^2!", Power(Rational(1),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("1!^2", Power(Factorial(Rational(1)),Rational(2)));
|
||||
assert_parsed_expression_is("1!^2!", Power(Factorial(Rational(1)),Factorial(Rational(2))));
|
||||
assert_parsed_expression_is("(1)!", Factorial(Parenthesis(Rational(1))));
|
||||
assert_raises_parsing_error("1+");
|
||||
assert_raises_parsing_error(")");
|
||||
assert_raises_parsing_error(")(");
|
||||
assert_raises_parsing_error("()");
|
||||
assert_raises_parsing_error("(1");
|
||||
assert_raises_parsing_error("1)");
|
||||
assert_raises_parsing_error("1++2");
|
||||
assert_raises_parsing_error("1//2");
|
||||
assert_raises_parsing_error("*1");
|
||||
assert_raises_parsing_error("1^^2");
|
||||
assert_raises_parsing_error("^1");
|
||||
}
|
||||
|
||||
Matrix BuildMatrix(int rows, int columns, Expression entries[]) {
|
||||
Matrix m;
|
||||
int position = 0;
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < columns; j++) {
|
||||
m.addChildAtIndexInPlace(entries[position], position, position);
|
||||
position++;
|
||||
}
|
||||
}
|
||||
m.setDimensions(rows, columns);
|
||||
return m;
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_matrices) {
|
||||
Expression m1[] = {Rational(1)};
|
||||
assert_parsed_expression_is("[[1]]", BuildMatrix(1,1,m1));
|
||||
Expression m2[] = {Rational(1),Rational(2),Rational(3)};
|
||||
assert_parsed_expression_is("[[1,2,3]]", BuildMatrix(1,3,m2));
|
||||
Expression m3[] = {Rational(1),Rational(2),Rational(3),Rational(4),Rational(5),Rational(6)};
|
||||
assert_parsed_expression_is("[[1,2,3][4,5,6]]", BuildMatrix(2,3,m3));
|
||||
Expression m4[] = {Rational(1), BuildMatrix(1,1,m1)};
|
||||
assert_parsed_expression_is("[[1,[[1]]]]", BuildMatrix(1,2,m4));
|
||||
assert_raises_parsing_error("[");
|
||||
assert_raises_parsing_error("]");
|
||||
assert_raises_parsing_error("[[");
|
||||
assert_raises_parsing_error("][");
|
||||
assert_raises_parsing_error("[]");
|
||||
assert_raises_parsing_error("[1]");
|
||||
assert_raises_parsing_error("[[1,2],[3]]");
|
||||
assert_raises_parsing_error("[[]");
|
||||
assert_raises_parsing_error("[[1]");
|
||||
assert_raises_parsing_error("[1]]");
|
||||
assert_raises_parsing_error("[[,]]");
|
||||
assert_raises_parsing_error("[[1,]]");
|
||||
assert_raises_parsing_error(",");
|
||||
assert_raises_parsing_error("[,]");
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_symbols_and_functions) {
|
||||
// User-defined symbols
|
||||
assert_parsed_expression_is("a", Symbol("a", 1));
|
||||
assert_parsed_expression_is("x", Symbol("x", 1));
|
||||
assert_parsed_expression_is("toot", Symbol("toot", 4));
|
||||
assert_parsed_expression_is("toto_", Symbol("toto_", 5));
|
||||
assert_parsed_expression_is("t_toto", Symbol("t_toto", 6));
|
||||
assert_parsed_expression_is("tot12", Symbol("tot12", 5));
|
||||
assert_parsed_expression_is("TOto", Symbol("TOto", 4));
|
||||
assert_parsed_expression_is("TO12_Or", Symbol("TO12_Or", 7));
|
||||
assert_raises_parsing_error("_a");
|
||||
assert_raises_parsing_error("abcdefgh");
|
||||
|
||||
// User-defined functions
|
||||
assert_parsed_expression_is("f(x)", Function("f", 1, Symbol("x",1)));
|
||||
assert_parsed_expression_is("f(1)", Function("f", 1, Rational(1)));
|
||||
assert_parsed_expression_is("ab12AB_(x)", Function("ab12AB_", 7, Symbol("x",1)));
|
||||
assert_parsed_expression_is("ab12AB_(1)", Function("ab12AB_", 7, Rational(1)));
|
||||
assert_parsed_expression_is("f(g(x))", Function("f", 1, Function("g", 1, Symbol("x",1))));
|
||||
assert_parsed_expression_is("f(g(1))", Function("f", 1, Function("g", 1, Rational(1))));
|
||||
assert_parsed_expression_is("f((1))", Function("f", 1, Parenthesis(Rational(1))));
|
||||
assert_raises_parsing_error("f(1,2)");
|
||||
assert_raises_parsing_error("f(f)");
|
||||
assert_raises_parsing_error("abcdefgh(1)");
|
||||
|
||||
// Reserved symbols
|
||||
assert_parsed_expression_is("ans", Symbol("ans", 3));
|
||||
assert_parsed_expression_is("I", Constant(Ion::Charset::IComplex));
|
||||
assert_parsed_expression_is("P", Constant(Ion::Charset::SmallPi));
|
||||
assert_parsed_expression_is("X", Constant(Ion::Charset::Exponential));
|
||||
assert_parsed_expression_is("inf", Infinity(false));
|
||||
assert_parsed_expression_is("undef", Undefined());
|
||||
|
||||
assert_raises_parsing_error("u");
|
||||
assert_raises_parsing_error("v");
|
||||
|
||||
// Reserved functions
|
||||
assert_parsed_expression_is("acos(1)", ArcCosine::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("acosh(1)", HyperbolicArcCosine::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("abs(1)", AbsoluteValue::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("arg(1)", ComplexArgument::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("asin(1)", ArcSine::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("asinh(1)", HyperbolicArcSine::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("atan(1)", ArcTangent::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("atanh(1)", HyperbolicArcTangent::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("binomial(2,1)", BinomialCoefficient::Builder(Rational(2),Rational(1)));
|
||||
assert_parsed_expression_is("ceil(1)", Ceiling::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("confidence(1,2)", ConfidenceInterval::Builder(Rational(1),Rational(2)));
|
||||
assert_raises_parsing_error("diff(1,2,3)");
|
||||
assert_parsed_expression_is("diff(1,x,3)", Derivative::Builder(Rational(1),Symbol("x",1),Rational(3)));
|
||||
assert_parsed_expression_is("dim(1)", MatrixDimension::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("conj(1)", Conjugate::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("det(1)", Determinant::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("cos(1)", Cosine::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("cosh(1)", HyperbolicCosine::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("factor(1)", Factor::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("floor(1)", Floor::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("frac(1)", FracPart::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("gcd(1,2)", GreatCommonDivisor::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("im(1)", ImaginaryPart::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("int(1,x,2,3)", Integral::Builder(Rational(1),Symbol("x",1),Rational(2),Rational(3)));
|
||||
assert_raises_parsing_error("int(1,2,3,4)");
|
||||
assert_parsed_expression_is("inverse(1)", MatrixInverse::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("lcm(1,2)", LeastCommonMultiple::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("ln(1)", NaperianLogarithm::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("log(1)", CommonLogarithm::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("log(1,2)", Logarithm::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("log_{2}(1)", Logarithm::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("permute(2,1)", PermuteCoefficient::Builder(Rational(2),Rational(1)));
|
||||
assert_parsed_expression_is("prediction95(1,2)", PredictionInterval::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("prediction(1,2)", SimplePredictionInterval::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("product(1,n,2,3)", Product::Builder(Rational(1),Symbol("n",1),Rational(2),Rational(3)));
|
||||
assert_raises_parsing_error("product(1,2,3,4)");
|
||||
assert_parsed_expression_is("quo(1,2)", DivisionQuotient::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("random()", Random::Builder());
|
||||
assert_parsed_expression_is("randint(1,2)", Randint::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("re(1)", RealPart::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("rem(1,2)", DivisionRemainder::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("root(1,2)", NthRoot::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("round(1,2)", Round::Builder(Rational(1),Rational(2)));
|
||||
assert_parsed_expression_is("sin(1)", Sine::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("sinh(1)", HyperbolicSine::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("sum(1,n,2,3)", Sum::Builder(Rational(1),Symbol("n",1),Rational(2),Rational(3)));
|
||||
assert_raises_parsing_error("sum(1,2,3,4)");
|
||||
assert_parsed_expression_is("tan(1)", Tangent::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("tanh(1)", HyperbolicTangent::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("trace(1)", MatrixTrace::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("transpose(1)", MatrixTranspose::Builder(Rational(1)));
|
||||
assert_parsed_expression_is("\x91(1)", SquareRoot::Builder(Rational(1)));
|
||||
assert_raises_parsing_error("cos(1,2)");
|
||||
assert_raises_parsing_error("log(1,2,3)");
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_parse_store) {
|
||||
assert_parsed_expression_is("1>a", Store(Rational(1),Symbol("a",1)));
|
||||
assert_parsed_expression_is("1>e", Store(Rational(1),Symbol("e",1)));
|
||||
assert_parsed_expression_is("1>ans", Store(Rational(1),Symbol("ans",3)));
|
||||
assert_parsed_expression_is("1>f(x)", Store(Rational(1),Function("f",1,Symbol("x",1))));
|
||||
assert_parsed_expression_is("x>f(x)", Store(Symbol("x",1),Function("f",1,Symbol("x",1))));
|
||||
assert_parsed_expression_is("n>f(x)", Store(Symbol("n",1),Function("f",1,Symbol("x",1))));
|
||||
assert_raises_parsing_error("1>2");
|
||||
assert_raises_parsing_error("1>");
|
||||
assert_raises_parsing_error(">2");
|
||||
assert_raises_parsing_error("(1>a)");
|
||||
assert_raises_parsing_error("1>u(n)");
|
||||
assert_raises_parsing_error("1>u(n+1)");
|
||||
assert_raises_parsing_error("1>v(n)");
|
||||
assert_raises_parsing_error("1>v(n+1)");
|
||||
assert_raises_parsing_error("1>u_{n}");
|
||||
assert_raises_parsing_error("1>u_{n+1}");
|
||||
assert_raises_parsing_error("1>v_{n}");
|
||||
assert_raises_parsing_error("1>v_{n+1}");
|
||||
assert_raises_parsing_error("1>inf");
|
||||
assert_raises_parsing_error("1>undef");
|
||||
assert_raises_parsing_error("1>P");
|
||||
assert_raises_parsing_error("1>I");
|
||||
assert_raises_parsing_error("1>X");
|
||||
assert_raises_parsing_error("1>\1"); // UnknownX
|
||||
assert_raises_parsing_error("1>acos");
|
||||
assert_raises_parsing_error("1>f(2)");
|
||||
assert_raises_parsing_error("1>f(f)");
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_implicit_multiplication) {
|
||||
assert_raises_parsing_error(".1.2");
|
||||
assert_raises_parsing_error("1 2");
|
||||
assert_parsed_expression_is("1x", Multiplication(Rational(1),Symbol("x", 1)));
|
||||
assert_parsed_expression_is("1ans", Multiplication(Rational(1),Symbol("ans", 3)));
|
||||
assert_parsed_expression_is("x1", Symbol("x1", 2));
|
||||
assert_parsed_expression_is("1x+2", Addition(Multiplication(Rational(1),Symbol("x", 1)),Rational(2)));
|
||||
assert_parsed_expression_is("1P", Multiplication(Rational(1),Constant(Ion::Charset::SmallPi)));
|
||||
assert_parsed_expression_is("1x-2", Subtraction(Multiplication(Rational(1),Symbol("x", 1)),Rational(2)));
|
||||
assert_parsed_expression_is("-1x", Opposite(Multiplication(Rational(1),Symbol("x", 1))));
|
||||
assert_parsed_expression_is("2*1x", Multiplication(Rational(2),Multiplication(Rational(1),Symbol("x", 1))));
|
||||
assert_parsed_expression_is("2^1x", Multiplication(Power(Rational(2),Rational(1)),Symbol("x", 1)));
|
||||
assert_parsed_expression_is("1x^2", Multiplication(Rational(1),Power(Symbol("x", 1),Rational(2))));
|
||||
assert_parsed_expression_is("2/1x", Division(Rational(2),Multiplication(Rational(1),Symbol("x", 1))));
|
||||
assert_parsed_expression_is("1x/2", Division(Multiplication(Rational(1),Symbol("x", 1)),Rational(2)));
|
||||
assert_parsed_expression_is("(1)2", Multiplication(Parenthesis(Rational(1)),Rational(2)));
|
||||
assert_parsed_expression_is("1(2)", Multiplication(Rational(1),Parenthesis(Rational(2))));
|
||||
assert_parsed_expression_is("sin(1)2", Multiplication(Sine::Builder(Rational(1)),Rational(2)));
|
||||
assert_parsed_expression_is("1cos(2)", Multiplication(Rational(1),Cosine::Builder(Rational(2))));
|
||||
assert_parsed_expression_is("1!2", Multiplication(Factorial(Rational(1)),Rational(2)));
|
||||
Expression m1[] = {Rational(1)}; Matrix M1 = BuildMatrix(1,1,m1);
|
||||
Expression m2[] = {Rational(2)}; Matrix M2 = BuildMatrix(1,1,m2);
|
||||
assert_parsed_expression_is("[[1]][[2]]", Multiplication(M1,M2));
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_expression_evaluation) {
|
||||
assert_parsed_expression_evaluates_to<float>("-0", "0");
|
||||
assert_parsed_expression_evaluates_to<float>("-0.1", "-0.1");
|
||||
assert_parsed_expression_evaluates_to<float>("-1.", "-1");
|
||||
@@ -61,32 +410,3 @@ QUIZ_CASE(poincare_parser) {
|
||||
assert_parsed_expression_evaluates_to<float>("4/2*(2+3)", "10");
|
||||
assert_parsed_expression_evaluates_to<double>("4/2*(2+3)", "10");
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_do_not_parse_implicitly_multiplied_numbers) {
|
||||
Expression e = Expression::parse(".1.2");
|
||||
quiz_assert(e.isUninitialized());
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_parser_memory_exhaustion) {
|
||||
int initialPoolSize = pool_size();
|
||||
int memoryFailureHasBeenHandled = false;
|
||||
{
|
||||
Poincare::ExceptionCheckpoint ecp;
|
||||
if (ExceptionRun(ecp)) {
|
||||
Addition a = Addition();
|
||||
while (true) {
|
||||
Expression e = Expression::parse("1+2+3+4+5+6+7+8+9+10");
|
||||
a.addChildAtIndexInPlace(e, 0, a.numberOfChildren());
|
||||
}
|
||||
} else {
|
||||
Poincare::Tidy();
|
||||
memoryFailureHasBeenHandled = true;
|
||||
}
|
||||
}
|
||||
|
||||
quiz_assert(memoryFailureHasBeenHandled);
|
||||
assert_pool_size(initialPoolSize);
|
||||
Expression e = Expression::parse("1+1");
|
||||
/* Stupid check to make sure the global variable generated by Bison is not
|
||||
* ruining everything */
|
||||
}
|
||||
|
||||
@@ -55,9 +55,8 @@ QUIZ_CASE(poincare_polynomial_degree) {
|
||||
assert_parsed_expression_polynomial_degree("P*x", 1);
|
||||
}
|
||||
|
||||
void assert_parsed_expression_has_characteristic_range(const char * expression, float range, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) {
|
||||
void assert_expression_has_characteristic_range(Expression e, float range, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) {
|
||||
Shared::GlobalContext globalContext;
|
||||
Expression e = parse_expression(expression);
|
||||
quiz_assert(!e.isUninitialized());
|
||||
e = e.simplify(globalContext, angleUnit);
|
||||
if (std::isnan(range)) {
|
||||
@@ -68,17 +67,17 @@ void assert_parsed_expression_has_characteristic_range(const char * expression,
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_characteristic_range) {
|
||||
assert_parsed_expression_has_characteristic_range("cos(?)", 360.0f);
|
||||
assert_parsed_expression_has_characteristic_range("cos(-?)", 360.0f);
|
||||
assert_parsed_expression_has_characteristic_range("cos(?)", 2.0f*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_parsed_expression_has_characteristic_range("cos(-?)", 2.0f*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_parsed_expression_has_characteristic_range("sin(9*?+10)", 40.0f);
|
||||
assert_parsed_expression_has_characteristic_range("sin(9*?+10)+cos(?/2)", 720.0f);
|
||||
assert_parsed_expression_has_characteristic_range("sin(9*?+10)+cos(?/2)", 4.0f*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_parsed_expression_has_characteristic_range("?", NAN);
|
||||
assert_parsed_expression_has_characteristic_range("cos(3)+2", 0.0f);
|
||||
assert_parsed_expression_has_characteristic_range("log(cos(40*?))", 9.0f);
|
||||
assert_parsed_expression_has_characteristic_range("cos(cos(?))", 360.0f);
|
||||
assert_expression_has_characteristic_range(Cosine::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)), 360.0f);
|
||||
assert_expression_has_characteristic_range(Cosine::Builder(Opposite(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX))), 360.0f);
|
||||
assert_expression_has_characteristic_range(Cosine::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)), 2.0f*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_expression_has_characteristic_range(Cosine::Builder(Opposite(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX))), 2.0f*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_expression_has_characteristic_range(Sine::Builder(Addition(Multiplication(Rational(9),Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)),Rational(10))), 40.0f);
|
||||
assert_expression_has_characteristic_range(Addition(Sine::Builder(Addition(Multiplication(Rational(9),Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)),Rational(10))),Cosine::Builder(Division(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX),Rational(2)))), 720.0f);
|
||||
assert_expression_has_characteristic_range(Addition(Sine::Builder(Addition(Multiplication(Rational(9),Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)),Rational(10))),Cosine::Builder(Division(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX),Rational(2)))), 4.0f*M_PI, Preferences::AngleUnit::Radian);
|
||||
assert_expression_has_characteristic_range(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX), NAN);
|
||||
assert_expression_has_characteristic_range(Addition(Cosine::Builder(Rational(3)),Rational(2)), 0.0f);
|
||||
assert_expression_has_characteristic_range(CommonLogarithm::Builder(Cosine::Builder(Multiplication(Rational(40),Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)))), 9.0f);
|
||||
assert_expression_has_characteristic_range(Cosine::Builder((Expression)Cosine::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX))), 360.0f);
|
||||
}
|
||||
|
||||
void assert_parsed_expression_has_variables(const char * expression, const char * variables[], int trueNumberOfVariables) {
|
||||
|
||||
@@ -53,7 +53,7 @@ QUIZ_CASE(poincare_simplify_mix) {
|
||||
assert_parsed_expression_simplify_to("R(-I)", "R(-I)");
|
||||
assert_parsed_expression_simplify_to("A*cos(9)IIln(2)", "-cos(9)*ln(2)*A");
|
||||
assert_parsed_expression_simplify_to("(R(2)+R(2)*I)/2(R(2)+R(2)*I)/2(R(2)+R(2)*I)/2", "(R(2)-R(2)*I)/32");
|
||||
assert_parsed_expression_simplify_to("root(5^(-I)3^9,I)", "(5^(-19683*I))^(-I)");
|
||||
assert_parsed_expression_simplify_to("root(5^((-I)3^9),I)", "(5^(-19683*I))^(-I)");
|
||||
assert_parsed_expression_simplify_to("I^I", "I^I");
|
||||
|
||||
//assert_parsed_expression_simplify_to("log(cos(9)^ln(6), cos(9))", "ln(2)+ln(3)"); // TODO: for this to work, we must know the sign of cos(9)
|
||||
|
||||
Reference in New Issue
Block a user