private bool AutoPrintPrefixOrSuffixOp(ILNode node, Precedence context) { Symbol bareName; if (LesPrecedenceMap.IsSuffixOperatorName(node.Name, out bareName, false)) { var prec = GetPrecedenceIfOperator(node, 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, 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(LNode node, OperatorShape shape, Precedence context) { int ac = node.ArgCount; if ((ac == (int)shape || ac == -(int)shape) && HasSimpleTargetWithoutPAttrs(node)) { var bs = node.BaseStyle; var op = node.Name; bool naturalOp = LesPrecedenceMap.IsNaturalOperator(op); if (bs == NodeStyle.Operator || (naturalOp && bs != NodeStyle.PrefixNotation)) { var result = _prec.Find(shape, op); if (bs == NodeStyle.Operator && !naturalOp) { result = LesPrecedence.Backtick; } else if (!result.CanAppearIn(context)) { result = LesPrecedence.Backtick; } if (!result.CanAppearIn(context) || !result.CanMixWith(context)) { return(null); } return(result); } } return(null); }
private bool AutoPrintPrefixOrSuffixOp(LNode node, Mode mode, Precedence context) { Symbol bareName; if (LesPrecedenceMap.IsSuffixOperatorName(node.Name, out bareName, false)) { var prec = GetPrecedenceIfOperator(node, OperatorShape.Suffix, context); if (prec == null || prec.Value == LesPrecedence.Backtick) { return(false); } Print(node.Args[0], mode, prec.Value.LeftContext(context)); SpaceIf(prec.Value.Lo < SpaceAfterPrefixStopPrecedence); WriteOpName(bareName, prec.Value); } else { var prec = GetPrecedenceIfOperator(node, OperatorShape.Prefix, context); if (prec == null) { return(false); } WriteOpName(node.Name, prec.Value); SpaceIf(prec.Value.Lo < SpaceAfterPrefixStopPrecedence); Print(node.Args[0], mode, prec.Value.RightContext(context)); } return(true); }
private void WriteOpName(Symbol op, Precedence prec) { if (prec == LesPrecedence.Backtick || !LesPrecedenceMap.IsNaturalOperator(op)) { PrintStringCore('`', false, op.Name); } else { _out.Write(op.Name, true); } //else { // _out.Write('\\', false); // _out.Write(op.Name, true); // _out.Space(); // lest the next char to be printed be treated as part of the operator name //} }
private Precedence?GetPrecedenceIfOperator(ILNode node, OperatorShape shape, Precedence context) { int ac = node.ArgCount(); if ((ac == (int)shape || ac == -(int)shape) && HasTargetIdWithoutPAttrs(node)) { var bs = node.BaseStyle(); var op = node.Name; bool naturalOp = LesPrecedenceMap.IsNaturalOperator(op.Name); if ((naturalOp && bs != NodeStyle.PrefixNotation) || (bs == NodeStyle.Operator && node.Name != null)) { var result = _prec.Find(shape, op); 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) { // 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 // (@[#trivia_trailing(#trivia_SLComment("comment"))] @==)(a, @[#trivia_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 (!LesPrecedenceMap.IsNaturalOperator(op.Name)) { PrintStringCore('`', false, op.Name); } else { Debug.Assert(op.Name.StartsWith("'")); _out.Write(op.Name.Substring(1), true); } SpaceIf(spaceAfter); if (target != null) { PrintSuffixTrivia(target, 0, null); } }