Example #1
0
        internal static void SkipWhitespace(PositionalTokenizer tokenizer)
        {
            tokenizer.SkipWhitespace();
            while (tokenizer.Match("//"))
            {
                var expressionTokenizer = tokenizer as ExpressionTokenizer;
                if (expressionTokenizer != null)
                {
                    int line   = tokenizer.Line;
                    int column = tokenizer.Column - 2;

                    var comment = tokenizer.ReadTo('\n');
                    if (comment.Length > 0 && comment[comment.Length - 1] == '\r')
                    {
                        comment = comment.SubToken(0, comment.Length - 1);
                    }

                    expressionTokenizer.AddComment(new CommentExpression("//" + comment.ToString())
                    {
                        Location = new TextRange(line, column, line, column + comment.Length + 1)
                    });
                }
                else
                {
                    tokenizer.ReadTo('\n');
                }

                tokenizer.SkipWhitespace();
            }
        }
Example #2
0
        private ParseErrorExpression ProcessRichPresenceDisplay(StringConstantExpression stringExpression, InterpreterScope scope, out string displayString)
        {
            displayString = null;

            ExpressionBase result;
            var            varargs = GetParameter(scope, "varargs", out result) as ArrayExpression;

            if (varargs == null)
            {
                var error = result as ParseErrorExpression;
                if (error == null)
                {
                    error = new ParseErrorExpression("unexpected varargs", stringExpression);
                }
                return(error);
            }

            var context = scope.GetContext <RichPresenceDisplayContext>();
            var builder = context.DisplayString;

            var tokenizer = new PositionalTokenizer(Tokenizer.CreateTokenizer(stringExpression.Value));

            while (tokenizer.NextChar != '\0')
            {
                var token = tokenizer.ReadTo('{');
                builder.Append(token.ToString());

                if (tokenizer.NextChar == '\0')
                {
                    break;
                }

                var positionalTokenColumn = tokenizer.Column;
                tokenizer.Advance();
                var index = tokenizer.ReadNumber();
                if (tokenizer.NextChar != '}')
                {
                    return(new ParseErrorExpression("Invalid positional token",
                                                    stringExpression.Line, stringExpression.Column + positionalTokenColumn,
                                                    stringExpression.Line, stringExpression.Column + tokenizer.Column - 1));
                }
                tokenizer.Advance();

                var parameterIndex = Int32.Parse(index.ToString());
                if (parameterIndex >= varargs.Entries.Count)
                {
                    return(new ParseErrorExpression("Invalid parameter index: " + parameterIndex,
                                                    stringExpression.Line, stringExpression.Column + positionalTokenColumn,
                                                    stringExpression.Line, stringExpression.Column + tokenizer.Column - 1));
                }

                var functionCall = varargs.Entries[parameterIndex] as FunctionCallExpression;

                var functionDefinition = scope.GetFunction(functionCall.FunctionName.Name);
                if (functionDefinition == null)
                {
                    return(new ParseErrorExpression("Unknown function: " + functionCall.FunctionName.Name));
                }

                var richPresenceFunction = functionDefinition as FunctionDefinition;
                if (richPresenceFunction == null)
                {
                    return(new ParseErrorExpression(functionCall.FunctionName.Name + " cannot be called as a rich_presence_display parameter", functionCall));
                }

                var error = richPresenceFunction.BuildMacro(context, scope, functionCall);
                if (error != null)
                {
                    return(new ParseErrorExpression(error, functionCall));
                }
            }

            displayString = builder.ToString();
            return(null);
        }
