예제 #1
0
        /// <summary>
        /// Calls the custom function.
        /// </summary>
        /// <param name="name">Name of the function</param>
        /// <param name="exp"></param>
        /// <returns></returns>
        public object Call(string name, FunctionCallExpr exp, IAstVisitor visitor)
        {
            var objectName = name;
            var method = string.Empty;
            Func<string, string, FunctionCallExpr, object> callback = null;

            // Contains callback for full function name ? e.g. CreateUser
            if (_customCallbacks.ContainsKey(name))
                callback = _customCallbacks[name];

            // Contains callback that handles multiple methods on a "object".
            // e.g. Blog.Create, Blog.Delete etc.
            if (name.Contains("."))
            {
                var ndxDot = name.IndexOf(".");
                objectName = name.Substring(0, ndxDot);
                method = name.Substring(ndxDot + 1);
                if (_customCallbacks.ContainsKey(objectName + ".*"))
                    callback = _customCallbacks[objectName + ".*"];
            }

            if (callback == null)
                return LObjects.Null;

            // 1. Resolve parameter froms expressions into Lang values.
            ParamHelper.ResolveParametersToHostLangValues(exp.ParamListExpressions, exp.ParamList, visitor);
            object result = callback(objectName, method, exp);
            return result;
        }
예제 #2
0
        /// <summary>
        /// Prints to the console.
        /// </summary>
        /// /// <param name="settings">Settings for interpreter</param>
        /// <param name="exp">The functiona call expression</param>
        /// <param name="printline">Whether to print with line or no line</param>
        public static string Print(LangSettings settings, FunctionCallExpr exp, bool printline)
        {
            if (!settings.EnablePrinting) return string.Empty;

            string message = BuildMessage(exp.ParamList);
            if (printline) Console.WriteLine(message);
            else Console.Write(message);
            return message;
        }
예제 #3
0
 /// <summary>
 /// Logs severity to console.
 /// </summary>
 /// <param name="settings">Settings for interpreter</param>
 /// <param name="exp">The functiona call expression</param>
 public static string Log(LangSettings settings, FunctionCallExpr exp)
 {
     if (!settings.EnableLogging) return string.Empty;
     var funcname = exp.ToQualifiedName();
     var severity =funcname.Substring(funcname.IndexOf(".") + 1);
     var message = BuildMessage(exp.ParamList);
     Console.WriteLine(severity.ToUpper() + " : " + message);
     return message;
 }
예제 #4
0
        /// <summary>
        /// Calls the custom function.
        /// </summary>
        /// <param name="name">Name of the function</param>
        /// <param name="exp"></param>
        /// <returns></returns>
        public object Call(string name, FunctionCallExpr exp)
        {
            var callback = GetByName(name);

            // 1. Resolve parameter froms expressions into Lang values.
            ParamHelper.ResolveParametersToHostLangValues(exp.ParamListExpressions, exp.ParamList);
            object result = callback(exp);
            return result;
        }
예제 #5
0
        /// <summary>
        /// Push the function expression on the call stack
        /// </summary>
        /// <param name="qualifiedName">Name of function call</param>
        /// <param name="exp">Function Call expression</param>
        public bool Push(string qualifiedName, FunctionCallExpr exp)
        {
            _stack.Add(new Tuple<string, FunctionCallExpr>(qualifiedName, exp));
            _lastIndex++;

            if (_limitCheck != null)
                _limitCheck(exp, _lastIndex);

            return true;
        }
