public override void CheckScope(ParsingContext context) { if (TreeFuncs != null) { Method found = TreeFuncs.FirstOrDefault(func => func.Name == Name.Text); // look for a script function first if (found == null) { // if not found, find all matching extern not case sensitive, and check parameters IEnumerable <Method> matchingExterns = null; matchingExterns = CoreCommands.Funcs.Where(func => func.Name.ToLower() == Name.Text.ToLower()); if (matchingExterns == null || matchingExterns.Count() == 0) { context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Undeclared function {0}.", Name.Text); } else if ((found = matchingExterns.FirstOrDefault(func => AreSameParams(func.Parameters, this.Arguments, true))) == null) { context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Invalid params for core function {0}.", Name.Text); } else { found.AddReference(this); } } else { // check params if ((Arguments == null || Arguments.Count == 0) != (found.Parameters == null || found.Parameters.Count == 0)) { context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Argument mismatch."); } else if (found.Parameters != null && found.Parameters.Count > 0) { if (Arguments == null || Arguments.Count == 0) { context.AddParserMessage(ParserErrorLevel.Error, this.Span, "This function call requires arguments."); } else { for (int i = 0; i < found.Parameters.Count; i++) { if (i >= Arguments.Count) { context.AddParserMessage(ParserErrorLevel.Error, this.ChildNodes[this.ChildNodes.Count - 1].Span, "Insufficient arguments."); break; } if (Arguments[i].UoTypeToken != found.Parameters[i].UoTypeToken) { if (Arguments[i].UoTypeToken == null) { context.AddParserMessage(ParserErrorLevel.Info, this.ChildNodes[i].Span, "Use of \"any\" as a typed argument."); } else { context.AddParserMessage(ParserErrorLevel.Error, this.ChildNodes[i].Span, "Argument type mismatch."); } } } } if (Arguments.Count > found.Parameters.Count) { context.AddParserMessage(ParserErrorLevel.Error, this.ChildNodes[found.Parameters.Count].Span, "Too many arguments."); } } // check location if (found.DefNode == null) { context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Function {0} is declared, but not defined.", found.Name); } else if (found.DefFilename == context.CurrentParseTree.FileName && found.DefNode.Location.Position > this.Location.Position && (found.ForwardNode == null || found.ForwardNode.Location.Position > this.Location.Position)) { context.AddParserMessage(ParserErrorLevel.Error, this.Span, "Function {0} must be declared before it is used.", found.Name); } } if (found != null) { this.SetUoTypeToken(found.UoTypeToken); found.AddReference(this); } } }