/// <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; var resolveParams = !expr.RetainEvaluatedParams; result = FunctionHelper.CallFunctionInScript(this.Ctx, this, fexpr.Meta.Name, fexpr, expr.ParamListExpressions, expr.ParamList, resolveParams); } // 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); }
/// <summary> /// Evauate and run the function /// </summary> /// <returns></returns> public override object DoEvaluate() { object result = null; bool isNameEmpty = string.IsNullOrEmpty(_name); // CASE 1: Exp is variable -> internal/external script. "getuser()". if (this.NameExp is VariableExpr) { return(FunctionHelper.CallFunction(this.Ctx, this, null, true)); } // At this point, is a method call on an object. var member = this.NameExp.Evaluate(); result = member; var isMemberAccessType = member is MemberAccess; if (!isMemberAccessType) { return(result); } var callStackName = this.NameExp.ToQualifiedName(); var maccess = member as MemberAccess; if (!IsMemberCall(maccess)) { return(result); } this.Ctx.State.Stack.Push(callStackName, this); // CASE 3: object "." method call from script is a external/internal function e.g log.error -> external c# callback. if (maccess.IsInternalExternalFunctionCall()) { result = FunctionHelper.CallFunction(Ctx, this, maccess.FullMemberName, false); } // CASE 4: Method call / Property on Language types else if (maccess.Type != null) { result = FunctionHelper.CallMemberOnBasicType(this.Ctx, this, maccess, this.ParamListExpressions, this.ParamList); } // 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, this, maccess, this.ParamListExpressions, this.ParamList); } // Pop the function name off the call stack. this.Ctx.State.Stack.Pop(); return(result); }