예제 #6
0
        /// <summary>
        /// Calls an internal function or external function.
        /// </summary>
        /// <param name="ctx">The context of the runtime.</param>
        /// <param name="fexpr">The function call expression</param>
        /// <param name="functionName">The name of the function. if not supplied, gets from the fexpr</param>
        /// <param name="pushCallStack"></param>
        /// <returns></returns>
        public static object CallFunction(Context ctx, FunctionCallExpr fexpr, string functionName, bool pushCallStack, IAstVisitor visitor)
        {
            if(string.IsNullOrEmpty(functionName))
                functionName = fexpr.NameExp.ToQualifiedName();

            // 1. Check if script func or extern func.
            var isScriptFunc = fexpr.SymScope.IsFunction(functionName);
            var isExternFunc = ctx.ExternalFunctions.Contains(functionName);

            // 2. If neither, this is an error scenario.
            if (!isScriptFunc && !isExternFunc)
                throw ExceptionHelper.BuildRunTimeException(fexpr, "Function does not exist : '" + functionName + "'");

            // 3. Push the name of the function on teh call stack
            if(pushCallStack)
                ctx.State.Stack.Push(functionName, fexpr);

            // 4. Call the function.
            object result = null;
            // Case 1: Custom C# function blog.create blog.*
            if (isExternFunc)
                result = ctx.ExternalFunctions.Call(functionName, fexpr, visitor);

            // Case 2: Script functions "createUser('john');"
            else
            {
                var sym = fexpr.SymScope.GetSymbol(functionName) as SymbolFunction;
                var func = sym.FuncExpr as FunctionExpr;
                result = FunctionHelper.CallFunctionInScript(ctx, func, functionName, fexpr.ParamListExpressions,
                                                             fexpr.ParamList, true, visitor);
            }
            // 3. Finnaly pop the call stact.
            if(pushCallStack)
                ctx.State.Stack.Pop();

            result = CheckConvert(result);
            return result;
        }
예제 #7
0
 /// <summary>
 /// Visits the function call expression tree
 /// </summary>
 /// <param name="exp"></param>
 public object VisitFunctionCall(FunctionCallExpr exp)
 {
     _callBackOnNodeStart(exp);
     foreach (var paramExp in exp.ParamListExpressions)
         _callBackOnNodeStart(paramExp);
     _callBackOnNodeEnd(exp);
     return null;
 }
예제 #8
0
        /// <summary>
        /// Parses the fluent function call.
        /// </summary>
        /// <returns></returns>
        public override Expr Parse()
        {
            // 1. Is it a function call?
            var fnameToken = _tokenIt.NextToken;

            _tokenIt.Advance(_result.TokenCount);

            string remainderOfFuncName = string.Empty;
            var parts = new List<Expr>();
            TokenData firstPart = null;

            // NOTES:
            // Given: function "Find user by" *
            // And: called via Find use by name role
            // wildcard part 1: name
            // wildcard part 2: role
            // full wildcard: "name role"
            var partsToken = _tokenIt.NextToken;
            // 1. Capture all the remaining parts of the wild card.
            while (_tokenIt.NextToken.Token.Kind == TokenKind.Ident)
            {
                string part = _tokenIt.NextToken.Token.Text;

                // a. Store the token of the first wildcard part
                if(firstPart == null)
                    firstPart = _tokenIt.NextToken;

                // b. Build up the full name from all wildcards
                remainderOfFuncName += " " + part;

                // c. Create a constant expr from the wildcard
                // as it will be part of an array of strings passed to function
                var partExp = Exprs.Const(new LString(part), _tokenIt.NextToken);
                parts.Add(partExp);

                // d. Move to the next token for another possible wildcard.
                _tokenIt.Advance();

                // e. Check for end of statement.
                if (_tokenIt.IsEndOfStmtOrBlock())
                    break;
            }

            var exp = new FunctionCallExpr();
            exp.ParamListExpressions = new List<Expr>();
            exp.ParamList = new List<object>();
            remainderOfFuncName = remainderOfFuncName.Trim();
            var fullWildCard = Exprs.Const(new LString(string.Empty), fnameToken) as ConstantExpr;

            // 2. Create a constant expr representing the full wildcard
            if(!string.IsNullOrEmpty(remainderOfFuncName))
            {
                fullWildCard.Value = remainderOfFuncName;
                _parser.SetupContext(fullWildCard, firstPart);
            }

            var token = _tokenIt.NextToken.Token;

            // CASE 1: Parse parameters with parenthesis "("
            if (token == Tokens.LeftParenthesis)
            {
                _parser.ParseParameters(exp, true, false, false);
            }
            // CASE 2: Parse parameters with ":" until newline.
            else if (token == Tokens.Colon)
            {
                _tokenIt.Advance();
                _parser.ParseParameters(exp, false, false, true);
            }
            exp.NameExp = Exprs.Ident(_result.Name, fnameToken);
            // Have to restructure the arguments.
            // 1. const expr     , fullwildcard,   "name role"
            // 2. list<constexpr>, wildcard parts, ["name", "role"]
            // 3. list<expr>,      args,           "kishore", "admin"
            var args = new List<Expr>();
            args.Add(fullWildCard);
            args.Add(Exprs.Array(parts, partsToken));
            args.Add(Exprs.Array(exp.ParamListExpressions, fnameToken));

            // Finally reset the parameters expr on the function call.
            exp.ParamListExpressions = args;
            return exp;
        }
