/// <summary> /// Get all the argument indices that are expressed in <paramref name="exp"/>. /// </summary> /// <param name="exp"></param> /// <param name="argumentIndices"></param> static void GetArguments(IExpression exp, ref StructList4 <int> argumentIndices) { StructList8 <IExpression> stack = new StructList8 <IExpression>(); stack.Add(exp); while (stack.Count > 0) { IExpression e = stack.Dequeue(); if (e is IArgumentIndexExpression arg) { argumentIndices.AddIfNew(arg.Index); } if (e is ICompositeExpression compositeExpression) { for (int i = 0; i < compositeExpression.ComponentCount; i++) { IExpression ce = compositeExpression.GetComponent(i); if (ce != null) { stack.Add(ce); } } } } }
/// <summary> /// Print as string /// </summary> /// <param name="str"></param> /// <returns>string or null</returns> public LineString Print(IString str) { if (str is CSharpFormat && str.Text != null) { return(new LineString(null, str.Text, LineStatus.StringFormatOkString)); } StringBuilder sb = new StringBuilder(); LineStatus status = 0UL; foreach (var part in str.Parts) { // Escape '{' '}' and '\' to '\{' '\}' '\\' if (part.Kind == StringPartKind.Text) { string s = part.Text; for (int i = 0; i < s.Length; i++) { char c = s[i]; if (c == '{' || c == '}' || c == '\\') { sb.Append('\\'); } sb.Append(c); } continue; } // Placeholder if (part.Kind == StringPartKind.Placeholder && part is IPlaceholder placeholder) { int argumentIx = -1; string format = null; int alignment = 0; StructList8 <IExpression> queue = new StructList8 <IExpression>(); queue.Add(placeholder.Expression); while (queue.Count > 0) { IExpression e = queue.Dequeue(); if (e is IArgumentIndexExpression arg) { // Second argument index if (argumentIx >= 0) { status.Up(LineStatus.StringFormatErrorPrintNoCapabilityMultipleArguments); } else { argumentIx = arg.Index; } continue; } if (e is ICallExpression call) { if (call.Name == "Format" && call.Args != null && call.Args.Length == 2 && call.Args[1] is IConstantExpression formatExp && formatExp.Value is string formatStr) { queue.Add(call.Args[0]); format = formatStr; } else if (call.Name == "Alignment" && call.Args != null && call.Args.Length == 2 && call.Args[1] is IConstantExpression alignmentExp) { queue.Add(call.Args[0]); if (alignmentExp.Value is long longValue) { alignment = (int)longValue; } else if (alignmentExp.Value is int intValue) { alignment = intValue; } else { status.Up(LineStatus.StringFormatErrorPrintUnsupportedExpression); } } else { status.Up(LineStatus.StringFormatErrorPrintUnsupportedExpression); } continue; } status.Up(LineStatus.StringFormatErrorPrintUnsupportedExpression); } if (argumentIx >= 0) { sb.Append('{'); if (placeholder.PluralCategory != null) { sb.Append(placeholder.PluralCategory); sb.Append(':'); } sb.Append(argumentIx); if (alignment != 0) { sb.Append(','); sb.Append(alignment); } if (format != null) { sb.Append(":"); sb.Append(format); } sb.Append('}'); } continue; } // Malformed status.Up(LineStatus.StringFormatErrorMalformed); }