Example #3
0
        public string GetFormattedErrorMessage(Tokenizer tokenizer)
        {
            var neededLines = new List <int>();
            var error       = Error;

            while (error != null)
            {
                for (int i = error.Location.Start.Line; i <= error.Location.End.Line; i++)
                {
                    if (!neededLines.Contains(i))
                    {
                        neededLines.Add(i);
                    }
                }

                error = error.InnerError;
            }

            neededLines.Sort();

            var lineDictionary      = new TinyDictionary <int, string>();
            var positionalTokenizer = new PositionalTokenizer(tokenizer);
            int lineIndex           = 0;

            while (lineIndex < neededLines.Count)
            {
                while (positionalTokenizer.NextChar != '\0' && positionalTokenizer.Line != neededLines[lineIndex])
                {
                    positionalTokenizer.ReadTo('\n');
                    positionalTokenizer.Advance();
                }

                lineDictionary[neededLines[lineIndex]] = positionalTokenizer.ReadTo('\n').TrimRight().ToString();
                lineIndex++;
            }

            var builder = new StringBuilder();

            error = Error;
            while (error != null)
            {
                builder.AppendFormat("{0}:{1} {2}", error.Location.Start.Line, error.Location.Start.Column, error.Message);
                builder.AppendLine();
                //for (int i = error.Line; i <= error.EndLine; i++)
                int i = error.Location.Start.Line; // TODO: show all lines associated to error?
                {
                    var line = lineDictionary[error.Location.Start.Line];

                    builder.Append(":: ");
                    var startColumn = 0;
                    while (Char.IsWhiteSpace(line[startColumn]))
                    {
                        startColumn++;
                    }

                    if (i == error.Location.Start.Line)
                    {
                        builder.Append("{{color|#C0C0C0|");
                        builder.Append(line.Substring(startColumn, error.Location.Start.Column - startColumn - 1));
                        builder.Append("}}");
                        startColumn = error.Location.Start.Column - 1;
                    }

                    if (i == error.Location.End.Line)
                    {
                        builder.Append(line.Substring(startColumn, error.Location.End.Column - startColumn));
                        builder.Append("{{color|#C0C0C0|");
                        builder.Append(line.Substring(error.Location.End.Column));
                        builder.Append("}}");
                    }
                    else
                    {
                        builder.Append(line.Substring(startColumn));
                    }
                    builder.AppendLine();
                }
                builder.AppendLine();
                error = error.InnerError;
            }

            while (builder.Length > 0 && Char.IsWhiteSpace(builder[builder.Length - 1]))
            {
                builder.Length--;
            }

            return(builder.ToString());
        }
Example #4
0
        public override bool Evaluate(InterpreterScope scope, out ExpressionBase result)
        {
            var stringExpression = GetStringParameter(scope, "format_string", out result);

            if (stringExpression == null)
            {
                return(false);
            }

            var varargs = GetParameter(scope, "varargs", out result) as ArrayExpression;

            if (varargs == null)
            {
                if (!(result is ParseErrorExpression))
                {
                    result = new ParseErrorExpression("unexpected varargs", stringExpression);
                }
                return(false);
            }

            var builder = new StringBuilder();

            var tokenizer = new PositionalTokenizer(Tokenizer.CreateTokenizer(stringExpression.Value));

            while (tokenizer.NextChar != '\0')
            {
                var token = tokenizer.ReadTo('{');
                builder.Append(token.ToString());

                if (tokenizer.NextChar == '\0')
                {
                    break;
                }

                var positionalTokenColumn = tokenizer.Column;
                tokenizer.Advance();
                if (tokenizer.NextChar == '}')
                {
                    result = new ParseErrorExpression("Empty parameter index",
                                                      stringExpression.Location.Start.Line, stringExpression.Location.Start.Column + positionalTokenColumn,
                                                      stringExpression.Location.Start.Line, stringExpression.Location.Start.Column + tokenizer.Column - 1);
                    return(false);
                }
                var index = tokenizer.ReadNumber();
                if (tokenizer.NextChar != '}')
                {
                    result = new ParseErrorExpression("Invalid positional token",
                                                      stringExpression.Location.Start.Line, stringExpression.Location.Start.Column + positionalTokenColumn,
                                                      stringExpression.Location.Start.Line, stringExpression.Location.Start.Column + tokenizer.Column - 1);
                    return(false);
                }
                tokenizer.Advance();

                Int32 parameterIndex;
                if (!Int32.TryParse(index.ToString(), out parameterIndex) ||
                    parameterIndex < 0 || parameterIndex >= varargs.Entries.Count)
                {
                    result = new ParseErrorExpression("Invalid parameter index: " + index.ToString(),
                                                      stringExpression.Location.Start.Line, stringExpression.Location.Start.Column + positionalTokenColumn,
                                                      stringExpression.Location.Start.Line, stringExpression.Location.Start.Column + tokenizer.Column - 1);
                    return(false);
                }

                result = varargs.Entries[parameterIndex];
                var functionCall = result as FunctionCallExpression;
                if (functionCall != null)
                {
                    if (!functionCall.Evaluate(scope, out result))
                    {
                        return(false);
                    }
                }

                if (result.IsLiteralConstant)
                {
                    result.AppendStringLiteral(builder);
                }
                else
                {
                    result = new ParseErrorExpression("Cannot convert expression to string", result);
                    return(false);
                }
            }

            result = new StringConstantExpression(builder.ToString());
            return(true);
        }