private bool AutoPrintPrefixOrSuffixOp(ILNode node, Precedence context) { Symbol bareName; if (Les2PrecedenceMap.IsSuffixOperatorName(node.Name, out bareName)) { var prec = GetPrecedenceIfOperator(node, bareName, OperatorShape.Suffix, context); if (prec == null || prec.Value == LesPrecedence.Other) { return(false); } Print(node[0], prec.Value.LeftContext(context)); SpaceIf(prec.Value.Lo < _o.SpaceAfterPrefixStopPrecedence); WriteOpName(bareName, node.Target, prec.Value); } else { var prec = GetPrecedenceIfOperator(node, bareName, OperatorShape.Prefix, context); if (prec == null) { return(false); } var spaceAfter = prec.Value.Lo < _o.SpaceAfterPrefixStopPrecedence; WriteOpName(node.Name, node.Target, prec.Value, spaceAfter); Print(node[0], prec.Value.RightContext(context)); } return(true); }
private Precedence?GetPrecedenceIfOperator(ILNode node, Symbol opName, OperatorShape shape, Precedence context) { int ac = node.ArgCount(); if ((ac == (int)shape || ac == -(int)shape) && HasTargetIdWithoutPAttrs(node)) { var bs = node.BaseStyle(); bool naturalOp = Les2PrecedenceMap.IsNaturalOperator(opName.Name); if ((naturalOp && bs != NodeStyle.PrefixNotation) || (bs == NodeStyle.Operator && node.Name != null)) { var result = _prec.Find(shape, opName); if (!result.CanAppearIn(context) || !result.CanMixWith(context)) { return(null); } return(result); } } return(null); }
private void WriteOpName(Symbol op, ILNode target, Precedence prec, bool spaceAfter = false) { _out.BeginNode(target); // Note: if the operator has a space after it, there's a subtle reason why // we want to print that space before the trivia and not after. Consider // the input "a == //comment\n b". After trivia injection this becomes // (@[@%trailing(@%SLComment("comment"))] @==)(a, @[@%newline] b). // Because the injector associates the newline with a different node than the // single-line comment, there's no easy way to strip out the newline during // the parsing process. So, to make the trivia round-trip, we use // _out.Newline(pending: true) when printing a single-line comment, which // suppresses the newline if it is followed immediately by another newline. // But if we print a space after the trivia, then this suppression does not // occur and we end up with two newlines. Therefore, we must print the space first. if (target.AttrCount() == 0) { target = null; // optimize the usual case } if (target != null) { PrintPrefixTrivia(target); } if (!Les2PrecedenceMap.IsNaturalOperator(op.Name)) { PrintStringCore('`', false, op.Name); } else { Debug.Assert(op.Name.StartsWith("'")); _out.Write(op.Name.Substring(1)); } SpaceIf(spaceAfter); if (target != null) { PrintSuffixTrivia(target, 0, null); } _out.EndNode(); }