예제 #1
0
        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);
        }
예제 #2
0
        public static BlockExpression RotateLerp(Ex target, Ex source, TExArgCtx bpi, bool isRate, bool isTrue, Ex rate)
        {
            if (isRate)
            {
                rate = rate.Mul(M.degRad);
            }
            if (isTrue)
            {
                rate = rate.Mul(ETime.FRAME_TIME);
            }
            TExV2       v   = TExV2.Variable();
            TEx <float> ang = ExUtils.VFloat();

            Expression[] exprs = new Expression[3];
            exprs[1] = ang.Is(RadDiff(target, v));
            if (isTrue)
            {
                var key = bpi.Ctx.NameWithSuffix("_RotateLerpKey");
                exprs[0] = v.Is(
                    Ex.Condition(FiringCtx.Contains <Vector2>(bpi, key),
                                 FiringCtx.GetValue <Vector2>(bpi, key),
                                 FiringCtx.SetValue <Vector2>(bpi, key, source)
                                 ));
                exprs[2] =
                    FiringCtx.SetValue <Vector2>(bpi, key, RotateRad(isRate ? (Ex)Limit(rate, ang) : ang.Mul(rate), v));
            }
            else
            {
                exprs[0] = v.Is(source);
                exprs[2] = RotateRad(isRate ?
                                     (Ex)Limit(bpi.t.Mul(rate), ang) :
                                     ang.Mul(Min(bpi.t.Mul(rate), E1)), v);
            }
            return(Ex.Block(new ParameterExpression[] { v, ang }, exprs));
        }
예제 #3
0
        public void TestAssign()
        {
            var x  = VF("x");
            var yi = VF("y");
            var zi = VF("z");

            var ex = x.Is(Ex.Block(new[] { yi },
                                   yi.Is(ExC(5f)),
                                   yi.Add(x)
                                   ));

            DebugsTo(ex, "(x=((y=5);\n(y+x);))");
            LinDebugsTo(ex, "((y=5);\n(x=(y+x));)");

            AreEqual(11f, Compile1(ex.Linearize(), x)(6));

            var ex2 = Ex.Block(
                x.Is(Ex.Block(new[] { yi },
                              yi.Is(ExC(5f)),
                              yi.Add(x)
                              ).Add(Ex.Block(new[] { zi },
                                             zi.Is(x),
                                             zi.Mul(2f)
                                             ))),
                x.Add(2f)
                );

            DebugsTo(ex2, "((x=(((y=5);\n(y+x);)+((z=x);\n(z*2);)));\n(x+2);)");
            LinDebugsTo(ex2, @"((y=5);
(z=x);
(x=((y+x)+(z*2)));
(x+2);)");
        }
예제 #4
0
        internal MetaObject /*!*/ CreateMetaObject(MetaObjectBinder /*!*/ action, MetaObject /*!*/[] /*!*/ siteArgs)
        {
            var expr = _error ? Ast.Throw(_result) : _result;

            Restrictions restrictions;

            if (_condition != null)
            {
                var deferral = action.Defer(siteArgs);
                expr         = Ast.Condition(_condition, AstUtils.Convert(expr, typeof(object)), deferral.Expression);
                restrictions = deferral.Restrictions;
            }
            else
            {
                restrictions = Restrictions.Empty;
            }

            if (_temps != null)
            {
                expr = Ast.Block(_temps, expr);
            }

            if (_restriction != null)
            {
                restrictions = restrictions.Merge(Restrictions.GetExpressionRestriction(_restriction));
            }

            return(new MetaObject(expr, restrictions));
        }
예제 #5
0
 // 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)));
 }
        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);
        }
        /// <summary>
        /// Generates the method's body
        /// </summary>
        /// <returns></returns>
        protected Expr GenerateDeserializationMethodBody()
        {
            // Generate a tree of BodyExpression.
            // We just populate the type token, the member info, and the access expressions
            var bodyParts = MakeRootNode();

            foreach (var member in Root.Members)
            {
                if (member.MemberType != MemberType || member.IsReadOnly)
                    continue;

                var node = new TreeNode() {
                    AccessExpression = MakeRootMemberAccess(member),
                    TypeToken = member.TypeToken,
                    MemberToken = member,
                };

                GenerateTreeNode(node);
                bodyParts.Children.Add(node);
            }

            // Emit candidate read calls.
            bodyParts.GenerateReadCalls(this);

            var expr = bodyParts.TryUnroll().ToExpression();
            var returnType = MakeReturnExpression();
            if (returnType != null)
                expr = Expr.Block(expr, returnType);

            // TODO: See if trying to optimize iterator usages in the generated code outweighs the cost of optimizing
            // (It probably doesn't) (except for large files question mark?)
            return expr;
        }
