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; } } }
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)); }