public List <NovelInstruction> ParseExpression(string text) { //Trim the expression text = text.Trim(); //Create empty expression object NovelExpression novelExpression = new NovelExpression(); //Declare instructions List <NovelInstruction> instructions = new List <NovelInstruction>(); //For RPN algorithm purpose string output = ""; string buffer = ""; for (int i = 0; i < text.Length; i++) { //Check if the i is pointing at operator name var operatorIndex = IsOperator(text, i); //operatorIndex = -1 means that its regular character if (operatorIndex >= 0) { //Build expression here based on whats in buffer if (!buffer.Equals("")) { if (IsDeclaredVariable(buffer)) { buffer = buffer.Substring(3); if (!Variables.ContainsVariable(buffer)) { instructions.Add(new NovelExpandStack(1)); Variables.AddVaraible(buffer); } //TODO functions name else { throw new NovelException("Variable or function name " + buffer + " already exists.", ParsedFile, ParsedLine); } } //Handle the operands novelExpression = HandleOperand(novelExpression, buffer); //Push variable to the output output += buffer; buffer = ""; } //Get the new operator var op = Operators[operatorIndex]; //Parentheses close operator if (op is NovelCloseCurvedParenthesesOperator) { //Pop all operators till ( while (OperatorStack.Count() > 0) { var opFromStack = OperatorStack.Pop(); if (opFromStack is NovelOpenCurvedParenthesesOperator) { var parentheses = parenthesesType.Pop(); if (parentheses == ParenthesesType.Function) { novelExpression.Term.Add(new NovelFunctionEndOperator()); } break; } else { if (!(opFromStack is NovelOpenCurvedParenthesesOperator || opFromStack is NovelCloseCurvedParenthesesOperator)) { novelExpression.Term.Add(opFromStack); } } } } //If every other operator else { //Iteratore over OperatorStack while (OperatorStack.Count() > 0) { //If priority of new operator is lower or equal pop stack operators // if (op.GetPriority() <= OperatorStack.First().GetPriority() && !(op is NovelOpenCurvedParenthesesOperator)) { var opFromStack = OperatorStack.Pop(); if (!(opFromStack is NovelOpenCurvedParenthesesOperator || opFromStack is NovelCloseCurvedParenthesesOperator)) { novelExpression.Term.Add(opFromStack); } } else { break; } } } //Now put the operator on the stack if not close curved if (!(op is NovelCloseCurvedParenthesesOperator)) { //If previous term part was function call if (novelExpression.Term.Count >= 1 && op is NovelOpenCurvedParenthesesOperator && novelExpression.Term[novelExpression.Term.Count - 1] is NovelExpressionFunctionCall) { parenthesesType.Push(ParenthesesType.Function); novelExpression.Term.Add(new NovelFunctionStartOperator()); } //If normal paretheses else if (op is NovelOpenCurvedParenthesesOperator) { parenthesesType.Push(ParenthesesType.Normal); } OperatorStack.Push(op); } //Move pointer by a length of operator i += op.GetName().Length - 1; } //If its not an operator else { if (text[i].Equals(' ')) { continue; } else if (text[i].Equals('\t')) { continue; } else if (text[i].Equals('\r')) { continue; } else if (text[i].Equals('\n')) { continue; } //If its a quote if (text[i].Equals('\"')) { int len = text.IndexOf('\"', i + 1) - i + 1; buffer += text.Substring(i, len); i += len - 1; } //If its not add single character else { buffer += text[i]; } } } //Empty buffer first if (!buffer.Equals("")) { novelExpression = HandleOperand(novelExpression, buffer); } //Empty operator stack while (OperatorStack.Count() > 0) { var opFromStack = OperatorStack.Pop(); if (!(opFromStack is NovelOpenCurvedParenthesesOperator || opFromStack is NovelCloseCurvedParenthesesOperator)) { novelExpression.Term.Add(opFromStack); } } Variables.AddScope(); int reservedVariables = Variables.GetStackVariables(); while (novelExpression.Term.Count > 0) { novelExpression = UnfoldOperations(novelExpression, ref instructions); novelExpression = UnfoldArguments(novelExpression, ref instructions); //For single variables or literals if (novelExpression.Term.Count == 1) { var newExpression = new NovelExpression(); newExpression.Term.Add(novelExpression.Term[0]); instructions.Add(newExpression); novelExpression.Term.Clear(); } } //How many of temporary variables expression has reservedVariables = Variables.GetStackVariables() - reservedVariables; //Shrink stack to remove them if (reservedVariables > 0) { instructions.Add(new NovelExpandStack(-reservedVariables)); } Variables.RemoveScope(); foreach (var instruction in instructions) { string buff = ""; buff += " " + instruction; Console.WriteLine(buff); } Console.WriteLine(""); return(instructions); }