import 'package:math_expressions/math_expressions.dart';
import 'dart:io';
String setOperation() {
print('Enter the operation: ');
return stdin.readLineSync()!;
}
void calculate() {
String? entrance = setOperation();
if (entrance.toLowerCase() == 'exit') {
return;
}
try {
ShuntingYardParser p = ShuntingYardParser();
Expression exp = p.parse(entrance);
ContextModel cm = ContextModel();
double result = exp.evaluate(EvaluationType.REAL, cm);
print('Result: $result');
} catch (e) {
print('Invalid expression: $e, please try again');
}
calculate();
}
void main() {
calculate();
}
Eu usei a biblioteca math_expressions para fazer uma calculadora que aceite a conta em uma linha só. O objeto (e sim eu sei que ainda não tem Objetos nessa parte, mas se você não souber, basta pesquisar no Google o que é um Objeto segundo a Orientação a Objetos) ShuntingYardParser criar um novo parser que, por sua vez, é capaz de "traduzir" uma conta completa e nela eu coloquei a entrada. O objeto ContextModel é utilizado para armazenar variáveis:
ContextModel cm = ContextModel();
cm.bindVariableName('x', 5.0);
cm.bindVariableName('y', 3.0);
// Now you can evaluate expressions like "x + y * 2"
Expression exp = p.parse('x + y * 2');
double result = exp.evaluate(EvaluationType.REAL, cm); // 11.0
Nesse caso ele estará nulo, mas ele é necessário na função evaluate. Por fim, o bloco try - catch (outra coisa que se pesquisar no Google você encontra o que é) eu usei pra fazer a validação. O código tenta o que tá no bloco try e se der erro ele entra no bloco catch que é a onde eu declarei o erro e chamei a função novamente. Também criei uma forma de o próprio usuário sair da funçãoe de o usuário fazer outra conta sem ter que repetir o comando na linha de comando.