Beispiel #1
0
            public static void Setup()
            {
                var invo = new InvokeableItem();
                var fn   = new Invokeable
                {
                    ReturnType = ItemType.Space,

                    Demands = InvokeableUtils.MakeDemands(
                        InvokeableUtils.DemandType(0, ItemType.List),
                        args => (args[0] as ListItem).Expression.HasEvenLength(),
                        args => (args[0] as ListItem).Expression
                        .GroupingSelect(2)
                        .All(pair => pair[0].ItemType == ItemType.Symbol)),

                    Function = (space, args) =>
                    {
                        var newSpace         = new SymbolSpace(space);
                        var symbolValuePairs = (args[0] as ListItem).Expression.GroupingSelect(2);

                        foreach (var pair in symbolValuePairs)
                        {
                            var symbol = pair[0] as SymbolItem;
                            newSpace.Bind(symbol.Name, pair[1]);
                        }

                        return(new SymbolSpaceItem(newSpace));
                    }
                };

                invo.AddInvokeable(fn);
                globalSpace.Bind("make-space", invo);
            }
Beispiel #2
0
            public static void Setup()
            {
                const int typeIndex   = 0;
                const int paramsIndex = 1;
                const int bodyIndex   = 2;

                Func <Item, List <Tuple <Item, Item> > > groupArguments = l =>
                                                                          (l as ListItem).Expression
                                                                          .GroupingSelect(2, xs => new Tuple <Item, Item>(xs[0], xs[1]));

                Func <List <Item>, ListItem> getParams = args => (args[paramsIndex] as ListItem);

                // now to the meat of things

                var invo = new InvokeableItem();

                var fn = new Invokeable
                {
                    ReturnType = ItemType.Invokeable,

                    Demands = InvokeableUtils.MakeDemands(
                        InvokeableUtils.DemandTypes(ItemType.Type, ItemType.List, ItemType.List),
                        args => args.Count == 3,
                        args => getParams(args).Expression.HasEvenLength(),
                        args => groupArguments(getParams(args)).All(pair =>
                                                                    pair.Item1.ItemType == ItemType.Symbol &&
                                                                    pair.Item2.ItemType == ItemType.Type)
                        ),

                    Function = (space, args) =>
                    {
                        var returnType   = args[typeIndex] as TypeItem;
                        var argumentList = groupArguments(args[paramsIndex]);
                        var body         = args[bodyIndex] as ListItem;

                        var argumentTypes =
                            argumentList
                            .Select(argument => (argument.Item2 as TypeItem).Type)
                            .ToArray();

                        var resultingInvokeable = new InvokeableItem();

                        resultingInvokeable.AddInvokeable(new Invokeable()
                        {
                            ReturnType = returnType.Type,

                            Demands = InvokeableUtils.MakeDemands(InvokeableUtils.DemandTypes(argumentTypes)),

                            // create symbol space,
                            // bind fnargs,
                            // evaluate body with new symbol space
                            Function = (fnspace, fnargs) => {
                                var newSpace = new SymbolSpace(space);

                                for (var index = 0; index < fnargs.Count; index++)
                                {
                                    newSpace.Bind(
                                        (argumentList[index].Item1 as SymbolItem).Name,
                                        fnargs[index]);
                                }

                                body = body.Unquote() as ListItem;
                                return(body.Evaluate(newSpace));
                            }
                        });

                        return(resultingInvokeable);
                    }
                };

                invo.AddInvokeable(fn);

                globalSpace.Bind("=>", invo);
            }