예제 #9
0
        /// <summary>
        /// Checks function call expressions for correct number of parameters.
        /// </summary>
        /// <param name="semActs">The semantic analyser</param>
        /// <param name="exp">The functioncallexpression</param>
        private SemanticCheckResult CheckFunctionCall(SemActs semActs, FunctionCallExpr exp)
        {
            var functionName = exp.ToQualifiedName();
            var exists = exp.SymScope.IsFunction(functionName);

            // 1. Function does not exist.
            if (!exists)
            {
                return AddErrorCode(ErrorCodes.Func1000, exp, functionName);
            }
            var sym = exp.SymScope.GetSymbol(functionName) as SymbolFunction;
            var func = sym.FuncExpr as FunctionExpr;

            // 5. Check that named parameters exist.
            foreach(var argExpr in exp.ParamListExpressions)
            {
                if(argExpr.IsNodeType(NodeTypes.SysNamedParameter))
                {
                    var argName = ((NamedParamExpr) argExpr).Name;
                    if (!func.Meta.ArgumentsLookup.ContainsKey(argName))
                        AddErrorCode(ErrorCodes.Func1002, exp, argName);
                }
            }
            return SemanticCheckResult.Valid;
        }
예제 #10
0
        /// <summary>
        /// run step 123.
        /// </summary>
        /// <returns></returns>
        public override Expr Parse()
        {
            _tokenIt.Expect(Tokens.Run);

            // run function 'name';
            // run function touser();
            if (_tokenIt.NextToken.Token == Tokens.Function)
                _tokenIt.Advance();

            // 'username'
            if (!(_tokenIt.NextToken.Token.IsLiteralAny() || _tokenIt.NextToken.Token.Kind == TokenKind.Ident))
                _tokenIt.BuildSyntaxExpectedException("identifier or string");

            var name = _tokenIt.NextToken.Token.Text;

            // Case 1: run 'step1';
            // Case 2: run step1;
            var next = _tokenIt.Peek();
            if (next.Token != Tokens.LeftParenthesis && next.Token != Tokens.Dot)
            {
                var funcExp = new FunctionCallExpr();
                funcExp.NameExp = _parser.ToIdentExpr(name, null);
                _parser.State.FunctionCall++;

                //Ctx.Limits.CheckParserFuncCallNested(_tokenIt.NextToken, _parser.State.FunctionCall);
                _parser.State.FunctionCall--;

                // Move past this plugin
                _tokenIt.Advance();
                return funcExp;
            }

            // Case 3: run step1();
            Expr exp = _parser.ParseIdExpression(name);
            return exp;
        }
예제 #11
0
 /// <summary>
 /// Calls the custom function.
 /// </summary>
 /// <param name="exp"></param>
 /// <returns></returns>
 public object Call(FunctionCallExpr exp)
 {
     return CallByName(exp.ToQualifiedName(), exp.ParamListExpressions, exp.ParamList, true);
 }
