public LNode Fn(LNode retType, LNode name, LNode argList, LNode body = null, int startIndex = -1, int endIndex = -1) { Debug.Assert(endIndex >= startIndex); CheckParam.Arg("argList", argList.Name == S.List || argList.Name == S.Missing); LNode[] list = body == null ? new[] { retType, name, argList } : new[] { retType, name, argList, body }; return(new StdSimpleCallNode(S.Fn, new RVList <LNode>(list), new SourceRange(_file, startIndex, endIndex - startIndex))); }
public LNode Property(LNode type, LNode name, LNode body = null, int startIndex = -1, int endIndex = -1) { Debug.Assert(endIndex >= startIndex); CheckParam.Arg("body", body.IsCall && (body.Name == S.Braces || (body.Name == S.Forward && body.Args.Count == 1))); LNode[] list = body == null ? new[] { type, name, } : new[] { type, name, body }; return(new StdSimpleCallNode(S.Property, new RVList <LNode>(list), new SourceRange(_file, startIndex, endIndex - startIndex))); }
public LNode Property(LNode type, LNode name, LNode argList, LNode body, LNode initializer = null, int startIndex = -1, int endIndex = -1) { argList = argList ?? Missing_; CheckParam.Arg("body with initializer", initializer == null || (body != null && body.Calls(S.Braces))); if (endIndex < startIndex) { endIndex = startIndex; } LNode[] list = body == null ? new[] { type, name, argList, } : initializer == null ? new[] { type, name, argList, body } : new[] { type, name, argList, body, initializer }; return(new StdSimpleCallNode(S.Property, new VList <LNode>(list), new SourceRange(_file, startIndex, endIndex - startIndex))); }
/// <summary>Given a normal operator symbol like <c>(Symbol)"'++"</c>, gets /// the suffix form of the name, such as <c>(Symbol)"'suf++"</c>.</summary> /// <remarks>op must be a Symbol, but the parameter has type object to avoid casting Token.Value in the parser.</remarks> public Symbol ToSuffixOpName(object symbol) { CheckParam.IsNotNull(nameof(symbol), symbol); _suffixOpNames = _suffixOpNames ?? new Dictionary <object, Symbol>(); Symbol name; if (_suffixOpNames.TryGetValue(symbol, out name)) { return(name); } CheckParam.Arg(nameof(symbol), symbol.ToString().StartsWith("'"), symbol); var was = symbol.ToString(); return(_suffixOpNames[symbol] = GSymbol.Get("'suf" + symbol.ToString().Substring(1))); }
/// <summary>Converts a StringBuilder with <see cref="LesColorCode"/> /// control codes to HTML with Pygments CSS class codes.</summary> /// <param name="input">Input containing <see cref="LesColorCode"/> control characters.</param> /// <param name="output">Output StringBuilder for HTML code. If null, a new one is created.</param> /// <param name="addPreCode">Whether to wrap the output in "<pre class='highlight'><code>" tags.</param> /// <param name="newline">What to write to <c>output</c> when '\n' is encountered.</param> /// <param name="colorCodesToCssClasses">CSS class table for span tags, /// see <see cref="GetDefaultCssClassTable"/>.</param> /// <returns>The output StringBuilder.</returns> public static StringBuilder PrintToHtmlCore( StringBuilder input, StringBuilder output = null, bool addPreCode = true, string newline = "\n", string[] colorCodesToCssClasses = null) { CheckParam.Arg("output", output != input); colorCodesToCssClasses = colorCodesToCssClasses ?? DefaultCssClassTable; output = output ?? new StringBuilder(input.Length); if (addPreCode) { output.Append("<pre class='highlight'><code>"); } string cssClass = null; int depth = 0; char c, next = input.TryGet(0, '\0'); for (int i = 0; i < input.Length; i++) { c = next; next = input.TryGet(i + 1, '\0'); if (c < colorCodesToCssClasses.Length) { if (c <= '\n') // \n is 10 { if (c == '\n') { output.Append(newline); } else if (c != '\0') { // If the LNode contains control codes, printer should have \escaped them Debug.Assert(c == '\t'); // \t is 9 output.Append(c); } } else if (c == (char)LesColorCode.Opener) { if (next == '(' || next == '[') { c = (char)((++depth & 1) == 0 ? LesColorCode.Closer : LesColorCode.Opener); } else { c = (char)LesColorCode.Separator; } } else if (c == (char)LesColorCode.Closer) { if (next == ')' || next == ']') { c = (char)((--depth & 1) == 1 ? LesColorCode.Closer : LesColorCode.Opener); } else { c = (char)LesColorCode.Separator; } } var newClass = colorCodesToCssClasses[(int)c]; if (newClass != cssClass) { if (cssClass != null) { output.Append("</span>"); } if (newClass != null) { output.Append("<span class='").Append(newClass).Append("'>"); } cssClass = newClass; } if (c == (char)LesColorCode.Attribute && next == '@' && input.TryGet(i + 2, '\0').IsOneOf((char)LesColorCode.Id, (char)LesColorCode.Number, (char)LesColorCode.KeywordLiteral, (char)LesColorCode.CustomLiteral, (char)LesColorCode.String)) { output.Append('@'); // skip over @ and the next control code to extend attribute coloring over it i += 2; } } else if (c == '<') { output.Append("<"); } else if (c == '&') { output.Append("&"); } else { output.Append(c); } } if (cssClass != null) { output.Append("</span>"); } if (addPreCode) { output.Append("</code></pre>"); } return(output); }