/// <summary> /// Initialize /// </summary> public ExecPlugin() { this.Init("exec"); _funcMeta = new FunctionMetaData("exec", null); _funcMeta.AddArg("program", "string", true, "", string.Empty, @"c:\tools\nunit\nunit.exe", "program to launch"); _funcMeta.AddArg("workingdir", "string", false, "in", string.Empty, @"c:\tools\nunit\", "working directory to launch in"); _funcMeta.AddArg("args", "list", false, "", string.Empty, "", "arguments to the program"); _funcMeta.AddArg("failOnError","bool", false, "", false, "", "arguments to the program"); }
/// <summary> /// Metadata about the function. /// </summary> /// <param name="meta"></param> public ExecExpr(FunctionMetaData meta) { Init(meta); }
private static IDictionary<Token, bool> BuildEndTokens(bool enableNewLineAsEnd, FunctionMetaData meta) { var endTokens = new Dictionary<Token, bool>(); var formalEndTokens = enableNewLineAsEnd ? Terminators.ExpFluentFuncExpParenEnd : Terminators.ExpFuncExpEnd; foreach (var pair in formalEndTokens) endTokens[pair.Key] = true; if (meta == null) return endTokens; // Go through all the arguments and use the if (meta.ArgumentsLookup != null && meta.ArgumentsLookup.Count > 0) { // Add all the parameter names and aliases to the map. foreach (var pair in meta.ArgumentsLookup) { var idToken = TokenBuilder.ToIdentifier(pair.Value.Name); endTokens[idToken] = true; if (!string.IsNullOrEmpty(pair.Value.Alias)) { idToken = TokenBuilder.ToIdentifier(pair.Value.Alias); endTokens[idToken] = true; } } } return endTokens; }
/// <summary> /// Initialize /// </summary> /// <param name="name">name of function</param> /// <param name="argNames">names of the arguments.</param> public void Init(string name, List<string> argNames) { _meta = new FunctionMetaData(name, argNames); _meta.Doc = new DocTags(); _meta.Version = new Version(1, 0, 0, 0); ExecutionCount = 0; }
/// <summary> /// Resolve the parameters in the function call. /// </summary> public static void ResolveParametersForScriptFunction(FunctionMetaData meta, List<Expr> paramListExpressions, List<object> paramList) { int totalParams = meta.Arguments == null ? 0 : meta.Arguments.Count; ResolveParameters(totalParams, paramListExpressions, paramList, namedParam => meta.ArgumentsLookup[namedParam.Name].Index, namedParam => meta.ArgumentsLookup.ContainsKey(namedParam.Name)); }
/// <summary> /// Parses parameters. /// </summary> /// <param name="args">The list of arguments to store.</param> /// <param name="tokenIt">The token iterator</param> /// <param name="parser">The parser</param> /// <param name="meta">The function meta for checking parameters</param> /// <param name="expectParenthesis">Whether or not to expect parenthis to designate the start of the parameters.</param> /// <param name="enableNewLineAsEnd">Whether or not to treat a newline as end</param> public static void ParseFuncParameters(List<Expr> args, TokenIterator tokenIt, Parser parser, bool expectParenthesis, bool enableNewLineAsEnd, FunctionMetaData meta) { int totalParameters = 0; if (tokenIt.NextToken.Token == Tokens.LeftParenthesis) expectParenthesis = true; // START with check for "(" if (expectParenthesis) tokenIt.Expect(Tokens.LeftParenthesis); bool passNewLine = !enableNewLineAsEnd; var endTokens = BuildEndTokens(enableNewLineAsEnd, meta); int totalNamedParams = 0; var hasMetaArguments = meta != null && meta.ArgumentNames != null && meta.ArgumentNames.Count > 0; while (true) { Expr exp = null; // Check for end of statment or invalid end of script. if (parser.IsEndOfParameterList(Tokens.RightParenthesis, enableNewLineAsEnd)) break; if (tokenIt.NextToken.Token == Tokens.Comma) tokenIt.Advance(); var token = tokenIt.NextToken.Token; var peek = tokenIt.Peek().Token; var isVar = parser.Context.Symbols.Contains(token.Text); var isParamNameMatch = hasMetaArguments && meta.ArgumentsLookup.ContainsKey(token.Text); var isKeywordParamName = token.Kind == TokenKind.Keyword && isParamNameMatch; // CASE 1: Named params for external c# object method calls // CASE 2: Named params for internal script functions ( where we have access to its param metadata ) if ( (meta == null && token.Kind == TokenKind.Ident && peek == Tokens.Colon ) || (token.Kind == TokenKind.Ident && isParamNameMatch && !isVar) || (token.Kind == TokenKind.Ident && !isParamNameMatch && !isVar && peek == Tokens.Colon) || (isKeywordParamName && !isVar ) ) { var paramName = token.Text; var namedParamToken = tokenIt.NextToken; tokenIt.Advance(); // Advance and check if ":" if (tokenIt.NextToken.Token == Tokens.Colon) tokenIt.Advance(); exp = parser.ParseExpression(endTokens, true, false, true, passNewLine, true); exp = Exprs.NamedParam(paramName, exp, namedParamToken); args.Add(exp); totalNamedParams++; } // CASE 2: Name of variable being passed to function is same as one of the parameter names. else if (isVar && hasMetaArguments && meta.ArgumentsLookup.ContainsKey(token.Text)) { // Can not have normal parameters after named parameters. if (totalNamedParams > 0) throw tokenIt.BuildSyntaxException("Un-named parameters must come before named parameters"); var next = tokenIt.Peek(); if (next.Token.Kind == TokenKind.Symbol) exp = parser.ParseExpression(endTokens, true, false, true, passNewLine, false); else exp = parser.ParseIdExpression(); args.Add(exp); } // CASE 3: Normal param else { // Can not have normal parameters after named parameters. if (totalNamedParams > 0) throw tokenIt.BuildSyntaxException("Un-named parameters must come before named parameters"); exp = parser.ParseExpression(endTokens, true, false, true, passNewLine, true); args.Add(exp); } totalParameters++; parser.Context.Limits.CheckParserFunctionParams(exp, totalParameters); // Check for end of statment or invalid end of script. if (parser.IsEndOfParameterList(Tokens.RightParenthesis, enableNewLineAsEnd)) break; // Advance if not using fluent-parameters if(meta == null) tokenIt.Expect(Tokens.Comma); } // END with check for ")" if (expectParenthesis) tokenIt.Expect(Tokens.RightParenthesis); }
/// <summary> /// Initailizes with function metadata. /// </summary> /// <param name="meta"></param> public void Init(FunctionMetaData meta) { _fmeta = meta; ParamList = new List<object>(); ParamListExpressions = new List<Expr>(); }
/// <summary> /// Define a function symbol within this scope. /// </summary> /// <param name="func">The function metadata</param> /// <param name="functionExpr">The function expression object that can execute the function</param> public virtual void DefineFunction(FunctionMetaData func, object functionExpr) { _current.DefineFunction(func, functionExpr); }
/// <summary> /// Define a function symbol within this scope. /// </summary> /// <param name="func">The function metadata</param> public void DefineFunction(FunctionMetaData func) { _current.DefineFunction(func); }
/// <summary> /// Define a function symbol within this scope. /// </summary> /// <param name="func">The function metadata</param> public virtual void DefineFunction(FunctionMetaData func) { var symbol = new SymbolFunction(func); this.Define(symbol); }
/// <summary> /// Creates functionmetadata object with the supplied inputs. /// </summary> /// <param name="memberType">What type of member e.g. property,function.</param> /// <param name="name">The name of the function</param> /// <param name="implementationMethod">The method that implements the funcion in this host language.</param> /// <param name="returnType">The return values type</param> /// <param name="description">Description of the function.</param> /// <returns></returns> private FunctionMetaData AddMethodInfo(MemberTypes memberType, string name, string implementationMethod, Type returnType, string description) { var funcdef = new FunctionMetaData(name, null); funcdef.Doc = new Docs.DocTags(); // Todo: funcdef.ReturnType = LangTypeHelper.ConvertToLangType(returnType); funcdef.Doc.Summary = description; var mappedMethod = new MappedMethod(); mappedMethod.DataTypeMethod = name; mappedMethod.HostLanguageMethod = implementationMethod; mappedMethod.FuncDef = funcdef; _methodMap[name] = mappedMethod; _allMembersMap[name] = memberType; return funcdef; }