private void EnqueOperation(ExpressionOperation operation) { while (operatorStack.Count > 0 && operation.Precedence <= operatorStack.Peek().Precedence) { outputQueue.Enqueue(operatorStack.Pop()); } operatorStack.Push(operation); }
public override void EndNode(ParserContext context) { switch (context.NodeKind) { case SyntaxNodeKind.Expression: while (operatorStack.Count > 0) { var op = operatorStack.Pop(); if (op.Kind == ExpressionOperationKind.Expression) break; outputQueue.Enqueue(op); } break; case SyntaxNodeKind.UnaryOperator: var unaryOp = new ExpressionOperation(ConvertUnaryToOperationKind(context.Span)); EnqueOperation(unaryOp); break; case SyntaxNodeKind.Operator: var op1 = new ExpressionOperation(ConvertToOperationKind(context.Span)); EnqueOperation(op1); break; case SyntaxNodeKind.Constant: outputQueue.Enqueue( new ExpressionOperation(ExpressionOperationKind.Number, ToNumber(context.Span.Text))); break; case SyntaxNodeKind.ExpressionIdentifier: Label label; var labelName = context.Span.Text; var found = labelStore.TryGetLabel(labelName, out label); var topOperatorKind = operatorStack.Peek().Kind; switch (topOperatorKind) { case ExpressionOperationKind.Def: labelStore.AddReferencedLabel(labelName, lineNumber); operatorStack.Pop(); outputQueue.Enqueue(new ExpressionOperation(ExpressionOperationKind.Number, found ? 1 : 0)); break; case ExpressionOperationKind.Ref: operatorStack.Pop(); ISet<int> referencingLines; bool anyReference = labelStore.TryGetReferencingLines(labelName, out referencingLines); int refOperatorResult = (anyReference && (referencingLines.Count != 1 || !referencingLines.Contains(lineNumber))) ? 1 : 0; outputQueue.Enqueue(new ExpressionOperation(ExpressionOperationKind.Number, refOperatorResult)); break; default: labelStore.AddReferencedLabel(labelName, lineNumber); outputQueue.Enqueue( found ? new ExpressionOperation(ExpressionOperationKind.Number, label.Value) : new ExpressionOperation(ExpressionOperationKind.Number, 0)); break; } break; } }