/// <summary> /// Convert to the given expression in infix notation to postfix notation. /// </summary> /// <param name="infix">The expression in infix notation.</param> /// <returns>The expression converted to postfix notation.</returns> private AstItem InfixToPostfix(List <AstItem> infix) { var output = new List <AstItem>(); var stack = new Stack <AstItem>(); AstItem cbuffer = null; //Convert infix to postfix foreach (var item in infix) { if (item.Kind == AstItemKind.Immediate || item.Kind == AstItemKind.Variable || item.Kind == AstItemKind.Vector || item.Kind == AstItemKind.FunctionCall || item.Kind == AstItemKind.Type || item.Kind == AstItemKind.Identifier || item.Kind == AstItemKind.IndexAccess) { output.Add(item); } else if (item.Operator == Operator.ROUND_BRACKET_OPEN) { stack.Push(item); } else if (item.Operator == Operator.ROUND_BRACKET_CLOSE) { cbuffer = stack.Pop(); while (cbuffer.Operator != Operator.ROUND_BRACKET_OPEN) { output.Add(cbuffer); cbuffer = stack.Pop(); } } else if (item.Kind == AstItemKind.BinaryOperator || item.Kind == AstItemKind.UnaryOperator) { if (stack.Count != 0 && Predecessor(stack.Peek(), item)) { cbuffer = stack.Pop(); while (Predecessor(cbuffer, item)) { output.Add(cbuffer); if (stack.Count == 0) { break; } cbuffer = stack.Peek(); // With unary operators it is now possible to find a round bracket here, which must not be popped! if (cbuffer.Kind == AstItemKind.BinaryOperator && cbuffer.Operator == Operator.ROUND_BRACKET_OPEN) { break; } else { stack.Pop(); } } stack.Push(item); } else { stack.Push(item); } } else { throw new Exception("Unexpected Ast item in expression: " + item); } } while (stack.Count > 0) { cbuffer = stack.Pop(); output.Add(cbuffer); } return(AstItem.Expression(output[0].DataType, output)); }