예제 #8
0
 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.");
     }
 }
        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);
        }
예제 #10
0
        /// <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
                );
        }
예제 #11
0
        private Exp CheckIfZero(CompilerState state, Exp expression)
        {
            if (state == null)
            {
                throw new Exception();
            }
            if (expression == null)
            {
                throw new Exception();
            }

            if (expression.Type == typeof(int))
            {
                var constructor = typeof(Exception).GetConstructor(new Type[] { typeof(string) });
                return(Exp.Block(
                           Exp.IfThen(Exp.Equal(expression, Exp.Constant(0)),
                                      Exp.Throw(Exp.New(constructor, Exp.Constant("Division by zero")))),
                           expression));
            }

            if (expression.Type == typeof(float))
            {
                var constructor = typeof(Exception).GetConstructor(new Type[] { typeof(string) });
                return(Exp.Block(
                           Exp.IfThen(Exp.Equal(expression, Exp.Constant(0.0f)),
                                      Exp.Throw(Exp.New(constructor, Exp.Constant("Division by zero")))),
                           expression));
            }
            return(expression);
        }
예제 #12
0
        /// <summary>
        /// For each expression provided, linearize it if necessary, and then linearize the process of combining
        /// the expressions by assigning all block results to temporary variables and then using those temporary
        /// variables instead of the blocks.
        /// </summary>
        private Expression Linearize(Func <Expression[], Expression> combiner, params Expression[] pieces)
        {
            var linearized = pieces.Select(Visit).ToArray();

            //Best case!
            if (!linearized.Any(ex => ex is BlockExpression))
            {
                return(combiner(linearized));
            }
            var prms         = new List <ParameterExpression>();
            var stmts        = new List <Expression>();
            var reduced_args = new Expression[linearized.Length];

            linearized.ForEachI((i, ex) => {
                if (ex is BlockExpression bex)
                {
                    prms.AddRange(bex.Variables);
                    stmts.AddRange(bex.Expressions.Take(bex.Expressions.Count - 1));
                    reduced_args[i] = bex.Expressions[bex.Expressions.Count - 1];
                }
                else
                {
                    reduced_args[i] = ex;
                }
            });
            stmts.Add(combiner(reduced_args));
            return(Ex.Block(prms, stmts));
        }
예제 #13
0
        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));
        }
예제 #14
0
        /// <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));
        }
예제 #15
0
        protected override Expression VisitBlock(BlockExpression node)
        {
            if (node.Expressions.Count == 1 && node.Variables.Count == 0)
            {
                return(Visit(node.Expressions[0]));
            }
            var prms  = new List <ParameterExpression>();
            var stmts = new List <Expression>();

            prms.AddRange(node.Variables);
            foreach (var ex in node.Expressions)
            {
                var linearized = Visit(ex);
                if (linearized is BlockExpression bex)
                {
                    prms.AddRange(bex.Variables);
                    stmts.AddRange(bex.Expressions);
                }
                else
                {
                    stmts.Add(linearized);
                }
            }
            return(Ex.Block(prms, stmts));
        }
예제 #16
0
            public Expr ToExpression()
            {
                var exitLabel = Expr.Label();
                var loopBody  = Expr.Block(Body.ToExpression(), Expr.PreIncrementAssign(Iterator.ToExpression()));

                return(Expr.Loop(Expr.IfThenElse(Expr.LessThan(Iterator.ToExpression(), UpperBound.ToExpression()), loopBody, Expr.Break(exitLabel)), exitLabel));
            }
