Skip to content

Instantly share code, notes, and snippets.

@DreamVB
Created October 15, 2021 10:05
Show Gist options
  • Save DreamVB/94d0e42233f552da7e10749e8598a50b to your computer and use it in GitHub Desktop.
Save DreamVB/94d0e42233f552da7e10749e8598a50b to your computer and use it in GitHub Desktop.
rpn calculator class with variables and functions
using System;
using System.Windows.Forms;
using DreamVB.RPNCalulator;
namespace RPNTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
clsRpn calc = new clsRpn();
calc.SetVariable("ten", 10);
MessageBox.Show(calc.Eval("%ten 50 +").ToString());
MessageBox.Show(calc.Eval("5 5 * 5 +").ToString());
MessageBox.Show(calc.Eval("#PI").ToString());
MessageBox.Show(calc.Eval("#e").ToString());
MessageBox.Show(calc.Eval("9 sqr").ToString());
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RPNCalulator
{
public class clsRpn
{
private Dictionary<string, double> Vars = new Dictionary<string, double>();
private bool IsOperator(char c)
{
bool isOp = false;
switch (c)
{
case '+':
isOp = true;
break;
case '-':
isOp = true;
break;
case '/':
isOp = true;
break;
case '*':
isOp = true;
break;
case '^':
isOp = true;
break;
}
return isOp;
}
public void SetVariable(string vName, double value)
{
if (Vars.ContainsKey(vName))
{
Vars[vName] = value;
}
else
{
Vars.Add(vName, value);
}
}
public bool VariableExists(string vName)
{
return Vars.ContainsKey(vName);
}
public double Eval(string expression)
{
Stack<double> stk = new Stack<double>();
double number = 0;
string token = string.Empty;
string[] _parts = expression.Split(' ');
int x = 0;
//Used for calulations
double d1 = 0;
double d2 = 0;
while (x < _parts.Length)
{
token = _parts[x].Trim();
if (token.Length > 0)
{
if (double.TryParse(token, out number))
{
stk.Push(double.Parse(token));
}
else if (IsOperator(token[0]))
{
//Check stack count
if (!(stk.Count >= 2))
{
throw new Exception("Stack Underflow.");
}
else
{
//Pop off the values on the stack
d2 = stk.Pop();
d1 = stk.Pop();
switch (token[0])
{
case '+':
stk.Push(d1 + d2);
break;
case '-':
stk.Push(d1 - d2);
break;
case '/':
if (d2 == 0.0)
{
throw new Exception("Divisn By Zero.");
}
else
{
stk.Push(d1 / d2);
}
break;
case '*':
stk.Push(d1 * d2);
break;
case '^':
stk.Push(Math.Pow(d1, d2));
break;
}
}
}
//Check for variable
else if (token.StartsWith("%"))
{
//Remove % from the left side
token = token.Remove(0, 1);
//Check if variable found
if (!VariableExists(token))
{
throw new Exception("Variable Not Found.");
}
else
{
//Push variable value
stk.Push(Vars[token]);
}
}
//Check for consts
else if (token.StartsWith("#"))
{
//Remove const sign
token = token.Remove(0,1).ToUpper();
switch (token)
{
case "PI":
stk.Push(Math.PI);
break;
case "E":
stk.Push(Math.E);
break;
default:
throw new Exception("Unknown Const Token.");
}
}else
{
//Process in-built functions
switch (token.ToUpper())
{
case "ABS":
stk.Push(Math.Abs(stk.Pop()));
break;
case "CEIL":
stk.Push(Math.Ceiling(stk.Pop()));
break;
case "EXP":
stk.Push(Math.Exp(stk.Pop()));
break;
case "POW":
d2 = stk.Pop();
d1 = stk.Pop();
stk.Push(Math.Pow(d1, d2));
break;
case "SIN":
stk.Push(Math.Sin(stk.Pop() / (180.0 / Math.PI)));
break;
case "COS":
stk.Push(Math.Cos(stk.Pop() / (180.0 / Math.PI)));
break;
case "LN":
stk.Push(Math.Log(stk.Pop()));
break;
case "SQRT":
stk.Push(Math.Sqrt(stk.Pop()));
break;
case "FLOOR":
stk.Push(Math.Floor(stk.Pop()));
break;
case "TAN":
stk.Push(Math.Tan(stk.Pop() / (180.0 / Math.PI)));
break;
case "SQR":
d1 = stk.Pop();
//Calc sqr root
for (int y = 1; y <= d1; y++)
{
d2 = (y * d1);
}
//Push value on stack
stk.Push(d2);
break;
case "MIN":
d2 = stk.Pop();
d1 = stk.Pop();
stk.Push(Math.Min(d1, d2));
break;
case "MAX":
d2 = stk.Pop();
d1 = stk.Pop();
stk.Push(Math.Max(d1, d2));
break;
case "INT":
stk.Push(Convert.ToInt32(stk.Pop()));
break;
case "LOG":
stk.Push(Math.Log(stk.Pop()));
break;
default:
throw new Exception("Unknown Function Token.");
}
}
}
x++;
}
try
{
return stk.Pop();
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment