/// <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);
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <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);
            }