예제 #17
0
파일: ExMV3.cs 프로젝트: Bagoum/danmokou
 /// <summary>
 /// Wrap a position equation around a cylinder.
 /// </summary>
 /// <param name="radius">Radius of the cylinder</param>
 /// <param name="ang0">Starting angle offset (radians) on the cylinder. 0 = z-axis</param>
 /// <param name="maxWrap">Maximum angle value (radians) of the wrap. After this, the function will continue along the tangent. Starting offset not included. Absolute value tested.</param>
 /// <param name="axisOff">Offset angle (radians) of the axis of the cylinder from the y-axis</param>
 /// <param name="position">Position equation</param>
 /// <returns></returns>
 public static tv3 CylinderWrap(efloat radius, efloat ang0, efloat maxWrap, efloat axisOff, ev2 position) =>
 EEx.Resolve(radius, ang0, axisOff, position, (r, a0, axis, _v2) => {
     var cs    = new TExV2();
     var xyd   = new TExV2();
     var v2    = new TExV2(_v2);
     var v3    = new TExV3();
     var a     = ExUtils.VFloat();
     var aRem  = ExUtils.VFloat();
     var aMax  = ExUtils.VFloat();
     var a_cs  = new TExV2();
     var a0_cs = new TExV2();
     return(Ex.Block(new[] { v3, cs, xyd, a, aRem, aMax, a_cs, a0_cs },
                     aMax.Is(maxWrap),
                     cs.Is(CosSin(axis)),
                     xyd.Is(ConvertBasis(v2, cs)),
                     a.Is(xyd.x.Div(r)),
                     aRem.Is(E0),
                     Ex.IfThen(Abs(a).GT(aMax), Ex.Block(
                                   Ex.IfThen(a.LT0(), MulAssign(aMax, EN1)),
                                   aRem.Is(a.Sub(aMax)),
                                   a.Is(aMax)
                                   )),
                     a0_cs.Is(CosSin(a0)),
                     a_cs.Is(CosSin(a.Add(a0))),
                     xyd.x.Is(r.Mul(a_cs.y.Sub(a0_cs.y).Add(aRem.Mul(a_cs.x)))),
                     v3.Is(TP3(DeconvertBasis(xyd, cs))),
                     v3.z.Is(r.Mul(a_cs.x.Sub(a0_cs.x).Sub(aRem.Mul(a_cs.y)))),
                     v3
                     ));
 });
예제 #18
0
        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());
        }
        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);
        }
예제 #20
0
        public void TestAssign()
        {
            var x = VF("x");
            var y = VF("y");

            AreEqual("((y=((2*x)+2));\n(y+(x*2));)", DerivDebug(x, Ex.Block(new[] { y }, Ex.Assign(y, E2.Mul(x).Add(E2)), x.Mul(y))));
        }
예제 #21
0
        // 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));
        }
예제 #22
0
        public EvaluationCallback Create(Node node)
        {
            var compilerstate = new CompilerState
            {
                FunctionState = Exp.Parameter(typeof(Character), "state"),
                ErrorVariable = Exp.Parameter(typeof(bool), "error")
            };
            var result = Make(compilerstate, node);

            if (result.Type == typeof(bool))
            {
                result = ToInteger(result);
            }
            if (result.Type == typeof(int) || result.Type == typeof(float))
            {
                // int or float convert to number
                var constructor = typeof(Number).GetConstructor(new[] { result.Type });
                result = Exp.New(constructor, new[] { result });

                // wrap the evaluation in a try..catch
                var exceptionParameter = Exp.Parameter(typeof(Exception), "e");
                var writeLineMethod    = typeof(Console).GetMethod(nameof(Console.WriteLine), new Type[] { typeof(string) });
                var toStringMethod     = typeof(Exception).GetMethod(nameof(Exception.ToString));
                var catchBody          = Exp.Block(
                    Exp.Call(null, writeLineMethod, Exp.Call(exceptionParameter, toStringMethod)),
                    Exp.Constant(new Number(0)));
                result = Exp.TryCatch(result, Exp.Catch(exceptionParameter, catchBody));
                // create lambda
                var func = Exp.Lambda <Func <Character, bool, Number> >(result, compilerstate.FunctionState, compilerstate.ErrorVariable).Compile();
                return(new EvaluationCallback(o => func(o, false)));
            }
            throw new Exception();
        }
