Пример #1
0
        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++;
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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;
        }
Пример #4
0
        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);
            ////}
        }
Пример #5
0
        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);
            //}
        }
Пример #6
0
        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));
        }