201 lines
8.3 KiB
C#
201 lines
8.3 KiB
C#
namespace Lunar.Evil_Calculator
|
|
{
|
|
class EquationManager
|
|
{
|
|
private ReverseNotationSolver reverseNotationSolver = new();
|
|
|
|
List<Token> equation = new();
|
|
string currentOperand = "";
|
|
Label? outerEquationLabel;
|
|
Label? outerOperandLabel;
|
|
int openParentheses;
|
|
|
|
|
|
//NO OPENING PARENTHESES AFTER NUMERICS OR CLOSING PARENTHESES => NULL, OPENING PARENTHESES OR OPERATOR EXPECTED
|
|
//NO CLOSING PARENTHESES AFTER OPERATORS, EXCEPT IF $currentOperand IS NOT ""
|
|
//NO CLOSING PARENTHESES WHEN $openParentheses <1
|
|
//OPERATOR OR null BEFORE OPENING PARENTHESES EXPECTED
|
|
//$openParentheses SHOULD BE 0 BEFORE SOLVING, DISPLAY ERROR OTHERWISE => HANDLED BY SOLVER
|
|
//MINUS AFTER OPENING PARENTHESES OR null GOES TO OPERAND IF $currentOperand IS ""
|
|
//NO OPERATORS AFTER OPERATORS, OPENING PARENTHESES OR null (EXCEPT FOR MINUS THAT GOES TO OPERAND AND SQRT THAT IS UNAR)
|
|
//NO NUMERICS IF currentOperand.StartsWith("0") AND currentOperand.Length == 1, . ALLOWED-EXPECTED
|
|
//NO . IF currentOperand.Contains(",")
|
|
|
|
|
|
public void ProcessButtonInput(object? sender, EventArgs e)
|
|
{
|
|
if (sender is Button buttonPressed)
|
|
{
|
|
switch (buttonPressed.Text)
|
|
{
|
|
//CLEAR
|
|
case "C":
|
|
currentOperand = "";
|
|
break;
|
|
case "CE":
|
|
equation.Clear();
|
|
currentOperand = "";
|
|
break;
|
|
//OPERATORS
|
|
// + -
|
|
case "+":
|
|
if ((!IsOperator() && !IsOpen() && !IsNull()) || currentOperand != "" && currentOperand != "-")
|
|
{
|
|
equation.Add(new Token(Token.TokenType.Operand, currentOperand));
|
|
equation.Add(new Token(Token.TokenType.Operator, buttonPressed.Text, 1));
|
|
currentOperand = "";
|
|
}
|
|
break;
|
|
case "-":
|
|
if ((!IsOperator() || currentOperand != "") && currentOperand != "-")
|
|
{
|
|
if ((IsOpen() || IsNull()) && currentOperand == "")
|
|
{
|
|
currentOperand += "-";
|
|
}
|
|
else
|
|
{
|
|
equation.Add(new Token(Token.TokenType.Operand, currentOperand));
|
|
equation.Add(new Token(Token.TokenType.Operator, buttonPressed.Text, 1));
|
|
currentOperand = "";
|
|
}
|
|
}
|
|
break;
|
|
// * /
|
|
case "*" or "/":
|
|
if ((!IsOperator() && !IsOpen() && !IsNull()) || currentOperand != "" && currentOperand != "-")
|
|
{
|
|
equation.Add(new Token(Token.TokenType.Operand, currentOperand));
|
|
equation.Add(new Token(Token.TokenType.Operator, buttonPressed.Text, 2));
|
|
currentOperand = "";
|
|
}
|
|
break;
|
|
//SQUARE ROOT
|
|
case "√":
|
|
if (!IsClose())
|
|
{
|
|
equation.Add(new Token(Token.TokenType.Operand, currentOperand));
|
|
equation.Add(new Token(Token.TokenType.Operator, buttonPressed.Text, 3));
|
|
currentOperand = "";
|
|
}
|
|
break;
|
|
//SQUARE AND POWER
|
|
case "x²":
|
|
if ((!IsOperator() && !IsOpen() && !IsNull()) || currentOperand != "" && currentOperand != "-")
|
|
{
|
|
equation.Add(new Token(Token.TokenType.Operand, currentOperand));
|
|
equation.Add(new Token(Token.TokenType.Operator, "^", 3));
|
|
equation.Add(new Token(Token.TokenType.Operand, "2"));
|
|
currentOperand = "";
|
|
}
|
|
break;
|
|
case "xˣ":
|
|
if ((!IsOperator() && !IsOpen() && !IsNull()) || currentOperand != "" && currentOperand != "-")
|
|
{
|
|
equation.Add(new Token(Token.TokenType.Operand, currentOperand));
|
|
equation.Add(new Token(Token.TokenType.Operator, "^", 3));
|
|
currentOperand = "";
|
|
}
|
|
break;
|
|
//PARENTHESES
|
|
case "(":
|
|
if (IsOperator() || IsOpen() || IsNull())
|
|
{
|
|
equation.Add(new Token(Token.TokenType.Operator, buttonPressed.Text));
|
|
openParentheses++;
|
|
currentOperand = "";
|
|
}
|
|
break;
|
|
case ")":
|
|
if ((!IsOperator() || currentOperand != "") && openParentheses > 0 && currentOperand != "-")
|
|
{
|
|
if (currentOperand.Length > 0)
|
|
{
|
|
equation.Add(new Token(Token.TokenType.Operand, currentOperand));
|
|
currentOperand = "";
|
|
}
|
|
equation.Add(new Token(Token.TokenType.Operator, buttonPressed.Text));
|
|
openParentheses--;
|
|
}
|
|
break;
|
|
//POINT
|
|
case ",":
|
|
if (currentOperand.Length > 0 && !currentOperand.Contains(","))
|
|
{
|
|
currentOperand += buttonPressed.Text;
|
|
}
|
|
break;
|
|
//NUMERIC
|
|
default:
|
|
if (!(currentOperand.Length == 1 && currentOperand.StartsWith("0")))
|
|
{
|
|
currentOperand += buttonPressed.Text;
|
|
}
|
|
break;
|
|
}
|
|
|
|
UpdateLabels();
|
|
}
|
|
}
|
|
|
|
public void EqualsButtonPressed(object? sender, EventArgs e)
|
|
{
|
|
if (sender is Button buttonEquals)
|
|
{
|
|
if (currentOperand != "") equation.Add(new Token(Token.TokenType.Operand, currentOperand));
|
|
buttonEquals.Text = "#";
|
|
currentOperand = reverseNotationSolver.Solve(ref equation);
|
|
UpdateLabels();
|
|
}
|
|
}
|
|
|
|
public void AcquireOutputLabels(ref Label equationTextBox, ref Label currentOperandTextBox)
|
|
{
|
|
outerEquationLabel = equationTextBox;
|
|
outerOperandLabel = currentOperandTextBox;
|
|
}
|
|
|
|
public string equationToString()
|
|
{
|
|
string equationString = "";
|
|
foreach (Token token in equation)
|
|
{
|
|
equationString += token.value + " ";
|
|
}
|
|
return equationString;
|
|
}
|
|
|
|
private void UpdateLabels()
|
|
{
|
|
if (outerEquationLabel != null && outerOperandLabel != null)
|
|
{
|
|
outerEquationLabel.Text = equationToString();
|
|
outerOperandLabel.Text = currentOperand == "" ? "0" : currentOperand;
|
|
}
|
|
}
|
|
|
|
private bool IsOperator()
|
|
{
|
|
if (equation.Count == 0) return false;
|
|
return new[] { "+", "-", "*", "/", "^", "√" }.Contains(equation.Last().value);
|
|
}
|
|
|
|
private bool IsOpen()
|
|
{
|
|
if (equation.Count == 0) return false;
|
|
return equation.Last().value == "(";
|
|
}
|
|
|
|
private bool IsClose()
|
|
{
|
|
if (equation.Count == 0) return false;
|
|
return equation.Last().value == ")";
|
|
}
|
|
|
|
private bool IsNull()
|
|
{
|
|
return equation.Count == 0;
|
|
}
|
|
}
|
|
}
|