예제 #23
0
        public static BlockExpression LaserRotateLerp(Ex target, Ex source, TExArgCtx bpi, Ex rate)
        {
            var         r1        = rate.Mul(ExC(ETime.FRAME_TIME));
            TExV2       v         = TExV2.Variable();
            TEx <float> ang       = ExUtils.VFloat();
            var         dirKey    = bpi.Ctx.NameWithSuffix("_LaserRotateLerpDirKey");
            var         sideKey   = bpi.Ctx.NameWithSuffix("_LaserRotateLerpSideKey");
            var         inter_ang = HighPass(ExC(0.01f), RadDiff(target, v));

            return(Ex.Block(new ParameterExpression[] { v, ang },
                            Ex.Condition(
                                bpi.FCtxHas <Vector2>(dirKey).And(bpi.t.GT0()),
                                Ex.Block(
                                    v.Is(bpi.FCtxGet <Vector2>(dirKey)),
                                    ang.Is(Ex.Condition(bpi.FCtxGet <float>(sideKey).LT0(),
                                                        RadToNeg(inter_ang),
                                                        RadToPos(inter_ang)
                                                        )),
                                    bpi.FCtxSet <Vector2>(dirKey, RotateRad(Limit(r1, ang), v))
                                    ),
                                Ex.Block(
                                    v.Is(source),
                                    ang.Is(RadDiff(target, v)),
                                    bpi.FCtxSet <float>(sideKey, Sign(ang)),
                                    bpi.FCtxSet <Vector2>(dirKey, RotateRad(Limit(r1, ang), v))
                                    )
                                )
                            ));
        }
예제 #24
0
 /// <summary>
 /// Lerp between two functions. The controller is not clamped.
 /// </summary>
 /// <param name="zeroBound">Lower bound for lerp controller</param>
 /// <param name="oneBound">Upper bound for lerp controller</param>
 /// <param name="controller">Lerp controller</param>
 /// <param name="f1">First function</param>
 /// <param name="f2">Second function</param>
 /// <returns></returns>
 public static TEx <T> LerpU <T>(efloat zeroBound, efloat oneBound, efloat controller, TEx <T> f1, TEx <T> f2) =>
 EEx.Resolve(zeroBound, oneBound, controller, (z, o, c) => {
     var rc = VFloat();
     return(Ex.Block(new[] { rc },
                     rc.Is(c.Sub(z).Div(o.Sub(z))),
                     rc.Mul(f2).Add(rc.Complement().Mul(f1))
                     ));
 });
예제 #25
0
        public void ZeroOneRemoval()
        {
            var x  = VF("x");
            var ex = Ex.Block(Ex.Add(x, E1), Ex.Add(x, E0), E1.Mul(x), x.Mul(E0), x.Sub(E0), E0.Sub(x));

            AreEqual("((x+1);\n(x+0);\n(1*x);\n(x*0);\n(x-0);\n(0-x);)", ex.Debug());
            AreEqual("((x+1);\nx;\nx;\n0;\nx;\n(0-x);)", ex.FlatDebug());
        }
        public void Block_Expressions()
        {
            var expression =
                LinqExpression.Block(
                    LinqExpression.Default(typeof(string)));

            ShouldRoundrip(expression);
        }
        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);
        }
예제 #28
0
        /// <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))))
                                   ));
        }
예제 #29
0
 /// <summary>
 /// Lerp between two functions with smoothing applied to the controller.
 /// </summary>
 public static TEx <T> LerpSmooth <T>([LookupMethod] Func <tfloat, tfloat> smoother,
                                      efloat zeroBound, efloat oneBound, efloat controller, TEx <T> f1, TEx <T> f2)
 => EEx.Resolve(zeroBound, oneBound, controller, (z, o, c) => {
     var rc = VFloat();
     return(Ex.Block(new[] { rc },
                     rc.Is(smoother(Clamp(z, o, c).Sub(z).Div(o.Sub(z)))),
                     rc.Mul(f2).Add(rc.Complement().Mul(f1))
                     ));
 });
예제 #30
0
        /// <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)
                                   ));
        }