예제 #1
0
            private Expression GenCall(Call ph, Expression prev)
            {
                Contract.Requires <ArgumentNullException>(ph != null);
                if (ph is MapCall)
                {
                    return(GenMapCall((MapCall)ph, prev));
                }
                // 関数あるいは,Globalを入れるために,0番目を開けた状態で,引数配列を作る。
                var sfxs = ph.Arguments.Select(a => a.Suffix).ToArray();
                var args = new List <Expression> {
                    null
                };                                                        // index : 0

                if (prev != null)
                {
                    args.Add(prev);
                }
                args.AddRange(ph.Arguments.Select(a => ElemGen.GenElem(a.Argument)));
                var callInfo = new CallInfo(sfxs.Length + (prev == null ? 0 : 1), sfxs);

                args[0] = ElemGen.GenElemCore(ph.Target);
                DynamicMetaObjectBinder binder;

                if (ph.Target.ElementType == ElementType.Symbol && !(args[0] is ParameterExpression))
                {
                    binder  = Factory.InvokeMemberBinder(((Symbol)ph.Target).Name, callInfo);
                    args[0] = Global;
                }
                else
                {
                    binder = Factory.InvokeBinder(callInfo);
                }
                return(Expression.Dynamic(binder, typeof(object), args));
            }
예제 #2
0
            private Expression GenMapCall(MapCall ph, Expression prev)
            {
                Contract.Requires <ArgumentNullException>(ph != null);
                if (ph.FirstArg == null && prev == null)
                {
                    throw Error("「それぞれ」の対象が指定されていません。", ph.Range.Start);
                }
                if (ph.FirstArg != null && prev != null)
                {
                    throw Error("「それぞれ」の対象が二重に指定されています。", ph.Range.Start);
                }
                var value = prev ?? ElemGen.GenElem(ph.FirstArg.Argument);

                Expression lambda;

                {
                    var param = Expression.Parameter(typeof(object), "要素");
                    var args  = new List <Expression> {
                        ElemGen.GenElemCore(ph.Target), param
                    };
                    var sfxs = new List <string>();
                    if (ph.FirstArg != null)
                    {
                        sfxs.Add(ph.FirstArg.Suffix);
                    }
                    foreach (var pair in ph.Arguments)
                    {
                        args.Add(ElemGen.GenElem(pair.Argument));
                        sfxs.Add(pair.Suffix);
                    }
                    var callInfo = new CallInfo(args.Count - 1, sfxs);
                    DynamicMetaObjectBinder binder;
                    if (ph.Target.ElementType == ElementType.Symbol && !(args[0] is ParameterExpression))
                    {
                        binder  = Factory.InvokeMemberBinder(((Symbol)ph.Target).Name, callInfo);
                        args[0] = Global;
                    }
                    else
                    {
                        binder = Factory.InvokeBinder(callInfo);
                    }
                    lambda = Expression.Lambda(Expression.Dynamic(binder, typeof(object), args), "それぞれ", new[] { param });
                }
                return(Expression.Dynamic(Factory.MapBinder, typeof(object), lambda, value));
            }