helper.cpp
5.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <quiz.h>
#include <poincare.h>
#include <string.h>
#include <ion.h>
#include <stdlib.h>
#include <assert.h>
#include <cmath>
#include "helper.h"
#if POINCARE_TESTS_PRINT_EXPRESSIONS
#include "../src/expression_debug.h"
#include <iostream>
using namespace std;
#endif
using namespace Poincare;
void translate_in_special_chars(char * expression) {
for (char *c = expression; *c; c++) {
switch (*c) {
case 'E': *c = Ion::Charset::Exponent; break;
case 'X': *c = Ion::Charset::Exponential; break;
case 'I': *c = Ion::Charset::IComplex; break;
case 'R': *c = Ion::Charset::Root; break;
case 'P': *c = Ion::Charset::SmallPi; break;
case '*': *c = Ion::Charset::MultiplicationSign; break;
case '>': *c = Ion::Charset::Sto; break;
}
}
}
void translate_in_ASCII_chars(char * expression) {
for (char *c = expression; *c; c++) {
switch (*c) {
case Ion::Charset::Exponent: *c = 'E'; break;
case Ion::Charset::Exponential: *c = 'X'; break;
case Ion::Charset::IComplex: *c = 'I'; break;
case Ion::Charset::Root: *c = 'R'; break;
case Ion::Charset::SmallPi: *c = 'P'; break;
case Ion::Charset::MultiplicationSign: *c = '*'; break;
case Ion::Charset::MiddleDot: *c = '*'; break;
case Ion::Charset::Sto: *c = '>'; break;
}
}
}
Expression * parse_expression(const char * expression) {
quiz_print(expression);
char buffer[200];
strlcpy(buffer, expression, sizeof(buffer));
translate_in_special_chars(buffer);
Expression * result = Expression::parse(buffer);
assert(result);
return result;
}
void assert_parsed_expression_type(const char * expression, Poincare::Expression::Type type) {
Expression * e = parse_expression(expression);
assert(e->type() == type);
delete e;
}
void assert_parsed_expression_polynomial_degree(const char * expression, int degree, char symbolName) {
GlobalContext globalContext;
Expression * e = parse_expression(expression);
Expression::Simplify(&e, globalContext, Radian);
assert(e->polynomialDegree(symbolName) == degree);
delete e;
}
typedef Expression * (*ProcessExpression)(Expression *, Context & context, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat);
void assert_parsed_expression_process_to(const char * expression, const char * result, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat, ProcessExpression process, int numberOfSignifiantDigits = PrintFloat::k_numberOfStoredSignificantDigits) {
GlobalContext globalContext;
Expression * e = parse_expression(expression);
#if POINCARE_TESTS_PRINT_EXPRESSIONS
cout << " Entry expression: " << expression << "----" << endl;
#endif
Expression::Simplify(&e, globalContext, angleUnit);
Expression * m = process(e, globalContext, angleUnit, complexFormat);
char buffer[500];
m->writeTextInBuffer(buffer, sizeof(buffer), DecimalMode, numberOfSignifiantDigits);
translate_in_ASCII_chars(buffer);
#if POINCARE_TESTS_PRINT_EXPRESSIONS
print_expression(e, 0);
cout << "---- serialize to: " << buffer << " ----" << endl;
cout << "----- compared to: " << result << " ----\n" << endl;
#endif
assert(strcmp(buffer, result) == 0);
delete e;
if (e != m) {
delete m;
}
}
template<typename T>
void assert_parsed_expression_evaluates_to(const char * expression, const char * approximation, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat, int numberOfSignificantDigits) {
#if POINCARE_TESTS_PRINT_EXPRESSIONS
cout << "--------- Approximation ---------" << endl;
#endif
int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits;
numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits;
assert_parsed_expression_process_to(expression, approximation, angleUnit, complexFormat, [](Expression * e, Context & context, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat) {
return e->approximate<T>(context, angleUnit, complexFormat);
}, numberOfDigits);
}
void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, Expression::AngleUnit angleUnit) {
#if POINCARE_TESTS_PRINT_EXPRESSIONS
cout << "--------- Simplification ---------" << endl;
#endif
assert_parsed_expression_process_to(expression, simplifiedExpression, angleUnit, Expression::ComplexFormat::Cartesian, [](Expression * e, Context & context, Expression::AngleUnit angleUnit, Expression::ComplexFormat complexFormat) { return e; });
}
void assert_parsed_expression_layout_serialize_to_self(const char * expressionLayout) {
Expression * e = parse_expression(expressionLayout);
#if POINCARE_TESTS_PRINT_EXPRESSIONS
cout << "---- Serialize: " << expressionLayout << "----" << endl;
#endif
ExpressionLayout * el = e->createLayout(DecimalMode, PrintFloat::k_numberOfStoredSignificantDigits);
int bufferSize = 255;
char buffer[bufferSize];
el->writeTextInBuffer(buffer, bufferSize);
#if POINCARE_TESTS_PRINT_EXPRESSIONS
cout << "---- serialized to: " << buffer << " ----\n" << endl;
#endif
assert(strcmp(expressionLayout, buffer) == 0);
delete e;
delete el;
}
void assert_expression_layout_serialize_to(Poincare::ExpressionLayout * layout, const char * serialization) {
int bufferSize = 255;
char buffer[bufferSize];
layout->writeTextInBuffer(buffer, bufferSize);
#if POINCARE_TESTS_PRINT_EXPRESSIONS
cout << "---- Serialize: " << serialization << "----" << endl;
cout << "---- serialized to: " << buffer << " ----" << endl;
cout << "----- compared to: " << serialization << " ----\n" << endl;
#endif
assert(strcmp(serialization, buffer) == 0);
}
template void assert_parsed_expression_evaluates_to<float>(char const*, char const *, Poincare::Expression::AngleUnit, Poincare::Expression::ComplexFormat, int);
template void assert_parsed_expression_evaluates_to<double>(char const*, char const *, Poincare::Expression::AngleUnit, Poincare::Expression::ComplexFormat, int);