diff --git a/.idea/.idea.calculator/.idea/git_toolbox_prj.xml b/.idea/.idea.calculator/.idea/git_toolbox_prj.xml
new file mode 100644
index 0000000..02b915b
--- /dev/null
+++ b/.idea/.idea.calculator/.idea/git_toolbox_prj.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Commands/CalculateCommand.cs b/Commands/CalculateCommand.cs
deleted file mode 100644
index 782282f..0000000
--- a/Commands/CalculateCommand.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using calculator.Common;
-using calculator.Model;
-using calculator.Services;
-
-namespace calculator.Commands;
-
-public class CalculateCommand : ICommand
-{
- private readonly ICaculator _caculator;
- private readonly CaculatorData _data;
- private readonly double? _b;
- private readonly Operation _operation;
- private double? _previousValue;
-
- public CalculateCommand(ICaculator caculator, CaculatorData data)
- {
- _caculator = caculator;
- _data = data;
- _operation = data.Operation.Value;
-
- if (double.TryParse(data.Input, out var b))
- _b = b;
- }
-
- public void Execute()
- {
- if (_data.Value is null)
- return;
- _previousValue = _data.Value;
- _data.Value = _caculator.Calculate(_operation, _data.Value.Value, _b);
- _data.Input = null;
- }
-
- public void Undo()
- {
- _data.Value = _previousValue;
- }
-}
\ No newline at end of file
diff --git a/Common/CalculatorExtensions.cs b/Common/CalculatorExtensions.cs
new file mode 100644
index 0000000..60b2a36
--- /dev/null
+++ b/Common/CalculatorExtensions.cs
@@ -0,0 +1,56 @@
+namespace calculator.Common;
+
+public static class CalculatorExtensions
+{
+ public static int Precedence(this Operation op)
+ {
+ switch (op)
+ {
+ case Operation.Add:
+ case Operation.Sub:
+ return 1;
+ case Operation.Mul:
+ case Operation.Div:
+ case Operation.Factorial:
+ return 2;
+ case Operation.PowY:
+ case Operation.SqrtY:
+ return 3;
+ case Operation.Cube:
+ case Operation.Pow:
+ case Operation.Sqrt:
+ case Operation.CubeRoot:
+ case Operation.Square:
+ case Operation.Log:
+ case Operation.Ln:
+ case Operation.Exp:
+ case Operation.Inv:
+ case Operation.Pi:
+ case Operation.OneDiv:
+ case Operation.Mod:
+ case Operation.Neg:
+ case Operation.Percent:
+ case Operation.Sinh:
+ case Operation.Sin:
+ case Operation.Cosh:
+ case Operation.Cos:
+ case Operation.Tanh:
+ case Operation.Tan:
+ return 4;
+ default:
+ case Operation.OpenBracket:
+ case Operation.CloseBracket:
+ return 0;
+ }
+ }
+
+ public static bool IsBigger(this Operation a, Operation b)
+ {
+ return Precedence(a) > Precedence(b);
+ }
+
+ public static bool IsLowerOrEqual(this Operation a, Operation b)
+ {
+ return Precedence(a) <= Precedence(b);
+ }
+}
\ No newline at end of file
diff --git a/Common/Operation.cs b/Common/Operation.cs
index b969da4..b9b187e 100644
--- a/Common/Operation.cs
+++ b/Common/Operation.cs
@@ -28,5 +28,7 @@ public enum Operation
Cosh,
Cos,
Tanh,
- Tan
+ Tan,
+ OpenBracket,
+ CloseBracket
}
\ No newline at end of file
diff --git a/Controller/CaculatorController.cs b/Controller/CaculatorController.cs
index 612b414..7805afc 100644
--- a/Controller/CaculatorController.cs
+++ b/Controller/CaculatorController.cs
@@ -1,5 +1,4 @@
-using calculator.Commands;
-using calculator.Common;
+using calculator.Common;
using calculator.Model;
using calculator.Services;
using calculator.View;
@@ -12,7 +11,6 @@ public class CaculatorController
private readonly IInputService _inputService;
private readonly ICaculatorView _view;
private readonly CaculatorData _data;
- private ICommand? _currentCommand;
public CaculatorController(ICaculator caculator, IInputService inputService, ICaculatorView view,
CaculatorData data)
@@ -32,9 +30,14 @@ public class CaculatorController
private void OnSingleOperationPressed(Operation operation)
{
- OnOperatorPressed(operation);
- _currentCommand = new CalculateCommand(_caculator, _data);
- OnCalculatePressed();
+ if (_data.Values.Count == 0)
+ return;
+
+ if (double.TryParse(_data.Input, out var value) == false)
+ return;
+
+ _data.Values.Push(_caculator.Calculate(operation, value));
+ UpdateView(_data.Values.Peek()!.Value);
}
private void OnClearPressed(bool full)
@@ -42,60 +45,104 @@ public class CaculatorController
Clear(full: full);
}
+ private void Calculate(bool fullAnswer = true)
+ {
+ if (_data.Operations.Count == 0)
+ return;
+
+ if (_data.Values.Count == 0)
+ return;
+
+ if (TryGetValueFromInput() == false)
+ return;
+
+ PerformCalculation(fullAnswer);
+
+ UpdateView(_data.Values.Peek()!.Value);
+ }
+
private void OnCalculatePressed()
{
- if (_data.Operation is null)
- return;
+ Calculate();
+ }
- if (_data.Value is null)
- return;
-
- if (_data is not { Caculated: true, Input: null } || _currentCommand == null)
+ private void PerformCalculation(bool fullAnswer = true)
+ {
+ while (true)
{
- _currentCommand = new CalculateCommand(_caculator, _data);
+ while (_data.Operations.Count > 0 && _data.Operations.Peek() != Operation.OpenBracket)
+ {
+ var b = _data.Values.Pop();
+ var a = _data.Values.Pop();
+ _data.Values.Push(_caculator.Calculate(_data.Operations.Pop(), a!.Value, b!.Value));
+ }
+
+ if (_data.Operations.Count > 0 && _data.Operations.Peek() == Operation.OpenBracket && fullAnswer)
+ {
+ _data.Operations.Pop();
+ }
+
+ if (_data.Operations.Count > 0 && fullAnswer)
+ {
+ continue;
+ }
+
+ break;
}
-
- _currentCommand?.Execute();
- _data.Caculated = true;
- UpdateView(_data.Value.Value);
}
private void Clear(string value = "0", bool full = true)
{
if (full)
{
- _data.Value = null;
- _data.Operation = null;
+ _data.Values.Clear();
+ _data.Operations.Clear();
}
-
- _data.Caculated = false;
+
_data.Input = null;
_view.UpdateView(value);
}
private void OnOperatorPressed(Operation operation)
{
- if (_data.Input == null && _data.Value == null)
- return;
-
- if (_data is { Caculated: false, Input: not null, Value: not null })
+ if (_data.Operations.Count > 0)
{
- OnCalculatePressed();
+ if (operation == Operation.CloseBracket)
+ {
+ Calculate(false);
+ return;
+ }
+
+ if (operation != Operation.OpenBracket && operation.IsLowerOrEqual(_data.Operations.Peek()))
+ {
+ Calculate(false);
+ }
}
- _data.Operation = operation;
+ _data.Operations.Push(operation);
- if (_data.Input != null)
+ TryGetValueFromInput();
+ }
+
+ private bool TryGetValueFromInput()
+ {
+ if (_data.Input is not null)
{
- _data.Value = double.Parse(_data.Input);
+ if (double.TryParse(_data.Input, out var value) == false)
+ {
+ return false;
+ }
+
+ _data.Values.Push(value);
}
_data.Input = null;
+ return true;
}
private void OnOperandPressed(char obj)
{
- if (_data.Caculated)
+ if (_data.Operations.Count == 0 && _data.Input == null)
{
Clear(full: true);
}
diff --git a/Form1.Designer.cs b/Form1.Designer.cs
index 53bd2c3..4087726 100644
--- a/Form1.Designer.cs
+++ b/Form1.Designer.cs
@@ -403,6 +403,7 @@
button23.TabIndex = 35;
button23.Text = ")";
button23.UseVisualStyleBackColor = true;
+ button23.Click += OnCloseBracketButtonClick;
//
// button30
//
@@ -414,6 +415,7 @@
button30.TabIndex = 34;
button30.Text = "(";
button30.UseVisualStyleBackColor = true;
+ button30.Click += OnOpenBracketButtonClick;
//
// Ln_button
//
diff --git a/Form1.cs b/Form1.cs
index 074e7e4..8944a74 100644
--- a/Form1.cs
+++ b/Form1.cs
@@ -221,5 +221,14 @@ namespace calculator
SingleOperatorPressed?.Invoke(Operation.Pi);
}
+ private void OnOpenBracketButtonClick(object? sender, EventArgs e)
+ {
+ OperatorPressed?.Invoke(Operation.OpenBracket);
+ }
+
+ private void OnCloseBracketButtonClick(object? sender, EventArgs e)
+ {
+ OperatorPressed?.Invoke(Operation.CloseBracket);
+ }
}
}
\ No newline at end of file
diff --git a/Model/CaculatorData.cs b/Model/CaculatorData.cs
index ddcd271..87e12c5 100644
--- a/Model/CaculatorData.cs
+++ b/Model/CaculatorData.cs
@@ -5,7 +5,6 @@ namespace calculator.Model;
public class CaculatorData
{
public string? Input { get; set; }
- public double? Value { get; set; }
- public Operation? Operation { get; set; }
- public bool Caculated { get; set; }
+ public Stack Values { get; set; } = new();
+ public Stack Operations { get; set; } = new();
}
\ No newline at end of file