public static ArgsToken ParseAndChooseArguments(Scope scope, OperatorToken openBracketToken, Definition[] sigDefs, out Definition selectedDef) { #if DEBUG if (sigDefs == null) { throw new ArgumentNullException("sigDefs"); } if (sigDefs.Length == 0) { throw new ArgumentException("sigDefs must contain at least one signature definition."); } #endif if (sigDefs.Length == 1) { selectedDef = sigDefs[0]; return(Parse(scope, openBracketToken, sigDefs[0].ArgumentsSignature)); } var code = scope.Code; var ret = new ArgsToken(scope, openBracketToken); scope = scope.Clone(); scope.Hint |= ScopeHint.SuppressStatementStarts; var tokens = new List <Token>(); var dataTypes = new List <DataType>(); List <Token> bestTokens = null; var bestConfidence = 0.0f; Definition bestSigDef = null; var codeResetPos = code.Position; foreach (var sigDef in sigDefs) { var args = sigDef.Arguments.ToArray(); var argIndex = 0; var expectingDataType = true; tokens.Clear(); dataTypes.Clear(); code.Position = codeResetPos; while (code.SkipWhiteSpace()) { code.Peek(); if (code.Text == ")") { tokens.Add(new OperatorToken(scope, code.MovePeekedSpan(), ")")); ret._terminated = true; break; } else if (code.Text == ",") { tokens.Add(new OperatorToken(scope, code.MovePeekedSpan(), ",")); argIndex++; expectingDataType = true; continue; } var exp = ExpressionToken.TryParse(scope, _endTokens, expectedDataType: argIndex < args.Length ? args[argIndex].DataType : null); if (exp != null) { tokens.Add(exp); if (expectingDataType) { dataTypes.Add(exp.ValueDataType); } expectingDataType = false; } else { break; } } if (dataTypes.Count == args.Length) { var confidence = 1.0f; for (int i = 0, ii = args.Length; i < ii; i++) { confidence *= DataType.CalcArgumentCompatibility(args[i].DataType, dataTypes[i]); } if (confidence > bestConfidence) { bestConfidence = confidence; bestTokens = tokens; bestSigDef = sigDef; } } else if (bestTokens == null) { bestTokens = tokens; bestConfidence = 0.0f; bestSigDef = sigDef; } } ret.AddTokens(bestTokens); ret._sig = bestSigDef.ArgumentsSignature; ret._sigAlternatives = (from s in sigDefs where s.ArgumentsSignature != ret._sig select s.ArgumentsSignature).ToArray(); selectedDef = bestSigDef; return(ret); }