I don't remember what changed here but I believe the core logic for parsing the math expression was updated to be 'better', perhaps more 'robust'. I don't think you can really call it that though considering it doesn't even make use of a syntax tree of any kind at the very least.
This commit is contained in:
+234
-352
@@ -6,17 +6,14 @@ using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Engine
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
//Invert over all expression (i + 7) ^ 2 -> -(i + 7) ^ 2
|
||||
|
||||
private Stack<Node> Tree = new Stack<Node>();
|
||||
private Dictionary<string, double> Symbols = new Dictionary<string, double>();
|
||||
private Dictionary<string, double> Symbols { get; set; } = new Dictionary<string, double>();
|
||||
|
||||
public Form1()
|
||||
{
|
||||
@@ -31,37 +28,8 @@ namespace Engine
|
||||
f.Reverse();
|
||||
var stack = new Stack<Token>(f);
|
||||
ActionsListView.Items.Clear();
|
||||
|
||||
button1.Text = "Result: " + NewCalc(stack);
|
||||
//var f2 = GetSubExpressions(f);
|
||||
//PrintSteps(f2);
|
||||
//PrintSymbolsTable();
|
||||
//var result = Calc(f2);
|
||||
//button1.Text = $"Result: {result}";
|
||||
//var result = Calc(FlattenInput(s));
|
||||
}
|
||||
|
||||
void PrintSteps(List<List<Node>> expressions)
|
||||
{
|
||||
StepsListView.Items.Clear();
|
||||
|
||||
for(var i = 0; i < expressions.Count; i++)
|
||||
{
|
||||
var expression = expressions[i];
|
||||
var item = new ListViewItem($"Step {i + 1}");
|
||||
var ex = string.Empty;
|
||||
|
||||
foreach (var token in expression)
|
||||
{
|
||||
if (!token.IsCoefficent)
|
||||
ex += token.Value + " ";
|
||||
else
|
||||
ex += token.Value;
|
||||
}
|
||||
|
||||
item.SubItems.Add(ex);
|
||||
StepsListView.Items.Add(item);
|
||||
}
|
||||
PrintSymbolsTable();
|
||||
button1.Text = "Result: " + HandleAddAndSub(stack);
|
||||
}
|
||||
|
||||
void PrintSymbolsTable()
|
||||
@@ -84,274 +52,264 @@ namespace Engine
|
||||
foreach(var token in tokens)
|
||||
{
|
||||
var item = new ListViewItem(token.Value);
|
||||
if(!token.IsCoefficent) item.SubItems.Add(token.Type.ToString());
|
||||
else item.SubItems.Add(token.Type.ToString() + " (Coefficent)");
|
||||
item.SubItems.Add(token.Type.ToString());
|
||||
|
||||
ExpressionBreakdownListView.Items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
double NewCalc(Stack<Token> tokens, double co = 1)
|
||||
double HandleParenthesis(Stack<Token> tokens, bool callerHasPriority = false)
|
||||
{
|
||||
var previousToken = new Token() { Type = TokenType.Unknown };
|
||||
var runningValue = 0d;
|
||||
var previousToken = new Token() { Type = TokenType.Unknown };
|
||||
|
||||
while(tokens.Count > 0)
|
||||
for(; ;)
|
||||
{
|
||||
var token = tokens.Pop();
|
||||
if (tokens.Count == 0) break;
|
||||
|
||||
if (token.Type == TokenType.ExpEnd)
|
||||
var currentToken = tokens.Pop();
|
||||
|
||||
if(currentToken.Type == TokenType.Constant)
|
||||
{
|
||||
previousToken = currentToken;
|
||||
continue;
|
||||
}
|
||||
else if(currentToken.Type == TokenType.ExpStart)
|
||||
{
|
||||
var tmp = HandleParenthesis(tokens);
|
||||
runningValue = tmp;
|
||||
}
|
||||
else if(currentToken.Type == TokenType.Add || currentToken.Type == TokenType.Subtract)
|
||||
{
|
||||
var lookAHead = tokens.Pop();
|
||||
|
||||
if(lookAHead.Type == TokenType.ExpStart)
|
||||
{
|
||||
var tmp = HandleParenthesis(tokens);
|
||||
|
||||
if (runningValue == 0) runningValue = Operate(Convert.ToDouble(previousToken.Value), tmp, currentToken.Type);
|
||||
else runningValue = Operate(runningValue, tmp, currentToken.Type);
|
||||
continue;
|
||||
}
|
||||
|
||||
tokens.Push(lookAHead);
|
||||
tokens.Push(currentToken);
|
||||
if (previousToken.Type != TokenType.Unknown) tokens.Push(previousToken);
|
||||
else tokens.Push(new Token { Type = TokenType.Constant, Value = runningValue.ToString() });
|
||||
runningValue = HandleAddAndSub(tokens);
|
||||
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
}
|
||||
else if (currentToken.Type == TokenType.Power)
|
||||
{
|
||||
var lookAHead = tokens.Pop();
|
||||
|
||||
if(lookAHead.Type == TokenType.ExpStart)
|
||||
{
|
||||
var powerOf = HandleParenthesis(tokens, true);
|
||||
|
||||
runningValue = Operate(Convert.ToDouble(previousToken.Value), powerOf, currentToken.Type);
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var tmp = Operate(Convert.ToDouble(previousToken.Value), Convert.ToDouble(lookAHead.Value), currentToken.Type);
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
|
||||
runningValue = tmp;
|
||||
}
|
||||
else if (currentToken.Type == TokenType.Multiply || currentToken.Type == TokenType.Divide)
|
||||
{
|
||||
var lookAHead = tokens.Peek();
|
||||
|
||||
if (lookAHead.Type == TokenType.ExpStart)
|
||||
{
|
||||
tokens.Pop();
|
||||
|
||||
var tmpe = Operate(Convert.ToDouble(previousToken.Value), HandleParenthesis(tokens), currentToken.Type);
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
|
||||
runningValue = tmpe;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tokens.Push(currentToken);
|
||||
if (previousToken.Type != TokenType.Unknown) tokens.Push(previousToken);
|
||||
else tokens.Push(new Token { Type = TokenType.Constant, Value = runningValue.ToString() });
|
||||
|
||||
var tmp = HandleMultAndDiv(tokens);
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
|
||||
runningValue = tmp;
|
||||
}
|
||||
else if (currentToken.Type == TokenType.ExpEnd)
|
||||
{
|
||||
if(tokens.Count > 0 && tokens.Peek().Type == TokenType.Power)
|
||||
{
|
||||
var op = tokens.Pop();
|
||||
var powerOf = tokens.Pop();
|
||||
//Pop the power of token before returning.
|
||||
tokens.Pop();
|
||||
runningValue = Operate(runningValue, Convert.ToDouble(tokens.Pop().Value), TokenType.Power);
|
||||
}
|
||||
|
||||
if(powerOf.Type == TokenType.Constant)
|
||||
if(!callerHasPriority && tokens.Count > 0 && (tokens.Peek().Type == TokenType.Multiply || tokens.Peek().Type == TokenType.Divide))
|
||||
{
|
||||
var op = tokens.Pop();
|
||||
var twoAHead = tokens.Pop();
|
||||
|
||||
if(twoAHead.Type == TokenType.ExpStart)
|
||||
{
|
||||
ActionsListView.Items.Add($"Taking {runningValue} to the power of {powerOf.Value}.");
|
||||
runningValue = Operate(runningValue, Convert.ToDouble(powerOf.Value), op.Type);
|
||||
runningValue = Operate(runningValue, HandleParenthesis(tokens, true), op.Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
runningValue = Operate(runningValue, Convert.ToDouble(twoAHead.Value), op.Type);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(token.Type == TokenType.ExpStart)
|
||||
{
|
||||
runningValue = NewCalc(tokens);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(token.IsCoefficent)
|
||||
{
|
||||
var lookAHead = tokens.Pop();
|
||||
|
||||
if (lookAHead.Type == TokenType.Variable)
|
||||
{
|
||||
ActionsListView.Items.Add($"{token.Value} is a coeffiecent, multiplying it against {Symbols[lookAHead.Value]} (Symbol '{lookAHead.Value}').");
|
||||
runningValue += Convert.ToDouble(token.Value) * Symbols[lookAHead.Value];
|
||||
if (previousToken.Type != TokenType.Unknown) throw new Exception("Token shouldn't have a valid value!");
|
||||
//2a(
|
||||
if(tokens.Count != 0 && tokens.Peek().Type == TokenType.ExpStart)
|
||||
{
|
||||
runningValue += NewCalc(tokens, runningValue);
|
||||
}
|
||||
|
||||
previousToken = new Token() { Type = TokenType.Constant, Value = runningValue.ToString(), IsCoefficent = false };
|
||||
continue;
|
||||
}
|
||||
else if (lookAHead.Type == TokenType.ExpStart)
|
||||
{
|
||||
runningValue += NewCalc(tokens, Convert.ToDouble(token.Value));
|
||||
previousToken = new Token() { Type = TokenType.Constant, Value = runningValue.ToString(), IsCoefficent = false };
|
||||
continue;
|
||||
}
|
||||
else throw new Exception("Invalid grammar!");
|
||||
}
|
||||
//If token is an operator
|
||||
if(GetOperator(token.Value[0]) != TokenType.Unknown)
|
||||
{
|
||||
//Operator found
|
||||
var lookAHead = tokens.Pop();
|
||||
|
||||
if(lookAHead.Type == TokenType.Constant && !lookAHead.IsCoefficent)
|
||||
{
|
||||
var tmpValue = 0d;
|
||||
|
||||
while (tokens.Count > 0 && (tokens.Peek().Type == TokenType.Multiply || tokens.Peek().Type == TokenType.Divide || tokens.Peek().Type == TokenType.Power))
|
||||
{
|
||||
var op = tokens.Pop();
|
||||
|
||||
if (op.Type != TokenType.Power)
|
||||
{
|
||||
var next = tokens.Pop();
|
||||
|
||||
if (next.Type == TokenType.ExpStart)
|
||||
{
|
||||
var returnValue = NewCalc(tokens);
|
||||
|
||||
if (tmpValue != 0)
|
||||
{
|
||||
ActionsListView.Items.Add($"{GetOperatorVerb(op.Type)} {tmpValue} (tmp) and {returnValue} (returnValue).");
|
||||
tmpValue = Operate(tmpValue, returnValue, op.Type);
|
||||
lookAHead.Value = tmpValue.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
ActionsListView.Items.Add($"{GetOperatorVerb(op.Type)} {Convert.ToDouble(lookAHead.Value) * co} (lookAHead) and {returnValue} (returnValue).");
|
||||
tmpValue = Operate(Convert.ToDouble(lookAHead.Value) * co, returnValue, op.Type);
|
||||
lookAHead.Value = tmpValue.ToString();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tmpValue != 0)
|
||||
{
|
||||
ActionsListView.Items.Add($"{GetOperatorVerb(op.Type)} {tmpValue} (tmp) and {Convert.ToDouble(next.Value) * co} (next).");
|
||||
tmpValue = Operate(tmpValue, Convert.ToDouble(next.Value) * co, op.Type);
|
||||
lookAHead.Value = tmpValue.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
ActionsListView.Items.Add($"{GetOperatorVerb(op.Type)} {Convert.ToDouble(lookAHead.Value) *co} (lookAHead) and {next.Value} (next).");
|
||||
tmpValue = Operate(Convert.ToDouble(lookAHead.Value) *co, Convert.ToDouble(next.Value) *co, op.Type);
|
||||
lookAHead.Value = tmpValue.ToString();
|
||||
}
|
||||
}
|
||||
else if (op.Type == TokenType.Power)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//if(tokens.Count > 0 && (tokens.Peek().Type == TokenType.Divide || tokens.Peek().Type == TokenType.Multiply || tokens.Peek().Type == TokenType.Power))
|
||||
//{
|
||||
// var op = tokens.Pop();
|
||||
// var con = tokens.Pop();
|
||||
// //TODO: check if "con" is a variable, right now we're assuming its a constant.
|
||||
// ActionsListView.Items.Add($"{GetOperatorVerb(op.Type)} {Convert.ToDouble(lookAHead.Value) * co} and {Convert.ToDouble(con.Value) * co} (Oder of Operations).");
|
||||
// var tmp = Operate(Convert.ToDouble(lookAHead.Value) * co, Convert.ToDouble(con.Value) * co, op.Type);
|
||||
|
||||
// ActionsListView.Items.Add($"{GetOperatorVerb(token.Type)} {Convert.ToDouble(previousToken.Value) * co} and {tmp}.");
|
||||
// runningValue += Operate(Convert.ToDouble(previousToken.Value) * co, tmp, token.Type);
|
||||
// previousToken = new Token { Type = TokenType.Unknown };
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
if (previousToken.Type != TokenType.Unknown)
|
||||
{
|
||||
ActionsListView.Items.Add($"{GetOperatorVerb(token.Type)} {Convert.ToDouble(previousToken.Value) * co} and {Convert.ToDouble(lookAHead.Value) * co}.");
|
||||
runningValue += Operate(Convert.ToDouble(previousToken.Value) * co, Convert.ToDouble(lookAHead.Value) * co, token.Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
ActionsListView.Items.Add($"{GetOperatorVerb(token.Type)} {runningValue} and {Convert.ToDouble(lookAHead.Value) * co}.");
|
||||
runningValue = Operate(runningValue, Convert.ToDouble(lookAHead.Value) * co, token.Type);
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
else if(token.Type == TokenType.Constant)
|
||||
{
|
||||
previousToken = token;
|
||||
}
|
||||
}
|
||||
|
||||
return runningValue;
|
||||
}
|
||||
|
||||
List<List<Node>> GetSubExpressions(List<Node> tokens)
|
||||
double HandleMultAndDiv(Stack<Token> tokens)
|
||||
{
|
||||
var expressions = new List<List<Node>>();
|
||||
var stack = new Stack<List<Node>>();
|
||||
var tmp = new List<Node>();
|
||||
var skipCount = 0;
|
||||
var nestingLevel = 0;
|
||||
var runningValue = 0d;
|
||||
var previousToken = new Token() { Type = TokenType.Unknown };
|
||||
|
||||
for(var i = 0; i < tokens.Count; i++)
|
||||
for(; ;)
|
||||
{
|
||||
if(skipCount > 0)
|
||||
if (tokens.Count == 0) break;
|
||||
//"Current" token.
|
||||
if (tokens.Peek().Type != TokenType.Multiply && tokens.Peek().Type != TokenType.Divide && tokens.Peek().Type != TokenType.Constant && tokens.Peek().Type != TokenType.Variable)
|
||||
{
|
||||
skipCount--;
|
||||
break;
|
||||
}
|
||||
|
||||
var currentToken = tokens.Pop();
|
||||
|
||||
if (currentToken.Type == TokenType.Constant)
|
||||
{
|
||||
previousToken = currentToken;
|
||||
continue;
|
||||
}
|
||||
else if (currentToken.Type == TokenType.Multiply || currentToken.Type == TokenType.Divide)
|
||||
{
|
||||
var lookAHead = tokens.Pop();
|
||||
|
||||
if (lookAHead.Type == TokenType.ExpStart)
|
||||
{
|
||||
var tmp = HandleParenthesis(tokens, true);
|
||||
|
||||
if (runningValue == 0) runningValue = Operate(Convert.ToDouble(previousToken.Value), tmp, currentToken.Type);
|
||||
else runningValue = Operate(runningValue, tmp, currentToken.Type);
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lookAHead.Type == TokenType.Constant)
|
||||
{
|
||||
if (runningValue == 0) runningValue = Operate(Convert.ToDouble(previousToken.Value), Convert.ToDouble(lookAHead.Value), currentToken.Type);
|
||||
else runningValue = Operate(runningValue, Convert.ToDouble(lookAHead.Value), currentToken.Type);
|
||||
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
}
|
||||
else if(lookAHead.Type == TokenType.ExpStart)
|
||||
{
|
||||
var tmp = HandleParenthesis(tokens, true);
|
||||
|
||||
if (runningValue == 0) runningValue = Operate(Convert.ToDouble(previousToken.Value), tmp, currentToken.Type);
|
||||
else runningValue = Operate(runningValue, tmp, currentToken.Type);
|
||||
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return runningValue;
|
||||
}
|
||||
|
||||
double HandleAddAndSub(Stack<Token> tokens)
|
||||
{
|
||||
var runningValue = 0d;
|
||||
var previousToken = new Token() { Type = TokenType.Unknown };
|
||||
|
||||
for(; ;)
|
||||
{
|
||||
if (tokens.Count == 0) break;
|
||||
|
||||
var currentToken = tokens.Pop();
|
||||
|
||||
if(currentToken.Type == TokenType.Constant)
|
||||
{
|
||||
previousToken = currentToken;
|
||||
continue;
|
||||
}
|
||||
|
||||
var token = tokens[i];
|
||||
|
||||
//if (stack.Count > 0 && nestingLevel == 0)
|
||||
//{
|
||||
// if (!stack.Peek()[0].IsCoefficent)
|
||||
// {
|
||||
// var offset = 0;
|
||||
|
||||
// while(stack.Count > 0)
|
||||
// {
|
||||
// expressions.Insert(0, stack.Pop());
|
||||
|
||||
// offset++;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
if (token.IsCoefficent)
|
||||
if (currentToken.Type == TokenType.ExpEnd)
|
||||
{
|
||||
//var lookAhead = tokens[i + 1];
|
||||
|
||||
//if(lookAhead.Type != Node.Token.ExpStart)
|
||||
//{
|
||||
if (tmp.Count > 0) expressions.Add(new List<Node>(tmp));
|
||||
expressions.Add(new List<Node>() { token });
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// stack.Push(new List<Node>(tmp));
|
||||
//}
|
||||
|
||||
tmp.Clear();
|
||||
tokens.Push(currentToken);
|
||||
break;
|
||||
}
|
||||
else if (token.Type == Node.Token.ExpStart)
|
||||
|
||||
if(currentToken.Type == TokenType.ExpStart)
|
||||
{
|
||||
nestingLevel++;
|
||||
var tmp = HandleParenthesis(tokens);
|
||||
|
||||
//if (i - 1 >= 0)
|
||||
//{
|
||||
// var lookBehind = tokens[i - 1];
|
||||
|
||||
// if (lookBehind.IsCoefficent)
|
||||
// {
|
||||
// tmp.Remove(tmp.Last());
|
||||
// expressions.Add(new List<Node>(tmp));
|
||||
// tmp.Clear();
|
||||
// stack.Push(new List<Node> { lookBehind });
|
||||
// //tmp.Add(token);
|
||||
// continue;
|
||||
// }
|
||||
//}
|
||||
|
||||
if (tmp.Count > 0) expressions.Add(new List<Node>(tmp));
|
||||
tmp.Clear();
|
||||
tmp.Add(token);
|
||||
runningValue = tmp;
|
||||
}
|
||||
else if(token.Type == Node.Token.ExpEnd)
|
||||
else if(currentToken.Type == TokenType.Add || currentToken.Type == TokenType.Subtract)
|
||||
{
|
||||
nestingLevel--;
|
||||
var lookAHead = tokens.Pop();
|
||||
|
||||
if (i + 1 < tokens.Count)
|
||||
if (lookAHead.Type == TokenType.ExpStart)
|
||||
{
|
||||
var lookAHead = tokens[i + 1];
|
||||
var tmp = HandleParenthesis(tokens);
|
||||
|
||||
if (lookAHead.Type == Node.Token.Power)
|
||||
{
|
||||
var toPowerOf = tokens[i + 2];
|
||||
if (runningValue == 0) runningValue = Operate(Convert.ToDouble(previousToken.Value), tmp, currentToken.Type);
|
||||
else runningValue = Operate(runningValue, tmp, currentToken.Type);
|
||||
|
||||
tmp.Add(token);
|
||||
tmp.Add(lookAHead);
|
||||
tmp.Add(toPowerOf);
|
||||
expressions.Add(new List<Node>(tmp));
|
||||
tmp.Clear();
|
||||
skipCount = 2;
|
||||
continue;
|
||||
}
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp.Add(token);
|
||||
if (tmp.Count > 0) expressions.Add(new List<Node>(tmp));
|
||||
tmp.Clear();
|
||||
if (tokens.Count > 0 && (tokens.Peek().Type == TokenType.Multiply || tokens.Peek().Type == TokenType.Divide))
|
||||
{
|
||||
tokens.Push(lookAHead);
|
||||
var tmp = HandleMultAndDiv(tokens);
|
||||
|
||||
if (runningValue == 0) runningValue = Operate(Convert.ToDouble(previousToken.Value), tmp, currentToken.Type);
|
||||
else runningValue = Operate(runningValue, tmp, currentToken.Type);
|
||||
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (runningValue == 0) runningValue = Operate(Convert.ToDouble(previousToken.Value), Convert.ToDouble(lookAHead.Value), currentToken.Type);
|
||||
else runningValue = Operate(runningValue, Convert.ToDouble(lookAHead.Value), currentToken.Type);
|
||||
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (currentToken.Type == TokenType.Multiply || currentToken.Type == TokenType.Divide)
|
||||
{
|
||||
tmp.Add(token);
|
||||
tokens.Push(currentToken);
|
||||
if (previousToken.Type != TokenType.Unknown) tokens.Push(previousToken);
|
||||
else tokens.Push(new Token { Type = TokenType.Constant, Value = runningValue.ToString() });
|
||||
var tmp = HandleMultAndDiv(tokens);
|
||||
|
||||
previousToken.Type = TokenType.Unknown;
|
||||
//TODO: this is wrong I'm sure.
|
||||
runningValue = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if(tmp.Count > 0)
|
||||
{
|
||||
expressions.Add(new List<Node>(tmp));
|
||||
}
|
||||
|
||||
return expressions;
|
||||
return runningValue;
|
||||
}
|
||||
|
||||
List<Token> FlattenInput(string expression)
|
||||
@@ -377,13 +335,13 @@ namespace Engine
|
||||
|
||||
if(lookBehind.Type == TokenType.ExpEnd)
|
||||
{
|
||||
tokens.Add(new Token() { Value = "^", Type = TokenType.Power, IsCoefficent = false });
|
||||
tokens.Add(new Token() { Value = "^", Type = TokenType.Power });
|
||||
}
|
||||
}
|
||||
|
||||
if((i + 1) == expression.Length)
|
||||
{
|
||||
tokens.Add(new Token() { Value = $"{tmp}{c}", Type = TokenType.Constant, IsCoefficent = false });//new Node($"{tmp}{c}", Node.Token.Constant));
|
||||
tokens.Add(new Token() { Value = $"{tmp}{c}", Type = TokenType.Constant });//new Node($"{tmp}{c}", Node.Token.Constant));
|
||||
}
|
||||
|
||||
parsingNumber = true;
|
||||
@@ -395,10 +353,11 @@ namespace Engine
|
||||
{
|
||||
if (parsingNumber)
|
||||
{
|
||||
tokens.Add(new Token() { Value = tmp, Type = TokenType.Constant, IsCoefficent = true });//new Node(tmp, Node.Token.Constant) { IsCoefficent = true });
|
||||
tokens.Add(new Token() { Value = tmp, Type = TokenType.Constant });
|
||||
tokens.Add(new Token() { Value = "*", Type = TokenType.Multiply });
|
||||
}
|
||||
|
||||
tokens.Add(new Token() { Value = "(", Type = TokenType.ExpStart, IsCoefficent = false });//new Node("(", Node.Token.ExpStart));
|
||||
tokens.Add(new Token() { Value = "(", Type = TokenType.ExpStart });//new Node("(", Node.Token.ExpStart));
|
||||
parsingNumber = false;
|
||||
tmp = string.Empty;
|
||||
continue;
|
||||
@@ -407,10 +366,10 @@ namespace Engine
|
||||
{
|
||||
if (parsingNumber)
|
||||
{
|
||||
tokens.Add(new Token() { Value = tmp, Type = TokenType.Constant, IsCoefficent = false }); //new Node(tmp, Node.Token.Constant));
|
||||
tokens.Add(new Token() { Value = tmp, Type = TokenType.Constant }); //new Node(tmp, Node.Token.Constant));
|
||||
}
|
||||
|
||||
tokens.Add(new Token() { Value = ")", Type = TokenType.ExpEnd, IsCoefficent = false }); //new Node(c.ToString(), Node.Token.ExpEnd));
|
||||
tokens.Add(new Token() { Value = ")", Type = TokenType.ExpEnd }); //new Node(c.ToString(), Node.Token.ExpEnd));
|
||||
parsingNumber = false;
|
||||
tmp = string.Empty;
|
||||
continue;
|
||||
@@ -419,10 +378,10 @@ namespace Engine
|
||||
{
|
||||
if(parsingNumber)
|
||||
{
|
||||
tokens.Add(new Token() { Value = tmp, Type = TokenType.Constant, IsCoefficent = false }); //new Node(tmp, Node.Token.Constant));
|
||||
tokens.Add(new Token() { Value = tmp, Type = TokenType.Constant }); //new Node(tmp, Node.Token.Constant));
|
||||
}
|
||||
|
||||
tokens.Add(new Token() { Value = c.ToString(), Type = op, IsCoefficent = false });//new Node(c.ToString(), op));
|
||||
tokens.Add(new Token() { Value = c.ToString(), Type = op });//new Node(c.ToString(), op));
|
||||
parsingNumber = false;
|
||||
tmp = string.Empty;
|
||||
continue;
|
||||
@@ -444,7 +403,7 @@ namespace Engine
|
||||
|
||||
if (lookBehind.Type == TokenType.ExpEnd)
|
||||
{
|
||||
tokens.Add(new Token() { Value = "^", Type = TokenType.Power, IsCoefficent = false });//new Node("^", Node.Token.Power));
|
||||
tokens.Add(new Token() { Value = "^", Type = TokenType.Power });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +413,8 @@ namespace Engine
|
||||
|
||||
if(lookAHead == '(')
|
||||
{
|
||||
tokens.Add(new Token() { Value = c.ToString(), Type = TokenType.Variable, IsCoefficent = true });
|
||||
tokens.Add(new Token() { Value = c.ToString(), Type = TokenType.Variable });
|
||||
tokens.Add(new Token() { Value = "*", Type = TokenType.Multiply });
|
||||
tmp = string.Empty;
|
||||
parsingNumber = false;
|
||||
continue;
|
||||
@@ -463,10 +423,11 @@ namespace Engine
|
||||
|
||||
if (parsingNumber)
|
||||
{
|
||||
tokens.Add(new Token() {Value = tmp, Type = TokenType.Constant, IsCoefficent = true });
|
||||
tokens.Add(new Token() { Value = tmp, Type = TokenType.Constant });
|
||||
tokens.Add(new Token() { Value = "*", Type = TokenType.Multiply });
|
||||
}
|
||||
|
||||
tokens.Add(new Token() { Value = c.ToString(), Type = TokenType.Variable, IsCoefficent = false });
|
||||
tokens.Add(new Token() { Value = c.ToString(), Type = TokenType.Variable });
|
||||
parsingNumber = false;
|
||||
tmp = string.Empty;
|
||||
}
|
||||
@@ -475,102 +436,24 @@ namespace Engine
|
||||
return tokens;
|
||||
}
|
||||
|
||||
//double Calc(List<List<Node>> expressions, double co = 1)
|
||||
//{
|
||||
// //Assumption: an operator is never last in the list.
|
||||
// //double runningTotal = 0;
|
||||
// double lastValue = 0;
|
||||
// var next = true;
|
||||
// Node previousToken = new Node("zzzz", Node.Token.Unknown);
|
||||
|
||||
// for(var i = 0; i < expressions.Count;)
|
||||
// {
|
||||
// if (!next) break;
|
||||
|
||||
// var tokens = expressions[i];
|
||||
// expressions.RemoveAt(i);
|
||||
|
||||
// for (var j = 0; j < tokens.Count; j++)
|
||||
// {
|
||||
// var token = tokens[j];
|
||||
|
||||
// if(token.IsCoefficent)
|
||||
// {
|
||||
// if(tokens.Count == 1)
|
||||
// {
|
||||
// return Calc(expressions, Convert.ToDouble(token.Value));
|
||||
// }
|
||||
// }
|
||||
// else if(token.Type == Node.Token.Constant)
|
||||
// {
|
||||
// previousToken = token;
|
||||
// }
|
||||
// else if(token.Type == Node.Token.Variable)
|
||||
// {
|
||||
// //TODO: do symbol lookup to get value for this variale.
|
||||
// previousToken = new Node("666", Node.Token.Variable);
|
||||
// }
|
||||
// else if(GetOperator(token.Value[0]) != Node.Token.Unknown)
|
||||
// {
|
||||
// if(tokens.Count > j + 1)
|
||||
// {
|
||||
// j++;
|
||||
// var lookAHead = tokens[j];
|
||||
|
||||
// if(lookAHead.Type == Node.Token.Constant)
|
||||
// {
|
||||
// if (previousToken.Type != Node.Token.Unknown)
|
||||
// {
|
||||
// lastValue = Operate(Convert.ToDouble(previousToken.Value) * co, Convert.ToDouble(lookAHead.Value) * co, token.Type);
|
||||
// previousToken = new Node("zzzz", Node.Token.Unknown);
|
||||
// }
|
||||
// else
|
||||
// lastValue = Operate(lastValue * co, Convert.ToDouble(lookAHead.Value) * co, token.Type);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// lastValue = Operate(Convert.ToDouble(previousToken.Value), Calc(expressions), token.Type);
|
||||
// }
|
||||
// }
|
||||
// else if(token.Type == Node.Token.ExpStart)
|
||||
// {
|
||||
|
||||
// }
|
||||
// else if(token.Type == Node.Token.ExpEnd)
|
||||
// {
|
||||
// if(tokens.Count > j + 1)
|
||||
// {
|
||||
// var lookAHead = tokens[j + 1];
|
||||
|
||||
// if(lookAHead.Type == Node.Token.Power)
|
||||
// {
|
||||
// lookAHead = tokens[j + 2];
|
||||
// lastValue = Operate(lastValue, Convert.ToDouble(lookAHead.Value), Node.Token.Power);
|
||||
// }
|
||||
// }
|
||||
|
||||
// next = false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return lastValue;
|
||||
//}
|
||||
|
||||
double Operate(double n1, double n2, TokenType operation)
|
||||
double Operate(double n1, double n2, TokenType operation, [CallerMemberName] string source = "")
|
||||
{
|
||||
switch(operation)
|
||||
{
|
||||
case TokenType.Add:
|
||||
ActionsListView.Items.Add($"From {source} {GetOperatorVerb(operation)} {n1} and {n2} to get {n1 + n2}");
|
||||
return n1 + n2;
|
||||
case TokenType.Divide:
|
||||
ActionsListView.Items.Add($"From {source} {GetOperatorVerb(operation)} {n1} and {n2} to get {n1 / n2}");
|
||||
return n1 / n2;
|
||||
case TokenType.Multiply:
|
||||
ActionsListView.Items.Add($"From {source} {GetOperatorVerb(operation)} {n1} and {n2} to get {n1 * n2}");
|
||||
return n1 * n2;
|
||||
case TokenType.Power:
|
||||
ActionsListView.Items.Add($"From {source} {GetOperatorVerb(operation)} {n1} to the power of {n2} to get {Math.Pow(n1, n2)}");
|
||||
return Math.Pow(n1, n2);
|
||||
case TokenType.Subtract:
|
||||
ActionsListView.Items.Add($"From {source} {GetOperatorVerb(operation)} {n1} and {n2} to get {n1 - n2}");
|
||||
return n1 - n2;
|
||||
default:
|
||||
throw new Exception("Token must be an operator!");
|
||||
@@ -618,7 +501,6 @@ namespace Engine
|
||||
struct Token
|
||||
{
|
||||
public string Value;
|
||||
public bool IsCoefficent;
|
||||
public TokenType Type;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user