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)); }
private ExprParamPair GenReturn(Return stmt, ParamList overlapCandidate) { Contract.Requires <ArgumentNullException>(stmt != null); Contract.Ensures(Contract.Result <ExprParamPair>() != null); var target = GetTarget(); var expr = Expression.Return(target, ElemGen.GenElem(stmt.Value), typeof(object)); return(new ExprParamPair(expr, null)); }
private Expression GenAssign(Assign ph, Expression prev) { Contract.Requires <ArgumentNullException>(ph != null); if (ph.Value == null && prev == null) { throw Error("値が指定されていません。", ph.Range.Start); } if (ph.Value != null && prev != null) { throw Error("値が二重に指定されています。", ph.Range.Start); } var value = prev ?? ElemGen.GenElem(ph.Value); return(AssignGlobal(ph.Name, value)); }
private Expression GenPropSet(PropertySet ph, Expression prev) { Contract.Requires <ArgumentNullException>(ph != null); if (ph.Value == null && prev == null) { throw Error("値が指定されていません。", ph.Range.Start); } if (ph.Value != null && prev != null) { throw Error("値が二重に指定されています。", ph.Range.Start); } var target = ElemGen.GenElem(ph.Property.Value); var value = prev ?? ElemGen.GenElem(ph.Value); return(Expression.Dynamic(Factory.SetMemberBinder(ph.Property.Name), typeof(object), target, value)); }
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)); }
private ExprParamPair GenDefValue(DefineValue ph, Expression prev, ParamList defined, ParamList overlapCandidate) { Contract.Requires <ArgumentNullException>(ph != null); if (ph.Value == null && prev == null) { throw Error("値が指定されていません。", ph.Range.Start); } if (ph.Value != null && prev != null) { throw Error("値が二重に指定されています。", ph.Range.Start); } ParameterExpression variable = ParamList.Search(overlapCandidate, p => p.Name == ph.Name) ?? Expression.Parameter(typeof(object), ph.Name); var value = prev ?? ElemGen.GenElem(ph.Value); var assign = Expression.Assign(variable, value); defined = new ParamList(variable, defined); return(new ExprParamPair(assign, defined)); }