C# Expression Calculator

I have usually written all my programs in C++. Now, however, I decided to try out C#. I've heard a lot of great stuff about it. The first thing I tried out, was a windows forms expression calculator. The calculator first uses the Shunting-Yard algorithm to parse the inputted expression into Reverse Polish Notation, then use several stack methods to to calculate the final result. A snippet of the source code:

  Stack<string> output = new Stack<string>();
string refr = "";
double num1 = 0;
double num2 = 0;
public Form1()
{
InitializeComponent();
}
private void outpush(string val , bool more )
{
if(!more)
{
output.Push(val+" ");
}
else
{
output.Push(val);
}
}
private void button1_Click(object sender, EventArgs e)
{
Stack<char> oper = new Stack<char>();
char[] exp = richTextBox1.Text.Replace(" ","").ToCharArray();
refr = "";
for(int i = 0; i < exp.Count(); i++)
{
if(Char.IsNumber(exp[i]))
{
if(exp.Count()-1 > i && Char.IsNumber(exp[i+1]))
{
outpush(Convert.ToString(exp[i]), true);
}
else
{
outpush(Convert.ToString(exp[i]), false);
}
}
else switch(exp[i])
{
case '+':
if(oper.Count()>0)
{
if (oper.ToArray()[0] == '*' || oper.ToArray()[0] == '/' || oper.ToArray()[0] == '^')
{
outpush(Convert.ToString(oper.Pop()), false);
}
}
oper.Push(exp[i]);
break;

case '-':
if (oper.Count() > 0)
{
if (oper.ToArray()[0] == '*' || oper.ToArray()[0] == '/' || oper.ToArray()[0] == '^')
{
outpush(Convert.ToString(oper.Pop()), false);
}
}
oper.Push(exp[i]);
break;

case '-':
if (oper.Count() > 0)
{
if (oper.ToArray()[0] == '*' || oper.ToArray()[0] == '/' || oper.ToArray()[0] == '^')
{
outpush(Convert.ToString(oper.Pop()), false);
}
}
oper.Push(exp[i]);
break;

case '*':
if (oper.Count() > 0)
{
if (oper.ToArray()[0] == '*' || oper.ToArray()[0] == '/' || oper.ToArray()[0] == '^')
{
outpush(Convert.ToString(oper.Pop()), false);
}
}
oper.Push(exp[i]);
break;

case '/':
if (oper.Count() > 0)
{
if (oper.ToArray()[0] == '*' || oper.ToArray()[0] == '/' || oper.ToArray()[0] == '^')
{
outpush(Convert.ToString(oper.Pop()), false);
}
}
oper.Push(exp[i]);
break;

case '(':
oper.Push(exp[i]);
break;

case ')':
int count2 = oper.Count();
if (oper.Count() > 0)
{
while(oper.ToArray()[0] != '(')
{
outpush(Convert.ToString(oper.Pop()), false);
}
}
if (oper.Count() == 0) { goto errorlp; }
oper.Pop();
break;

case '^':
oper.Push(exp[i]);
break;

default:
break;
}
}
int count = oper.Count();
for(int i = 0; i < count; i++)
{
outpush(Convert.ToString(oper.Pop()), false);
}
int counto = output.Count();
for(int i = 0; i < counto; i++)
{
refr = output.Pop() + refr;
}

string[] input = refr.Split(' ');

Stack<double> numbers = new Stack<double>();
for(int i = 0; i < input.Count(); i++)
{
if(input[i] != ""){
if(Char.IsNumber(input[i],0))
{
numbers.Push(Convert.ToDouble(input[i]));
}
else switch(input[i])
{
case "+":
if (numbers.Count() < 2) { goto errornum; }
num1 = numbers.Pop();
num2 = numbers.Pop();
numbers.Push(num2 + num1);
break;

case "-":
if (numbers.Count() < 2) { goto errornum; }
num1 = numbers.Pop();
num2 = numbers.Pop();
numbers.Push(num2-num1);
break;

case "-":
if (numbers.Count() < 2) { goto errornum; }
num1 = numbers.Pop();
num2 = numbers.Pop();
numbers.Push(num2-num1);
break;

case "*":
if (numbers.Count() < 2) { goto errornum; }
num1 = numbers.Pop();
num2 = numbers.Pop();
numbers.Push(num2*num1);
break;

case "/":
if (numbers.Count() < 2) { goto errornum; }
num1 = numbers.Pop();
num2 = numbers.Pop();
numbers.Push(num2/num1);
break;


case "^":
if (numbers.Count() < 2) { goto errornum; }
num1 = numbers.Pop();
num2 = numbers.Pop();
numbers.Push(Math.Pow(num2,num1));
break;
}
}
}
if (numbers.Count() != 1) { goto errornum; }
richTextBox1.Text = Convert.ToString(numbers.Pop());

goto Ends;

errorlp:
richTextBox1.Text = "Error!\nMissing left parenthesis!";
goto Ends;

Errorrp:
richTextBox1.Text = "Error!\nMissing right parenthesis!";
goto Ends;

errornum:
richTextBox1.Text = "Error!\nNumber count does not equal operator count!";

Ends:
num1 = 0;



And here's an image of the calculator interface:

0 comments: