public static Object Invoke(ScriptObject func, Engine engine, Context context, ScriptList arguments) { var name = func.gsp("@name"); var argumentInfo = func["@arguments"] as ScriptList; if (context.trace != null) { context.trace(new String('.', context.traceDepth) + "Entering " + name +"\n"); context.traceDepth += 1; } var newArguments = new ScriptList(); //Check argument types if (argumentInfo.Count == 0 && arguments.Count != 0) { context.RaiseNewError("Function expects no arguments.", context.currentNode); return null; } int argumentIndex = 0; for (int i = 0; i < argumentInfo.Count; ++i) { var info = argumentInfo[i] as ScriptObject; if (info == null) throw new ScriptError("Invalid argument descriptor on function object", context.currentNode); if (info["@repeat"] != null) { var list = new ScriptList(); while (argumentIndex < arguments.Count) //Handy side effect: If no argument is passed for an optional repeat { //argument, it will get an empty list. list.Add(MutateArgument(arguments[argumentIndex], info, engine, context)); //list.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex])); if (context.evaluationState != EvaluationState.Normal) return null; ++argumentIndex; } newArguments.Add(list); } else { if (argumentIndex < arguments.Count) { newArguments.Add(MutateArgument(arguments[argumentIndex], info, engine, context)); //newArguments.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex])); if (context.evaluationState == EvaluationState.UnwindingError) return null; } else if (info["@optional"] != null) newArguments.Add(MutateArgument(null, info, engine, context)); else { context.RaiseNewError("Not enough arguments to " + name, context.currentNode); return null; } ++argumentIndex; } } if (argumentIndex < arguments.Count) { context.RaiseNewError("Too many arguments to " + name, context.currentNode); return null; } Object r = null; if (func["@function-body"] is ScriptObject) { var declarationScope = func["@declaration-scope"]; if (declarationScope is GenericScriptObject) { var newScope = new Scope(); foreach (var valueName in (declarationScope as GenericScriptObject).properties) newScope.PushVariable(valueName.Key, valueName.Value); func["@declaration-scope"] = newScope; } context.PushScope(func["@declaration-scope"] as Scope); for (int i = 0; i < argumentInfo.Count; ++i) context.Scope.PushVariable((argumentInfo[i] as ScriptObject).gsp("@name"), newArguments[i]); r = engine.Evaluate(context, func["@function-body"], true); for (int i = 0; i < argumentInfo.Count; ++i) context.Scope.PopVariable((argumentInfo[i] as ScriptObject).gsp("@name")); context.PopScope(); } else { try { r = (func["@function-body"] as Func<Context, ScriptList, Object>)(context, newArguments); } catch (Exception e) { context.RaiseNewError("System Exception: " + e.Message, context.currentNode); return null; } } if (context.trace != null) { context.traceDepth -= 1; context.trace(new String('.', context.traceDepth) + "Leaving " + name + (context.evaluationState == EvaluationState.UnwindingError ? (" -Error: " + context.errorObject.GetLocalProperty("message").ToString()) : "") + (context.evaluationState == EvaluationState.UnwindingBreak ? " -Breaking" : "") + "\n"); } return r; }
public static Object Invoke(ScriptObject func, Engine engine, Context context, ScriptList arguments) { var name = func.gsp("@name"); var argumentInfo = func["@arguments"] as ScriptList; if (context.trace != null) { context.trace(new String('.', context.traceDepth) + "Entering " + name + "\n"); context.traceDepth += 1; } var newArguments = new ScriptList(); //Check argument types if (argumentInfo.Count == 0 && arguments.Count != 0) { context.RaiseNewError("Function expects no arguments.", context.currentNode); return(null); } int argumentIndex = 0; for (int i = 0; i < argumentInfo.Count; ++i) { var info = argumentInfo[i] as ScriptObject; if (info == null) { throw new ScriptError("Invalid argument descriptor on function object", context.currentNode); } if (info["@repeat"] != null) { var list = new ScriptList(); while (argumentIndex < arguments.Count) //Handy side effect: If no argument is passed for an optional repeat { //argument, it will get an empty list. list.Add(MutateArgument(arguments[argumentIndex], info, engine, context)); //list.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex])); if (context.evaluationState != EvaluationState.Normal) { return(null); } ++argumentIndex; } newArguments.Add(list); } else { if (argumentIndex < arguments.Count) { newArguments.Add(MutateArgument(arguments[argumentIndex], info, engine, context)); //newArguments.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex])); if (context.evaluationState == EvaluationState.UnwindingError) { return(null); } } else if (info["@optional"] != null) { newArguments.Add(MutateArgument(null, info, engine, context)); } else { context.RaiseNewError("Not enough arguments to " + name, context.currentNode); return(null); } ++argumentIndex; } } if (argumentIndex < arguments.Count) { context.RaiseNewError("Too many arguments to " + name, context.currentNode); return(null); } Object r = null; if (func["@function-body"] is ScriptObject) { var declarationScope = func["@declaration-scope"]; if (declarationScope is GenericScriptObject) { var newScope = new Scope(); foreach (var valueName in (declarationScope as GenericScriptObject).properties) { newScope.PushVariable(valueName.Key, valueName.Value); } func["@declaration-scope"] = newScope; } context.PushScope(func["@declaration-scope"] as Scope); for (int i = 0; i < argumentInfo.Count; ++i) { context.Scope.PushVariable((argumentInfo[i] as ScriptObject).gsp("@name"), newArguments[i]); } r = engine.Evaluate(context, func["@function-body"], true); for (int i = 0; i < argumentInfo.Count; ++i) { context.Scope.PopVariable((argumentInfo[i] as ScriptObject).gsp("@name")); } context.PopScope(); } else { try { r = (func["@function-body"] as Func <Context, ScriptList, Object>)(context, newArguments); } catch (Exception e) { context.RaiseNewError("System Exception: " + e.Message, context.currentNode); return(null); } } if (context.trace != null) { context.traceDepth -= 1; context.trace(new String('.', context.traceDepth) + "Leaving " + name + (context.evaluationState == EvaluationState.UnwindingError ? (" -Error: " + context.errorObject.GetLocalProperty("message").ToString()) : "") + (context.evaluationState == EvaluationState.UnwindingBreak ? " -Breaking" : "") + "\n"); } return(r); }