fromStringExtended static method
Create a new MathExpression from String
Compared to fromString, this method also supports creating MathExpression entities, like MathComparisonEquation, MathComparisonGreater, MathComparisonLess. This means, this method supports =, < and > operators.
Implementation
static MathExpression fromStringExtended(
/// The expression to convert
String expression, {
/// Converts all X - Y to X + (-Y)
bool isMinusNegativeFunction = false,
/// Allows skipping the multiplication (*) operator
bool isImplicitMultiplication = true,
/// Expressions which should be marked as variables
Set<String> variableNames = const {'x'},
/// Expressions which should be marked as functions
MathCustomFunctionsImplemented customFunctions =
const MathCustomFunctionsImplemented({}),
}) {
final nodes = <_MathExpressionPart>[];
int start = 0;
for (final match in RegExp('(<=|>=|=|<|>)').allMatches(expression, 0)) {
var r = expression.substring(start, match.start);
if (r.isNotEmpty) nodes.add(_MathExpressionPartString(r));
r = match[0]!;
if (r.isNotEmpty) {
nodes.add(_MathExpressionPartString(r));
}
start = match.end;
}
final r = expression.substring(start);
if (r.isNotEmpty) nodes.add(_MathExpressionPartString(r));
for (var i = 0; i < nodes.length; i++) {
final token = nodes[i];
if (token is! _MathExpressionPartString ||
!RegExp(r'^(<=|>=|=|<|>)$').hasMatch(token.str)) continue;
if (i == 0 || i == nodes.length - 1) {
throw MissingOperatorOperandException(token.str);
}
final left = nodes[i - 1];
late final _MathExpressionPartParsed leftParsed;
if (left is _MathExpressionPartString) {
leftParsed = _MathExpressionPartParsed(
fromString(
left.str,
isMinusNegativeFunction: isImplicitMultiplication,
isImplicitMultiplication: isImplicitMultiplication,
customFunctions: customFunctions,
variableNames: variableNames,
),
);
} else if (left is _MathExpressionPartParsed) {
leftParsed = left;
} else {
throw CantProcessExpressionException([left]);
}
final right = nodes[i + 1];
late final _MathExpressionPartParsed rightParsed;
if (right is _MathExpressionPartString) {
rightParsed = _MathExpressionPartParsed(
fromString(
right.str,
isMinusNegativeFunction: isImplicitMultiplication,
isImplicitMultiplication: isImplicitMultiplication,
customFunctions: customFunctions,
variableNames: variableNames,
),
);
} else if (right is _MathExpressionPartParsed) {
rightParsed = right;
} else {
throw CantProcessExpressionException([right]);
}
nodes.removeAt(i - 1);
nodes.removeAt(i - 1);
nodes.removeAt(i - 1);
late final MathExpression result;
if (token.str == '>=') {
result =
MathComparisonGreaterOrEquals(leftParsed.node, rightParsed.node);
} else if (token.str == '<=') {
result = MathComparisonLessOrEquals(leftParsed.node, rightParsed.node);
} else if (token.str == '=') {
result = MathComparisonEquation(leftParsed.node, rightParsed.node);
} else if (token.str == '>') {
result = MathComparisonGreater(leftParsed.node, rightParsed.node);
} else if (token.str == '<') {
result = MathComparisonLess(leftParsed.node, rightParsed.node);
} else {
throw UnknownOperationException(token.str);
}
nodes.insert(i - 1, _MathExpressionPartParsed(result));
i -= 2;
}
if (nodes.length == 1) {
if (nodes[0] is _MathExpressionPartString) {
return fromString(
nodes[0].str!,
isMinusNegativeFunction: isImplicitMultiplication,
isImplicitMultiplication: isImplicitMultiplication,
customFunctions: customFunctions,
variableNames: variableNames,
);
} else if (nodes[0] is _MathExpressionPartParsed) {
return nodes[0].node!;
}
}
throw CantProcessExpressionException(nodes);
}