This commit is contained in:
2026-01-10 20:52:44 +01:00
parent 1f6e9ce376
commit 4a418ddf75
10 changed files with 849 additions and 1 deletions

View File

@@ -0,0 +1,39 @@
namespace Lunar.Evil_Calculator
{
partial class CalculatorBody
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "CalculatorBody";
}
#endregion
}
}

View File

@@ -0,0 +1,274 @@
namespace Lunar.Evil_Calculator
{
public partial class CalculatorBody : Form
{
private bool mouseDown;
private bool onTop;
private Point lastLocation;
private static Color LunarGray = System.Drawing.ColorTranslator.FromHtml("#2b292d");
private static Color LunarOrange = System.Drawing.ColorTranslator.FromHtml("#ff8700");
private Form CalculatorPanel = new Form();
private EquationManager equationManager = new EquationManager();
public CalculatorBody()
{
InitializeComponent();
this.BackColor = LunarGray;
this.Opacity = 0.75;
this.FormBorderStyle = FormBorderStyle.None;
this.ClientSize = new Size(300, 500);
this.Text = "Calculator";
MyTitleBar();
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
CalculatorPanelInit();
}
protected override void OnMove(EventArgs e)
{
base.OnMove(e);
if (OwnedForms.Length > 0)
{
var p = PointToScreen(new Point(0, 30));
var dx = p.X - OwnedForms[0].Location.X;
var dy = p.Y - OwnedForms[0].Location.Y;
foreach (var f in OwnedForms)
f.Location = new Point(f.Location.X + dx, f.Location.Y + dy);
}
}
private void MyTitleBar()
{
Panel TitleBar = new Panel
{
Height = 30,
Dock = DockStyle.Top,
Visible = true
};
TitleBar.MouseDown += TitleBar_MouseDown;
TitleBar.MouseMove += TitleBar_MouseMove;
TitleBar.MouseUp += TitleBar_MouseUp;
this.Controls.Add(TitleBar);
Button ButtonMinimize = new Button
{
Text = "_",
Width = 40,
Height = TitleBar.Height,
Dock = DockStyle.Right,
FlatStyle = FlatStyle.Flat,
ForeColor = Color.White
};
ButtonMinimize.FlatAppearance.BorderSize = 0;
ButtonMinimize.FlatAppearance.BorderColor = LunarGray;
ButtonMinimize.Click += (s, e) => this.WindowState = FormWindowState.Minimized;
TitleBar.Controls.Add(ButtonMinimize);
Button ButtonMaximize = new Button
{
Text = "□",
Width = 40,
Height = TitleBar.Height,
Dock = DockStyle.Right,
FlatStyle = FlatStyle.Flat,
ForeColor = Color.White
};
ButtonMaximize.FlatAppearance.BorderSize = 0;
ButtonMaximize.FlatAppearance.BorderColor = LunarGray;
ButtonMaximize.Click += (s, e) =>
{
this.WindowState = (this.WindowState == FormWindowState.Normal) ? FormWindowState.Maximized : FormWindowState.Normal;
};
TitleBar.Controls.Add(ButtonMaximize);
Button ButtonClose = new Button
{
Text = "X",
Width = 40,
Height = TitleBar.Height,
Dock = DockStyle.Right,
FlatStyle = FlatStyle.Flat,
ForeColor = Color.White
};
ButtonClose.FlatAppearance.BorderSize = 0;
ButtonClose.FlatAppearance.BorderColor = LunarGray;
ButtonClose.Click += (s, e) => this.Close();
TitleBar.Controls.Add(ButtonClose);
Label titleLabel = new Label
{
Text = this.Text,
Location = new Point(8, 7),
AutoSize = true,
ForeColor = Color.White
};
TitleBar.Controls.Add(titleLabel);
void TitleBar_MouseDown(object? sender, MouseEventArgs e)
{
mouseDown = true;
lastLocation = e.Location;
}
void TitleBar_MouseMove(object? sender, MouseEventArgs e)
{
if (mouseDown)
{
this.Location = new Point(
(this.Location.X - lastLocation.X) + e.X, (this.Location.Y - lastLocation.Y) + e.Y);
this.Update();
}
}
void TitleBar_MouseUp(object? sender, MouseEventArgs e)
{
mouseDown = false;
}
void Titlebar_BaseTextChanged(object? sender, EventArgs e)
{
titleLabel.Text = this.Text;
}
this.TextChanged += Titlebar_BaseTextChanged;
}
private void CalculatorPanelInit()
{
CalculatorPanel.FormBorderStyle = FormBorderStyle.None;
CalculatorPanel.BackColor = Color.Gray;
CalculatorPanel.TransparencyKey = CalculatorPanel.BackColor;
CalculatorPanel.Opacity = 0.90;
CalculatorPanel.StartPosition = FormStartPosition.Manual;
CalculatorPanel.DesktopLocation = new Point(this.Location.X, this.Location.Y + 30);
CalculatorPanel.ClientSize = new Size(this.Size.Width, this.Size.Height - 30);
CalculatorPanel.Owner = this;
CalculatorPanel.ShowInTaskbar = false;
CalculatorButton buttonZero = new CalculatorButton("0", new Point(90, 410), CalculatorPanel, equationManager);
CalculatorButton buttonOne = new CalculatorButton("1", new Point(20, 360), CalculatorPanel, equationManager);
CalculatorButton buttonTwo = new CalculatorButton("2", new Point(90, 360), CalculatorPanel, equationManager);
CalculatorButton buttonThree = new CalculatorButton("3", new Point(160, 360), CalculatorPanel, equationManager);
CalculatorButton buttonFour = new CalculatorButton("4", new Point(20, 310), CalculatorPanel, equationManager);
CalculatorButton buttonFive = new CalculatorButton("5", new Point(90, 310), CalculatorPanel, equationManager);
CalculatorButton buttonSix = new CalculatorButton("6", new Point(160, 310), CalculatorPanel, equationManager);
CalculatorButton buttonSeven = new CalculatorButton("7", new Point(20, 260), CalculatorPanel, equationManager);
CalculatorButton buttonEight = new CalculatorButton("8", new Point(90, 260), CalculatorPanel, equationManager);
CalculatorButton buttonNine = new CalculatorButton("9", new Point(160, 260), CalculatorPanel, equationManager);
CalculatorButton buttonLeftBracket = new CalculatorButton("(", new Point(160, 160), CalculatorPanel, equationManager);
CalculatorButton buttonRightBracket = new CalculatorButton(")", new Point(230, 160), CalculatorPanel, equationManager);
CalculatorButton buttonClear = new CalculatorButton("C", new Point(20, 160), CalculatorPanel, equationManager);
CalculatorButton buttonClearEverything = new CalculatorButton("CE", new Point(90, 160), CalculatorPanel, equationManager);
CalculatorButton buttonPowerX = new CalculatorButton("xˣ", new Point(20, 210), CalculatorPanel, equationManager);
CalculatorButton buttonPowerTwo = new CalculatorButton("x²", new Point(90, 210), CalculatorPanel, equationManager);
CalculatorButton buttonSquareRoot = new CalculatorButton("√", new Point(160, 210), CalculatorPanel, equationManager);
CalculatorButton buttonDivide = new CalculatorButton("/", new Point(230, 210), CalculatorPanel, equationManager);
CalculatorButton buttonMultiply = new CalculatorButton("*", new Point(230, 260), CalculatorPanel, equationManager);
CalculatorButton buttonMinus = new CalculatorButton("-", new Point(230, 310), CalculatorPanel, equationManager);
CalculatorButton buttonPlus = new CalculatorButton("+", new Point(230, 360), CalculatorPanel, equationManager);
CalculatorButton buttonComma = new CalculatorButton(",", new Point(160, 410), CalculatorPanel, equationManager);
EqualsButton equalsButton = new EqualsButton(new Point(230, 410), CalculatorPanel, equationManager);
ToggleTopButton toggleTopButton = new ToggleTopButton(new Point(20, 410), CalculatorPanel);
toggleTopButton.Click += ToggleTopButton_Click;
Label equationTextBox = new Label();
equationTextBox.Location = new Point(20, 20);
equationTextBox.ClientSize = new Size(260, 80);
equationTextBox.TextAlign = ContentAlignment.TopRight;
equationTextBox.Font = new Font("Arial", 16);
equationTextBox.ForeColor = Color.White;
CalculatorPanel.Controls.Add(equationTextBox);
Label currentOperandTextBox = new Label();
currentOperandTextBox.Text = "0";
currentOperandTextBox.Location = new Point(20, 100);
currentOperandTextBox.ClientSize = new Size(260, 30);
currentOperandTextBox.TextAlign = ContentAlignment.TopRight;
currentOperandTextBox.Font = new Font("Arial", 20);
currentOperandTextBox.ForeColor = Color.White;
CalculatorPanel.Controls.Add(currentOperandTextBox);
equationManager.AcquireOutputLabels(ref equationTextBox, ref currentOperandTextBox);
CalculatorPanel.Show();
void ToggleTopButton_Click(object? sender, EventArgs e)
{
this.Text = this.onTop ? "Calculator" : "Calculator [pinned]";
this.onTop = !this.onTop;
this.TopMost = !this.TopMost;
CalculatorPanel.TopMost = !CalculatorPanel.TopMost;
}
}
private class CalculatorButton : Button
{
public CalculatorButton(string Text, Point Location, Form Panel, EquationManager equationManager)
{
this.Text = Text;
this.Font = new Font("Arial", 12);
this.Location = Location;
this.Width = 50;
this.Height = 40;
this.FlatStyle = FlatStyle.Flat;
this.BackColor = LunarGray;
this.FlatAppearance.BorderSize = 0;
this.FlatAppearance.BorderColor = LunarGray;
ForeColor = Color.White;
this.Click += equationManager.ProcessButtonInput;
Panel.Controls.Add(this);
}
}
private class EqualsButton : Button
{
public EqualsButton(Point Location, Form Panel, EquationManager equationManager)
{
this.Text = "=";
this.Font = new Font("Arial", 12);
this.Location = Location;
this.Width = 50;
this.Height = 40;
this.FlatStyle = FlatStyle.Flat;
this.BackColor = LunarOrange;
this.FlatAppearance.BorderSize = 0;
this.FlatAppearance.BorderColor = LunarOrange;
ForeColor = Color.White;
this.Click += equationManager.EqualsButtonPressed;
Panel.Controls.Add(this);
}
}
private class ToggleTopButton : Button
{
public ToggleTopButton(Point Location, Form Panel)
{
this.Text = "Toggle\ntop";
this.Font = new Font("Arial", 7);
this.Location = Location;
this.Width = 50;
this.Height = 40;
this.FlatStyle = FlatStyle.Flat;
this.BackColor = LunarGray;
this.FlatAppearance.BorderSize = 0;
this.FlatAppearance.BorderColor = LunarGray;
ForeColor = Color.White;
Panel.Controls.Add(this);
}
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,203 @@
namespace Lunar.Evil_Calculator
{
class EquationManager
{
private ReverseNotationSolver reverseNotationSolver = new ReverseNotationSolver();
List<Token> equation = new List<Token>();
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)
{
Button? buttonPressed = sender as Button;
if (buttonPressed != null)
{
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)
{
Button? buttonEquals = sender as Button;
if (buttonEquals != null)
{
if (currentOperand != "") equation.Add(new Token(Token.TokenType.Operand, currentOperand));
buttonEquals.Text = "#";
this.currentOperand = reverseNotationSolver.Solve(ref equation);
UpdateLabels();
}
}
public void AcquireOutputLabels(ref Label equationTextBox, ref Label currentOperandTextBox)
{
this.outerEquationLabel = equationTextBox;
this.outerOperandLabel = currentOperandTextBox;
}
public string equationToString()
{
string equationString = "";
foreach (Token token in equation)
{
equationString += token.value.ToString() + " ";
}
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;
}
}
}

View File

@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<RootNamespace>Lunar.Evil_Calculator</RootNamespace>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,12 @@
namespace Lunar.Evil_Calculator
{
internal static class Program
{
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new CalculatorBody());
}
}
}

View File

@@ -0,0 +1,116 @@
namespace Lunar.Evil_Calculator
{
internal class ReverseNotationSolver
{
List<Token> equation = new List<Token>();
public string? ToReverseNotation(ref List<Token> equation)
{
List<Token> TEMP = new List<Token>();
Stack<Token> OPERATORS = new Stack<Token>();
foreach (Token token in equation)
{
if (token.tokenType == Token.TokenType.Operand)
{
TEMP.Add(token);
}
if (token.tokenType == Token.TokenType.Operator)
{
if (token.value == "(")
{
OPERATORS.Push(token);
}
else if (token.value == ")")
{
while (OPERATORS.Peek().value != "(")
{
TEMP.Add(OPERATORS.Pop());
}
OPERATORS.Pop();
}
else
{
while (OPERATORS.Count != 0 ? OPERATORS.Peek().priority >= token.priority : false)
{
TEMP.Add(OPERATORS.Pop());
}
OPERATORS.Push(token);
}
}
}
while (OPERATORS.Count != 0)
{
TEMP.Add(OPERATORS.Pop());
}
this.equation = TEMP;
return equationToString();
}
public string? Solve(ref List<Token> equation)
{
ToReverseNotation(ref equation);
Stack<Token> stack = new Stack<Token>();
foreach (Token token in this.equation)
{
double result, left, right;
if (token.tokenType == Token.TokenType.Operand)
{
stack.Push(token);
}
if (token.tokenType == Token.TokenType.Operator)
{
switch (token.value)
{
case "+":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = left + right;
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
case "-":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = left - right;
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
case "*":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = left * right;
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
case "/":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = left / right;
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
case "^":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = Math.Pow(left, right);
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
}
}
}
return stack.Pop().value;
}
public string equationToString()
{
string equationString = "";
foreach (Token token in this.equation)
{
equationString += token.value.ToString() + " ";
}
return equationString;
}
}
}

25
Evil Calculator/Token.cs Normal file
View File

@@ -0,0 +1,25 @@
namespace Lunar.Evil_Calculator
{
internal class Token
{
public enum TokenType { Operator, Operand };
public TokenType tokenType;
public string value = "";
public int? priority;
public Token() { }
public Token(TokenType tokenType, string value)
{
this.tokenType = tokenType;
this.value = value;
}
public Token(TokenType tokenType, string value, int priority)
{
this.tokenType = tokenType;
this.value = value;
this.priority = priority;
}
}
}