public static Assign ( |
||
left | An |
|
right | An |
|
return |
/// <summary> /// From control flow perspective it "calls" the proc. /// </summary> internal static void SetProcCallRule( MetaObjectBuilder /*!*/ metaBuilder, Expression /*!*/ procExpression, // proc object Expression /*!*/ selfExpression, // self passed to the proc Expression callingMethodExpression, // RubyLambdaMethodInfo passed to the proc via BlockParam CallArguments /*!*/ args // user arguments passed to the proc ) { var bfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc"); var resultVariable = metaBuilder.GetTemporary(typeof(object), "#result"); metaBuilder.Result = AstFactory.Block( Ast.Assign(bfcVariable, (callingMethodExpression != null) ? Methods.CreateBfcForMethodProcCall.OpCall( AstUtils.Convert(procExpression, typeof(Proc)), callingMethodExpression ) : Methods.CreateBfcForProcCall.OpCall( AstUtils.Convert(procExpression, typeof(Proc)) ) ), Ast.Assign(resultVariable, AstFactory.YieldExpression( args.GetSimpleArgumentExpressions(), args.GetSplattedArgumentExpression(), args.GetRhsArgumentExpression(), bfcVariable, selfExpression )), Methods.MethodProcCall.OpCall(bfcVariable, resultVariable), resultVariable ); }
public void Factorial() { var value = LinqExpression.Parameter(typeof(int), "value"); var result = LinqExpression.Parameter(typeof(int), "result"); var label = LinqExpression.Label(typeof(int), "label"); var one = LinqExpression.Constant(1); var expression = LinqExpression.Block( new[] { result }, LinqExpression.Assign( result, one), LinqExpression.Loop( LinqExpression.Condition( LinqExpression.GreaterThan( value, one), LinqExpression.MultiplyAssign( result, LinqExpression.PostDecrementAssign( value)), LinqExpression.Break( label, result), typeof(void)), label)); ShouldRoundrip(expression); }
public LambdaExpression CreateLambda(Type from, Type to) { var fromParameters = from.GetTypeInfo().GenericTypeArguments; var toParameters = to.GetTypeInfo().GenericTypeArguments; var converters = fromParameters .Zip(toParameters, (f, t) => Ref.GetLambda(f, t)) .ToArray(); var input = Ex.Parameter(from, "input"); var res = toParameters.Select(t => Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(t))).ToArray(); var conversion = res.Select((r, i) => Ex.Assign(res[i], converters[i].ApplyTo(Ex.PropertyOrField(input, $"Item{i + 1}")))).ToArray(); var conversionSuccesful = Enumerable.Aggregate(res, (Ex)Ex.Constant(true), (c, p) => Ex.MakeBinary(Et.AndAlso, c, Ex.Property(p, nameof(IConversionResult.IsSuccessful)))); var block = Ex.Block(res, Ex.Block(conversion), Ex.Condition(conversionSuccesful, Result(to, Ex.Call(Creator(to), Enumerable.Select(res, p => Ex.Property(p, nameof(IConversionResult.Result))))), NoResult(to))); var lambda = Ex.Lambda(block, input); return(lambda); }
Exp Assign(List <Token> expr, Exp value) { if (expr.Count == 1) { Token tok = expr[0]; if (tok.Type == TokenType.Identifier) { if (Local != null) { if (Local.TryGetValue(tok.Value, out Exp id)) { return(Exp.Assign(id, value)); } else { var var = Exp.Variable(typeof(Object), tok.Value); Local.Add(var); return(Exp.Assign(var, value)); } /* if 'name' is not present in the 'Local' dictionary defines * new local variable instead of accessing 'Global' (by default) */ } else { return(Exp.Assign(GlobalAccess(tok.Value), value)); } } } else { Token tok = expr[^ 1]; // last
private static Func <int[], int[]> GenerateCopyExpression() { var ctor = typeof(int[]).GetConstructor(new[] { typeof(int) }); var get = typeof(int[]).GetMethod("Get", new[] { typeof(int) }); var set = typeof(int[]).GetMethod("Set", new[] { typeof(int), typeof(int) }); var p1 = Exp.Parameter(typeof(int[])); var v1 = Exp.Variable(typeof(int[])); var v2 = Exp.Variable(typeof(int)); var @break = Exp.Label(); var block = Exp.Block( new[] { v1, v2 }, Exp.Assign(v1, Exp.New(ctor, Exp.Property(p1, "Length"))), Exp.Assign(v2, Exp.Constant(0)), Exp.Loop( Exp.IfThenElse( Exp.LessThan(v2, Exp.Property(p1, "Length")), Exp.Block( Exp.Call(v1, set, v2, Exp.Call(p1, get, v2)), Exp.AddAssign(v2, Exp.Constant(1)) ), Exp.Break(@break) ), @break), v1 ); return(Exp.Lambda <Func <int[], int[]> >(block, new ParameterExpression[] { p1 }).Compile()); }
internal bool AddSplattedArgumentTest(object value, Expression /*!*/ expression, out int listLength, out ParameterExpression /*!*/ listVariable) { if (value == null) { AddRestriction(Ast.Equal(expression, Ast.Constant(null))); } else { // test exact type: AddTypeRestriction(value.GetType(), expression); List <object> list = value as List <object>; if (list != null) { Type type = typeof(List <object>); listLength = list.Count; listVariable = GetTemporary(type, "#list"); AddCondition(Ast.Equal( Ast.Property(Ast.Assign(listVariable, Ast.Convert(expression, type)), type.GetProperty("Count")), Ast.Constant(list.Count)) ); return(true); } } listLength = -1; listVariable = null; return(false); }
public static Func <TExArgCtx, TEx <float> > PivotShift <S>(Func <EEx <float>, TEx <float>[], TEx <float> > shifter, Func <TExArgCtx, TEx <float> > sharpness, Func <TExArgCtx, TEx <float> > pivot, Func <TExArgCtx, TEx <float> > f1, Func <TExArgCtx, TEx <float> > f2, string pivotVar) where S : TEx, new() { if (pivotVar == "t" || pivotVar == "p" || pivotVar == "x") { return(t => { var pivotT = t.MakeCopyForType <S>(out var currEx, out var pivotEx); return Ex.Block(new ParameterExpression[] { pivotEx }, Ex.Assign(pivotEx, currEx), Ex.Assign(pivotVar.Into <Func <TExArgCtx, TEx <float> > >()(pivotT), pivot(t)), shifter(sharpness(t), new TEx <float>[] { f1(t), f1(pivotT).Add(f2(t).Sub(f2(pivotT))) }) ); }); } else if (pivotVar[0] == Parser.SM_REF_KEY_C) { var let = pivotVar.Substring(1); return(t => shifter(sharpness(t), new TEx <float>[] { f1(t), f2(t).Add( ReflectEx.Let <float, float>(let, pivot, () => f1(t).Sub(f2(t)), t) ) })); } else { throw new Exception($"{pivotVar} is not a valid pivoting target."); } }
private LambdaExpression toDictLambda(Type from, Type to) { var valueType = recordCreator.GetValueType(to); var recType = typeof(IRecord <>).MakeGenericType(valueType); var set = recType.GetTypeInfo().GetDeclaredMethod(nameof(IRecord <object> .SetValue)); var input = Ex.Parameter(from, "input"); var tmp = Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(valueType), "tmp"); var res = Ex.Parameter(typeof(IDictionary <,>).MakeGenericType(typeof(string), valueType), "res"); var rec = Ex.Parameter(recType, "rec"); var getters = GetReadablePropertiesForType(from); var converters = getters.Select(g => Ref.GetLambda(g.PropertyType, valueType)); var end = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to)); var block = Ex.Block(new[] { tmp, res, rec }, Ex.Assign(res, Ex.New(GetParameterlessConstructor(to))), Ex.Assign(rec, recordCreator.Creator(to).ApplyTo(res)), Ex.IfThen(Ex.MakeBinary(ExpressionType.Equal, rec, Ex.Default(rec.Type)), Ex.Goto(end, NoResult(to))), Ex.Block(getters.Zip(converters, (g, c) => new { g, c }) .Select(x => Ex.Block( Ex.Assign(tmp, x.c.ApplyTo(Ex.Property(input, x.g))), Ex.IfThenElse(Ex.Property(tmp, nameof(IConversionResult.IsSuccessful)), Ex.Call(rec, set, Ex.Constant(x.g.Name), Ex.Property(tmp, nameof(IConversionResult.Result))), Ex.Goto(end, NoResult(to)))))), Ex.Label(end, Result(to, Ex.Convert(res, to)))); return(Ex.Lambda(block, input)); }
/// <summary> /// Invariant: bex is linearized. /// </summary> private BlockExpression AssignBlockResultToTemp(BlockExpression bex, ParameterExpression pex) { var exprs = bex.Expressions.ToArray(); exprs[exprs.Length - 1] = Ex.Assign(pex, exprs[exprs.Length - 1]); return(Ex.Block(bex.Variables, exprs)); }
public LinqExpr ReDeclInit <T>(string Name, T Init) { LinqExpr p = ReDecl(typeof(T), Name); code.Add(LinqExpr.Assign(p, LinqExpr.Constant(Init))); return(p); }
// Pseudocode: //string input => //{ // R result = 0; // for (int i = input.Length - 1; i >= 0; i--) // { // result <<= 6; // var m = _invMap[input[i]]; // if (m == 0xff) // return default(ConversionResult<R>); // result += m; // } // return new ConversionResult<R>(result); //} private LambdaExpression fromLambda(Type to) { var stringthis = typeof(string).GetTypeInfo().DeclaredProperties.First(p => p.GetIndexParameters().Length == 1 && p.GetIndexParameters()[0].ParameterType == typeof(int)); var input = Ex.Parameter(typeof(string), "input"); var result = Ex.Parameter(to, "result"); var i = Ex.Parameter(typeof(int), "i"); var m = Ex.Parameter(typeof(byte), "m"); var loopstart = Ex.Label("loopstart"); var end = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end"); var loop = Ex.Block( Ex.Label(loopstart), Ex.IfThen(Ex.MakeBinary(ExpressionType.LessThan, i, Ex.Constant(0)), Ex.Goto(end, Result(to, result))), Ex.LeftShiftAssign(result, Ex.Constant(6)), Ex.Assign(m, Ex.ArrayIndex(Ex.Constant(_invMap), Ex.Convert(Ex.MakeIndex(input, stringthis, new[] { i }), typeof(int)))), Ex.IfThen(Ex.MakeBinary(ExpressionType.Equal, m, Ex.Constant((byte)0xff)), Ex.Goto(end, NoResult(to))), Ex.AddAssign(result, Ex.Convert(m, result.Type)), Ex.PostDecrementAssign(i), Ex.Goto(loopstart)); var block = Ex.Block(new[] { result, i, m }, Ex.Assign(result, Ex.Convert(Ex.Constant(0), to)), Ex.Assign(i, Ex.MakeBinary(ExpressionType.Subtract, Ex.Property(input, nameof(string.Length)), Ex.Constant(1))), loop, Ex.Label(end, NoResult(to))); return(Ex.Lambda(block, input)); }
public LambdaExpression CreateLambda(Type from, Type to) { var toParameters = to.GetTypeInfo().GenericTypeArguments; var tupa = toParameters.Length; var input = Ex.Parameter(from, "input"); var converters = toParameters.Select(p => Ref.GetLambda(typeof(string), p)).ToArray(); var res = toParameters.Select(p => Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(p))).ToArray(); var end = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end"); var indexer = typeof(string[]).GetTypeInfo().GetDeclaredProperty("Item"); var split = Ex.Parameter(typeof(string[]), "split"); var conversion = Ex.Block(converters.Select((c, i) => Ex.Block( Ex.Assign(res[i], c.ApplyTo(Ex.MakeIndex(split, indexer, new[] { Ex.MakeBinary(Et.Add, Ex.Constant(i), Ex.MakeBinary(Et.Subtract, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa))) }))), Ex.IfThen(Ex.Not(Ex.Property(res[i], nameof(IConversionResult.IsSuccessful))), Ex.Goto(end, NoResult(to)))))); var block = Ex.Block(new[] { split }, Ex.Assign(split, Ex.Call(input, nameof(string.Split), Type.EmptyTypes, _separator)), Ex.Condition(Ex.MakeBinary(Et.LessThan, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa)), NoResult(to), Ex.Block(res, Ex.IfThen(Ex.MakeBinary(Et.GreaterThan, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa)), Ex.Assign(Ex.ArrayAccess(split, Ex.MakeBinary(Et.Subtract, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa))), Ex.Call(typeof(string), nameof(string.Join), Type.EmptyTypes, _separatorString, Ex.Call(typeof(Enumerable), nameof(Enumerable.Take), new[] { typeof(string) }, split, Ex.MakeBinary(Et.Add, Ex.Constant(1), Ex.MakeBinary(Et.Subtract, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa))))))), conversion, Ex.Label(end, Result(to, Ex.Call(Creator(to), res.Select(r => Ex.Property(r, nameof(IConversionResult.Result))))))))); var lambda = Ex.Lambda(block, input); return(lambda); }
protected override object VisitAssignment(Assignment A) { LinqExpr value = target.Compile(A.Value); switch (A.Operator) { case Operator.Add: target.Add(LinqExpr.AddAssign(target.LookUp(A.Assign), value)); break; case Operator.Subtract: target.Add(LinqExpr.SubtractAssign(target.LookUp(A.Assign), value)); break; case Operator.Multiply: target.Add(LinqExpr.MultiplyAssign(target.LookUp(A.Assign), value)); break; case Operator.Divide: target.Add(LinqExpr.DivideAssign(target.LookUp(A.Assign), value)); break; case Operator.Power: target.Add(LinqExpr.PowerAssign(target.LookUp(A.Assign), value)); break; case Operator.And: target.Add(LinqExpr.AndAssign(target.LookUp(A.Assign), value)); break; case Operator.Or: target.Add(LinqExpr.OrAssign(target.LookUp(A.Assign), value)); break; case Operator.Equal: LinqExpr x = target.LookUp(A.Assign); if (x == null) { x = target.DeclInit(A.Assign, A.Value); } target.Add(LinqExpr.Assign(x, value)); break; default: throw new NotImplementedException("Operator not implemented for assignment."); } return(null); }
public ParamExpr DeclInit <T>(Scope Scope, string Name, T Init) { ParamExpr p = Decl(Scope.Local, typeof(T), Name); code.Add(LinqExpr.Assign(p, LinqExpr.Constant(Init))); return(p); }
// Generate expression to swap a and b, using t as a temporary. private static LinqExpr Swap(LinqExpr a, LinqExpr b, LinqExpr t) { return(LinqExpr.Block( LinqExpr.Assign(t, a), LinqExpr.Assign(a, b), LinqExpr.Assign(b, t))); }
/// <summary> /// Takes current result and wraps it into try-filter(MethodUnwinder)-finally block that ensures correct "break" behavior for /// Ruby method calls with a block given in arguments. /// /// Sets up a RFC frame similarly to MethodDeclaration. /// </summary> internal static void ApplyBlockFlowHandlingInternal(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args) { // TODO (improvement): // We don't special case null block here, although we could (we would need a test for that then). // We could also statically know (via call-site flag) that the current method is not a proc-converter (passed by ref), // which would make such calls faster. if (metaBuilder.Error || !args.Signature.HasBlock) { return; } Expression rfcVariable = metaBuilder.GetTemporary(typeof(RuntimeFlowControl), "#rfc"); ParameterExpression methodUnwinder = metaBuilder.GetTemporary(typeof(MethodUnwinder), "#unwinder"); Expression resultVariable = metaBuilder.GetTemporary(typeof(object), "#result"); metaBuilder.Result = Ast.Block( // initialize frame (RFC): Ast.Assign(rfcVariable, Methods.CreateRfcForMethod.OpCall(AstUtils.Convert(args.GetBlockExpression(), typeof(Proc)))), AstUtils.Try( Ast.Assign(resultVariable, metaBuilder.Result) ).Filter(methodUnwinder, Ast.Equal(Ast.Field(methodUnwinder, MethodUnwinder.TargetFrameField), rfcVariable), // return unwinder.ReturnValue; Ast.Assign(resultVariable, Ast.Field(methodUnwinder, MethodUnwinder.ReturnValueField)) ).Finally( // we need to mark the RFC dead snce the block might escape and break later: Ast.Assign(Ast.Field(rfcVariable, RuntimeFlowControl.IsActiveMethodField), Ast.Constant(false)) ), resultVariable ); }
private LambdaExpression fromEnumerableLambda(Type from) { var input = Ex.Parameter(from, "input"); var eType = from.GetTypeInfo().ImplementedInterfaces .Where(i => i.GenericTypeArguments.Length == 1 && i.GetGenericTypeDefinition() == typeof(IEnumerable <>)) .Select(i => i.GenericTypeArguments[0]).SingleOrDefault() ?? from.GetTypeInfo().GenericTypeArguments[0]; var res = Ex.Parameter(typeof(string), "res"); var result = Ex.Block(new[] { res }, Ex.Assign(res, Ex.Call((from mi in typeof(string).GetTypeInfo().GetDeclaredMethods(nameof(string.Join)) where mi.GetGenericArguments().Length == 1 let par = mi.GetParameters() where par.Length == 2 && par[0].ParameterType == typeof(string) && par[1].ParameterType == typeof(IEnumerable <>).MakeGenericType(mi.GetGenericArguments()[0]) select mi).Single().MakeGenericMethod(eType), Ex.Constant(Separators[0].ToString()), input)), Ex.Condition(Ex.MakeBinary(Et.Equal, Ex.Property(res, nameof(string.Length)), Ex.Constant(0)), NoResult(typeof(string)), Result(typeof(string), res))); var block = Ex.Condition(Ex.MakeBinary(Et.Equal, input, Ex.Default(from)), NoResult(typeof(string)), result); var lambda = Ex.Lambda(block, input); return(lambda); }
/// <summary> /// Declare and initialize a new variable. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="Name"></param> /// <param name="Init"></param> /// <returns></returns> public ParamExpr DeclInit <T>(Scope Scope, string Name, LinqExpr Init) { ParamExpr p = Decl(Scope, typeof(T), Name); code.Add(LinqExpr.Assign(p, Init)); return(p); }
public ParamExpr DeclInit(Scope Scope, Expression Expr, Expression Init) { ParamExpr d = Decl(Scope, Expr); Add(LinqExpr.Assign(d, Compile(Init))); return(d); }
// Define a function for running the simulation of a population system S with timestep // dt. The number of timesteps and the data buffer are parameters of the defined function. static Func <int, double[, ], int> DefineSimulate(double dt, PopulationSystem S) { CodeGen code = new CodeGen(); // Define a parameter for the current population x, and define mappings to the // expressions defined above. LinqExpr N = code.Decl <int>(Scope.Parameter, "N"); LinqExpr Data = code.Decl <double[, ]>(Scope.Parameter, "Data"); // Loop over the sample range requested. Note that this loop is a 'runtime' loop, // while the rest of the loops nested in the body of this loop are 'compile time' loops. LinqExpr n = code.DeclInit <int>("n", 1); code.For( () => { }, LinqExpr.LessThan(n, N), () => code.Add(LinqExpr.PostIncrementAssign(n)), () => { // Define expressions representing the population of each species. List <Expression> x = new List <Expression>(); for (int i = 0; i < S.N; ++i) { // Define a variable xi. Expression xi = "x" + i.ToString(); x.Add(xi); // xi = Data[n, i]. code.DeclInit(xi, LinqExpr.ArrayAccess(Data, LinqExpr.Subtract(n, LinqExpr.Constant(1)), LinqExpr.Constant(i))); } for (int i = 0; i < S.N; ++i) { // This list is the elements of the sum representing the i'th // row of f, i.e. r_i + (A*x)_i. Expression dx_dt = 1; for (int j = 0; j < S.N; ++j) { dx_dt -= S.A[i, j] * x[j]; } // Define dx_i/dt = x_i * f_i(x), as per the Lotka-Volterra equations. dx_dt *= x[i] * S.r[i]; // Euler's method for x(t) is: x(t) = x(t - h) + h * x'(t - h). Expression integral = x[i] + dt * dx_dt; // Data[n, i] = Data[n - 1, i] + dt * dx_dt; code.Add(LinqExpr.Assign( LinqExpr.ArrayAccess(Data, n, LinqExpr.Constant(i)), code.Compile(integral))); } }); code.Return(N); // Compile the generated code. LinqExprs.Expression <Func <int, double[, ], int> > expr = code.Build <Func <int, double[, ], int> >(); return(expr.Compile()); }
public void MiscellaneousExpression_Block() { var variable = Expr.Variable(typeof(bool)); var block = Expr.Block(Expr.Assign(variable, Expr.Constant(true)), variable); UnsupportedExpr(Property.Active, active => Expr.Equal(active, block), ExpressionType.Block); }
public static ExCoordF CartesianRot(ExTP erv) => (c, s, bpi, nrv, fxy) => { var v2 = new TExV2(); return(Ex.Block(new ParameterExpression[] { v2 }, Ex.Assign(v2, erv(bpi)), fxy(Ex.Subtract(Ex.Multiply(c, v2.x), Ex.Multiply(s, v2.y)), Ex.Add(Ex.Multiply(s, v2.x), Ex.Multiply(c, v2.y))), Expression.Empty() )); };
/// <summary> /// Home towards a target location at a fixed speed. /// </summary> /// <remarks> /// Use with StopSampling to home for only a few seconds. /// <para>This is primarily for use with non-rotational velocity. /// Rotational use creates: contracting spirals (0,90), circle around player [90], expanding spiral (90,180).</para> /// </remarks> /// <param name="speed">Speed</param> /// <param name="location">Target location</param> /// <returns></returns> public static ExTP VHome(ExBPY speed, ExTP location) { TExV2 l = new TExV2(); return(bpi => Ex.Block(new ParameterExpression[] { l }, Ex.Assign(l, location(bpi).Sub(bpi.loc)), l.Mul(Ex.Divide(speed(bpi), Sqrt(Ex.Add(SqrMag(l), EPS)))) )); }
/// <summary> /// Derive a Vector2 from a Vector3 by dropping the Z-component. /// </summary> public static ExTP TP(ExTP3 xyz) { var v3 = TExV3.Variable(); return(bpi => Ex.Block(new ParameterExpression[] { v3 }, Ex.Assign(v3, xyz(bpi)), ExUtils.V2(v3.x, v3.y) )); }
private static Func <PluginMetadata, object> MakeCreateFunc(Type type, string name) { // TODO: what do i want the visibiliy of Init methods to be? var ctors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance) .Select(c => (c, attr: c.GetCustomAttribute <InitAttribute>())) .NonNull(t => t.attr) .OrderByDescending(t => t.c.GetParameters().Length) .Select(t => t.c).ToArray(); if (ctors.Length > 1) { Logger.loader.Warn($"Plugin {name} has multiple [Init] constructors. Picking the one with the most parameters."); } bool usingDefaultCtor = false; var ctor = ctors.FirstOrDefault(); if (ctor == null) { // this is a normal case usingDefaultCtor = true; ctor = type.GetConstructor(Type.EmptyTypes); if (ctor == null) { throw new InvalidOperationException($"{type.FullName} does not expose a public default constructor and has no constructors marked [Init]"); } } var initMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance) .Select(m => (m, attr: m.GetCustomAttribute <InitAttribute>())) .NonNull(t => t.attr).Select(t => t.m).ToArray(); // verify that they don't have lifecycle attributes on them foreach (var method in initMethods) { var attrs = method.GetCustomAttributes(typeof(IEdgeLifecycleAttribute), false); if (attrs.Length != 0) { throw new InvalidOperationException($"Method {method} on {type.FullName} has both an [Init] attribute and a lifecycle attribute."); } } var metaParam = Expression.Parameter(typeof(PluginMetadata), "meta"); var objVar = ExpressionEx.Variable(type, "objVar"); var persistVar = ExpressionEx.Variable(typeof(object), "persistVar"); var createExpr = Expression.Lambda <Func <PluginMetadata, object> >( ExpressionEx.Block(new[] { objVar, persistVar }, initMethods .Select(m => PluginInitInjector.InjectedCallExpr(m.GetParameters(), metaParam, persistVar, es => Expression.Call(objVar, m, es))) .Prepend(ExpressionEx.Assign(objVar, usingDefaultCtor ? Expression.New(ctor) : PluginInitInjector.InjectedCallExpr(ctor.GetParameters(), metaParam, persistVar, es => Expression.New(ctor, es)))) .Append(Expression.Convert(objVar, typeof(object)))), metaParam); // TODO: since this new system will be doing a f**k load of compilation, maybe add FastExpressionCompiler return(createExpr.Compile()); }
Exp Call(Exp obj, string name, Exp arg0) { return(Exp.Call(obj, Callvirt, Exp.Constant(name), Exp.Block ( Exp.Assign(Exp.Field(arg1, "self"), obj), Exp.Assign(Exp.ArrayAccess(Exp.Field(arg1, "Input"), Exp.Constant(0)), arg0), arg1 ))); }
public static TEx <T> Let <T, L>(string alias, Func <TExArgCtx, TEx <L> > content, Func <TEx <T> > inner, TExArgCtx applier) { var variabl = V <L>(); using var let = applier.Let(alias, variabl); return(Ex.Block(new[] { variabl }, Ex.Assign(variabl, content(applier)), inner() )); }
internal static Expression InjectedCallExpr(ParameterInfo[] initParams, Expression meta, Expression persistVar, Func <IEnumerable <Expression>, Expression> exprGen) { var arr = ExpressionEx.Variable(typeof(object[]), "initArr"); return(ExpressionEx.Block(new[] { arr }, ExpressionEx.Assign(arr, Expression.Call(InjectMethod, Expression.Constant(initParams), meta, persistVar)), exprGen(initParams .Select(p => p.ParameterType) .Select((t, i) => (Expression)Expression.Convert( Expression.ArrayIndex(arr, Expression.Constant(i)), t))))); }
/// <summary> /// Multiply the x-component of a parametric equation by a function of input. /// </summary> /// <param name="f">Function of input</param> /// <param name="tp">Parametric equation</param> /// <returns></returns> public static ExTP MultiplyX(ExBPY f, ExTP tp) { var v = TExV2.Variable(); var by = ExUtils.VFloat(); return(bpi => Ex.Block( new[] { v, by }, Ex.Assign(v, tp(bpi)), MulAssign(v.x, f(bpi)), v )); }
/// <summary> /// Add a function of input to the y-component of a parametric equation. /// </summary> /// <param name="f">Function of input</param> /// <param name="tp">Parametric equation</param> /// <returns></returns> public static ExTP AddY(ExBPY f, ExTP tp) { var v = TExV2.Variable(); var by = ExUtils.VFloat(); return(bpi => Ex.Block( new[] { v, by }, Ex.Assign(v, tp(bpi)), ExUtils.AddAssign(v.y, f(bpi)), v )); }