예제 #12
0
        /// <summary>
        /// Evauate and run the function
        /// </summary>
        /// <returns></returns>
        public object VisitFunctionCall(FunctionCallExpr expr)
        {
            object result = null;

            // CASE 1: Exp is variable -> internal/external script. "getuser()".
            if (expr.NameExp.IsNodeType(NodeTypes.SysVariable))
            {
                return FunctionHelper.CallFunction(this.Ctx, expr, null, true, this);
            }

            // At this point, is a method call on an object.
            var member = expr.NameExp.Evaluate(this);
            result = member;
            var isMemberAccessType = member is MemberAccess;
            if (!isMemberAccessType) return result;

            var callStackName = expr.NameExp.ToQualifiedName();
            var maccess = member as MemberAccess;
            if (!IsMemberCall(maccess)) return result;

            this.Ctx.State.Stack.Push(callStackName, expr);
            // CASE 2: Module.Function
            if (maccess.Mode == MemberMode.FunctionScript && maccess.Expr != null)
            {
                var fexpr = maccess.Expr as FunctionExpr;
                result = FunctionHelper.CallFunctionInScript(this.Ctx, fexpr, fexpr.Meta.Name, expr.ParamListExpressions, expr.ParamList, true, this);
            }
            // CASE 3: object "." method call from script is a external/internal function e.g log.error -> external c# callback.
            else if (maccess.IsInternalExternalFunctionCall())
            {
                result = FunctionHelper.CallFunction(Ctx, expr, maccess.FullMemberName, false, this);
            }
            // CASE 4: Method call / Property on Language types
            else if (maccess.Type != null)
            {
                result = FunctionHelper.CallMemberOnBasicType(this.Ctx, expr, maccess, expr.ParamListExpressions, expr.ParamList, this);
            }
            // CASE 5: Member call via "." : either static or instance method call. e.g. Person.Create() or instance1.FullName() e.g.
            else if (maccess.Mode == MemberMode.CustObjMethodStatic || maccess.Mode == MemberMode.CustObjMethodInstance)
            {
                result = FunctionHelper.CallMemberOnClass(this.Ctx, expr, maccess, expr.ParamListExpressions, expr.ParamList, this);
            }
            // Pop the function name off the call stack.
            this.Ctx.State.Stack.Pop();
            return result;
        }
예제 #13
0
        private object RunCompilerMethod(string objectName, string method, LangSettings settings, FunctionCallExpr ex)
        {
            var metaCompiler = new MetaCompiler();
            metaCompiler.Ctx = ex.Ctx;

            if(method == "ToConstDate")
            {

            }
            else if(method == "ToConstTime")
            {

            }
            else if(method == "ToConstDateTimeToken")
            {
                var dateToken = ex.ParamList[0] as TokenData;
                var timeToken = ex.ParamList[1] as TokenData;
                return metaCompiler.ToConstDateTimeToken(dateToken, timeToken);
            }
            else if (method == "ToConstDay")
            {
                var token = ex.ParamList[0] as TokenData;
                var day = Convert.ToInt32(ex.ParamList[1]);
                return metaCompiler.ToConstDay(day, token);
            }
            return LObjects.Null;
        }
예제 #14
0
 /// <summary>
 /// Creates a function call expression.
 /// </summary>
 /// <param name="nameExpr"></param>
 /// <param name="parameters"></param>
 /// <param name="token"></param>
 /// <returns></returns>
 public static Expr FunctionCall(Expr nameExpr, List<Expr> parameters, TokenData token)
 {
     var funcExp = new FunctionCallExpr();
     funcExp.NameExp = nameExpr;
     funcExp.ParamListExpressions = parameters == null ? new List<Expr>() : parameters;
     funcExp.ParamList = new List<object>();
     SetupContext(funcExp, token);
     return funcExp;
 }
예제 #15
0
 /// <summary>
 /// Creates a function call expression.
 /// </summary>
 /// <param name="nameExpr"></param>
 /// <param name="parameters"></param>
 /// <param name="token"></param>
 /// <returns></returns>
 public Expr ToFunctionCallExpr(Expr nameExpr, List<Expr> parameters, TokenData token)
 {
     var funcExp = new FunctionCallExpr();
     funcExp.NameExp = nameExpr;
     funcExp.ParamMap = new Dictionary<string, object>();
     this.SetupContext(funcExp, token);
     return funcExp;
 }
예제 #16
0
        /// <summary>
        /// Sorts expression
        /// </summary>
        /// <returns></returns>
        public override Expr Parse(object context)
        {
            var constExp = context as ConstantExpr;
            var c = _tokenIt.NextToken;
            var t = _tokenIt.Advance();
            _parser.SetupContext(constExp, c);

            // Get the function symbol.
            var fce = new FunctionCallExpr();
            fce.NameExp = _parser.ToIdentExpr(t.Token.Text, t);
            fce.ParamListExpressions.Add(constExp);

            // Move the postfix token.
            _tokenIt.Advance();
            return fce;
        }