Exemplo n.º 1
0
        private static void ParseFunctionAttributes(ExpressionToken exp, Scope scope, CompositeToken funcToken)
        {
            var             code = scope.Code;
            string          word;
            ExpressionToken exp2;

            while (true)
            {
                word = code.PeekWordR();
                switch (word)
                {
                case "description":
                case "prompt":
                case "comment":
                case "accel":
                    funcToken.AddToken(new KeywordToken(scope, code.MovePeekedSpan(), code.Text));
                    exp2 = ExpressionToken.TryParse(scope, _functionAttribsEndTokens);
                    if (exp2 != null)
                    {
                        funcToken.AddToken(exp2);
                    }
                    break;

                case "nomenu":
                    funcToken.AddToken(new KeywordToken(scope, code.MovePeekedSpan(), code.Text));
                    break;

                case "BEGINHLP":
                    funcToken.AddToken(new KeywordToken(scope, code.MovePeekedSpan(), code.Text));
                    while (code.ReadStringLiteral())
                    {
                        funcToken.AddToken(new StringLiteralToken(scope, code.Span, code.Text));
                    }
                    if (code.ReadExactWholeWord("ENDHLP"))
                    {
                        funcToken.AddToken(new KeywordToken(scope, code.Span, code.Text));
                    }
                    break;

                case "tag":
                    if (code.ReadTagName())
                    {
                        funcToken.AddToken(new KeywordToken(scope, code.Span, code.Text));
                    }
                    exp2 = ExpressionToken.TryParse(scope, _functionAttribsEndTokens);
                    if (exp2 != null)
                    {
                        funcToken.AddToken(exp2);
                    }
                    break;

                default:
                    return;
                }
            }
        }
Exemplo n.º 2
0
        private static Token ProcessWord(ExpressionToken exp, Scope scope, string word, Span wordSpan)
        {
            // Global keyword that take effect anywhere.
            switch (word)
            {
            case "static":
                return(new KeywordToken(scope, wordSpan, word));
            }

            var code = scope.Code;

            if (code.PeekExact('.'))
            {
                var dotSpan = code.MovePeekedSpan();
                var word2   = code.PeekWordR();
                if (!string.IsNullOrEmpty(word2))
                {
                    var word2Span           = code.MovePeekedSpan();
                    var argsPresent         = (scope.Hint & ScopeHint.SuppressFunctionCall) == 0 && code.PeekExact('(');
                    var argsOpenBracketSpan = argsPresent ? code.MovePeekedSpan() : Span.Empty;

                    foreach (var def in scope.DefinitionProvider.GetAny(wordSpan.Start, word))
                    {
                        if (def.AllowsChild)
                        {
                            // When arguments are present, take only the definitions that accept arguments
                            var childDefs = def.GetChildDefinitions(word2).Where(x => argsPresent ? x.ArgumentsRequired : true).ToArray();
                            if (childDefs.Any())
                            {
                                ArgsToken  argsToken = null;
                                Definition childDef  = null;

                                if (argsPresent)
                                {
                                    var openBracketToken = new OperatorToken(scope, argsOpenBracketSpan, "(");
                                    argsToken = ArgsToken.ParseAndChooseArguments(scope, openBracketToken, childDefs, out childDef);
                                }
                                else
                                {
                                    childDef = childDefs[0];
                                }

                                var word1Token = new IdentifierToken(scope, wordSpan, word, def);
                                var dotToken   = new DotToken(scope, dotSpan);
                                var word2Token = new IdentifierToken(scope, word2Span, word2, childDef);
                                var compToken  = new CompositeToken(scope, childDef.DataType);
                                compToken.AddToken(word1Token);
                                compToken.AddToken(dotToken);
                                compToken.AddToken(word2Token);
                                if (argsToken != null)
                                {
                                    compToken.AddToken(argsToken);
                                }
                                return(compToken);
                            }
                        }
                    }
                }
                else
                {
                    code.Position = dotSpan.Start;
                    return(new UnknownToken(scope, wordSpan, word));
                }
            }

            if ((scope.Hint & ScopeHint.SuppressFunctionCall) == 0 && code.PeekExact('('))
            {
                var argsOpenBracketSpan = code.MovePeekedSpan();

                foreach (var def in scope.DefinitionProvider.GetAny(wordSpan.Start, word))
                {
                    if (def.ArgumentsRequired)
                    {
                        var wordToken        = new IdentifierToken(scope, wordSpan, word, def);
                        var openBracketToken = new OperatorToken(scope, argsOpenBracketSpan, "(");
                        var argsToken        = ArgsToken.Parse(scope, openBracketToken, def.Signature);

                        var compToken = new CompositeToken(scope, def.DataType);
                        compToken.AddToken(wordToken);
                        compToken.AddToken(argsToken);

                        if (def.AllowsFunctionBody && (scope.Hint & ScopeHint.SuppressFunctionDefinition) == 0)
                        {
                            ParseFunctionAttributes(exp, scope, compToken);
                            if (code.PeekExact('{'))
                            {
                                compToken.AddToken(BracesToken.Parse(scope, def, argsToken.Span.End + 1));
                            }
                        }

                        return(compToken);
                    }
                }
            }

            foreach (var def in scope.DefinitionProvider.GetAny(wordSpan.Start, word))
            {
                if (def.ArgumentsRequired || def.RequiresChild)
                {
                    continue;
                }

                return(new IdentifierToken(scope, wordSpan, word, def));
            }

            if (StatementToken.IsStatementBreakingWord(scope, word))
            {
                // There could be a statement without a terminating ';' before this.
                // This can happen if it's a macro that already includes the ';'.
                return(null);
            }

            if (Constants.HighlightKeywords.Contains(word))
            {
                return(new KeywordToken(scope, wordSpan, word));
            }

            return(new UnknownToken(scope, wordSpan, word));
        }