public static void SetupMacroArgs(ConsNode definedArgs, FunctionInvocation call, Scope newScope) { int i = 1; //todo: verify arg list, only identifiers allowed //setup local args for (int argIndex = 0; argIndex < definedArgs.Args.Count; argIndex++) { var arg = definedArgs.Args[argIndex] as SymbolNode; string argName = arg.Name; if (argName == "&optional") {} else if (argName == "&rest") { argIndex++; var restArg = definedArgs.Args[argIndex] as SymbolNode; string restName = restArg.Name; ConsNode restCons = NewCons(call.StackFrame.Root); restCons.Args = call.Args.Skip(i).ToList(); newScope.PushSymbol(restName).Value = restCons; } else { Symbol symbol = newScope.PushSymbol(argName); object bodyArg = call.Args[i]; symbol.Value = bodyArg; } i++; } }
public object HandleCall(FunctionInvocation call, string methodName) { var var = call.Args[1] as ValueNode; object target = var.Eval(call.StackFrame); int paramCount = call.Args.Count - 3; MethodInfo[] methods = (from mi in target.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy) where mi.Name == methodName && mi.GetParameters().Length == paramCount select mi).ToArray(); MethodInfo method = methods[0]; var methodArgs = new object[paramCount]; for (int i = 0; i < paramCount; i++) { object arg = Utils.Eval(call.StackFrame, call.Args[i + 3]); if (arg is LispFunc) { var func = arg as LispFunc; Type del = method.GetParameters()[i].ParameterType; MethodInfo invoke = del.GetMethod("Invoke"); ParameterInfo[] invokeParams = invoke.GetParameters(); EventHandler eh = (s, e) => { var args = new List <object>(10); args.Add(new SymbolNode()); args.Add(s); args.Add(e); var newStackFrame = new StackFrame(StackFrame, null); newStackFrame.Function = func; newStackFrame.FunctionName = "{native call}"; var kall = new FunctionInvocation(func, args, newStackFrame); //foreach (ParameterInfo invokeParam in invokeParams) //{ // kall.Args.Add(new PrimitiveValueNode<object>(null)); //} func(kall); }; arg = eh; } methodArgs[i] = arg; } object res = method.Invoke(target, methodArgs); return(res); }
public object HandleCall(FunctionInvocation call, string methodName) { var var = call.Args[1] as ValueNode; object target = var.Eval(call.StackFrame); int paramCount = call.Args.Count - 3; MethodInfo[] methods = (from mi in target.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy) where mi.Name == methodName && mi.GetParameters().Length == paramCount select mi).ToArray(); MethodInfo method = methods[0]; var methodArgs = new object[paramCount]; for (int i = 0; i < paramCount; i++) { object arg = Utils.Eval(call.StackFrame, call.Args[i + 3]); if (arg is LispFunc) { var func = arg as LispFunc; Type del = method.GetParameters()[i].ParameterType; MethodInfo invoke = del.GetMethod("Invoke"); ParameterInfo[] invokeParams = invoke.GetParameters(); EventHandler eh = (s, e) => { var args = new List<object>(10); args.Add(new SymbolNode()); args.Add(s); args.Add(e); var newStackFrame = new StackFrame(StackFrame, null); newStackFrame.Function = func; newStackFrame.FunctionName = "{native call}"; var kall = new FunctionInvocation(func, args, newStackFrame); //foreach (ParameterInfo invokeParam in invokeParams) //{ // kall.Args.Add(new PrimitiveValueNode<object>(null)); //} func(kall); }; arg = eh; } methodArgs[i] = arg; } object res = method.Invoke(target, methodArgs); return res; }
public static void TearDownArgs(ConsNode definedArgs, FunctionInvocation call) { //int i = 1; ////tear down args //foreach (IdentifierNode arg in definedArgs.Args) //{ // string argName = arg.Name; // if (argName.StartsWith("*")) // { // argName = argName.Substring(1); // call.StackFrame.PopSymbol(argName); // } // else if (argName.StartsWith("!")) // { // argName = argName.Substring(1); // call.StackFrame.PopSymbol(argName); // } // else if (argName.StartsWith("#")) // { // argName = argName.Substring(1); // call.StackFrame.PopSymbol(argName); // } // else if (argName.StartsWith("@")) // { // argName = argName.Substring(1); // call.StackFrame.PopSymbol(argName); // } // else if (argName.StartsWith(":")) // { // } // else // { // call.StackFrame.PopSymbol(argName); // } // i++; //} ////for (int j = i; j < call.Args.Count; j++) ////{ //// ValueNode node = call.Args[j]; //// string argName = string.Format("arg{0}", j); //// stack.PopSymbol(argName); ////} }
public static void SetupArgs(ConsNode definedArgs, FunctionInvocation call, Scope newScope) { int i = 1; //todo: verify arg list, only identifiers allowed //setup local args for (int argIndex = 0; argIndex < definedArgs.Args.Count; argIndex ++) { var arg = definedArgs.Args[argIndex] as SymbolNode; string argName = arg.Name; if (argName == "&optional") {} else if (argName == "&rest") { argIndex ++; var restArg = definedArgs.Args[argIndex] as SymbolNode; string restName = restArg.Name; ConsNode restCons = NewCons(call.StackFrame.Root); restCons.Args = call.EvalArgs(i); newScope.PushSymbol(restName).Value = restCons; } else if (argName[0] == '*') { //ref symbol var argId = call.Args[i] as SymbolNode; argName = argName.Substring(1); if (argId == null) { throw new Exception( string.Format("Argument '{0}' is defined as a pointer, but passed as a value", argName)); } Symbol sourceVar = argId.GetSymbol(call.StackFrame); newScope.DeclareRef(argName, sourceVar); } else if (argName[0] == '!') { argName = argName.Substring(1); newScope.PushSymbol(argName); var bodyArg = call.Args[i] as ValueNode; newScope.SetSymbolValue(argName, bodyCall => bodyArg.Eval(call.StackFrame)); } else if (argName[0] == '#') { argName = argName.Substring(1); Symbol symbol = newScope.PushSymbol(argName); object bodyArg = call.Args[i]; symbol.Value = bodyArg; } else if (argName[0] == ':') { var argId = call.Args[i] as SymbolNode; argName = argName.Substring(1); if (argId == null) { throw new Exception( string.Format("Argument '{0}' is defined as a verbatim, but passed as a value", argName)); } if (argId.Name != argName) { throw new Exception(string.Format("Argument '{0}' is defined as a verbatim, but passed as {1}", argName, argId.Name)); } } else if (argName[0] == '@') { var argId = call.Args[i] as SymbolNode; object argValue = argId.Name; argName = argName.Substring(1); newScope.PushSymbol(argName).Value = argValue; } else { //normal var object argValue = Eval(call.StackFrame, call.Args[i]); newScope.PushSymbol(argName).Value = argValue; } i++; } //for (int j = i; j < call.Args.Count; j++) //{ // ValueNode node = call.Args[j]; // string argName = string.Format("arg{0}", j); // object argValue = node.GetValue(stack); // stack.PushSymbol(argName); // stack.Scope.SetSymbolValue(argName, argValue); //} }
public override object Eval(StackFrame stackFrame) { if (Args.Count == 0) return null; object res = null; object first = Args[0]; var func = Utils.Eval(stackFrame, first) as LispFunc; if (func != null) { string name = ""; if (first is SymbolNode) { name = ((SymbolNode) first).Name; } var newStackFrame = new StackFrame(stackFrame, this); newStackFrame.Function = func; newStackFrame.FunctionName = name; Stack.Engine.OnBeginNotifyCall(newStackFrame, this, func, name); //function var invocation = new FunctionInvocation(func, Args, newStackFrame); try { res = func(invocation); } catch (Exception x) { throw newStackFrame.CreateException(x.Message); } Stack.Engine.OnEndNotifyCall(newStackFrame, this, func, name, res); //int recursions = 0; //while (res is TailRecursionValue) //{ // TailRecursionValue tail = res as TailRecursionValue; // if (!tail.ReadyForEval) // { // tail.ReadyForEval = true; // break; // } // else // { // recursions++; // ConsNode tailCons = tail.Expression as ConsNode; // newStackFrame = new StackFrame(stackFrame, this); // newStackFrame.Function = func; // newStackFrame.FunctionName = name; // Stack.Engine.OnBeginNotifyCall(newStackFrame, this, func, name); // invocation.Args = tailCons.Args; // try // { // res = func(invocation); // } // catch (Exception x) // { // throw newStackFrame.CreateException(x.Message); // } // Stack.Engine.OnEndNotifyCall(newStackFrame, this, func, name, res); // } //} return res; } throw stackFrame.CreateException(string.Format("Invalid function : {0}", this)); }