protected override LExpression GetExpressionTreeIfPossible(LExpression contextExpression, LExpression evalContext)
        {
            AST node = getFirstChild();
            var conditionExpression = GetExpressionTreeIfPossible((BaseNode)node, contextExpression, evalContext);

            if (conditionExpression == null)
            {
                return(null);
            }

            node = node.getNextSibling();
            var trueExpression = GetExpressionTreeIfPossible((BaseNode)node, contextExpression, evalContext);

            if (trueExpression == null)
            {
                return(null);
            }

            node = node.getNextSibling();
            var falseExpression = GetExpressionTreeIfPossible((BaseNode)node, contextExpression, evalContext);

            if (falseExpression == null)
            {
                return(null);
            }

            return(LExpression.Condition(conditionExpression, trueExpression, falseExpression));
        }
示例#2
0
        /// <summary>Helper to produce the rule for converting T to Nullable of T</summary>
        private static MSAst MakeConvertingToTToNullableOfTTarget(Type toType, ConversionResultKind kind, MSAst arg)
        {
            var valueType = toType.GetGenericArguments()[0];

            // ConvertSelfToT -> Nullable<T>
            if (kind == ConversionResultKind.ExplicitCast)
            {
                // if the conversion to T fails we just throw
                var conversion = ConvertExpression(arg, valueType);

                return(MSAst.New(
                           toType.GetConstructor(new[] { valueType }),
                           conversion));
            }
            else
            {
                var conversion = ConvertExpression(arg, valueType);

                // if the conversion to T succeeds then produce the nullable<T>, otherwise return default(retType)

                return(MSAst.Condition(
                           MSAst.NotEqual(
                               conversion,
                               AstUtils.Constant(null)),
                           MSAst.New(
                               toType.GetConstructor(new[] { valueType }),
                               MSAst.Convert(
                                   conversion,
                                   valueType)),
                           GetTryConvertReturnValue(toType)));
            }
        }
示例#3
0
文件: ExMMod.cs 项目: Bagoum/danmokou
 /// <summary>
 /// Periodize a value,
 /// "bouncing off" the endpoint instead of wrapping around.
 /// </summary>
 /// <example>
 /// <c>
 /// FSoftMod(X(), 4)(3.95) = 3.95
 /// FSoftMod(X(), 4)(4.05) = 3.95
 /// FSoftMod(X(), 4)(4.15) = 3.85
 /// </c>
 /// </example>
 /// <param name="by">Period</param>
 /// <param name="x">Value</param>
 /// <returns></returns>
 public static tfloat SoftMod(efloat by, efloat x) => EEx.Resolve(by, _by => {
     var vd = VFloat();
     return(Ex.Block(new[] { vd },
                     vd.Is(Mod(E2.Mul(_by), x)),
                     Ex.Condition(vd.LT(_by), vd, E2.Mul(_by).Sub(vd))
                     ));
 });
示例#4
0
文件: ExMMod.cs 项目: Bagoum/danmokou
 /// <summary>
 /// Use this to draw "wings" where both go in opposite directions.
 /// <br/>Odd by: 0 is the center, [1,by/2-0.5] are one wing, and [by/2+0.5,by) are the other.
 /// <br/>Even by: [0, by/2) are one wing, [by/2, by) are the other.
 /// </summary>
 /// <example>
 /// <c>
 /// HNMod(X(), 9)(0) = HNMod(X(), 9)(9) = 0
 /// HNMod(X(), 9)(1) = 1
 /// HNMod(X(), 9)(5) = -1
 /// HNMod(X(), 9)(8) = -4
 /// HNMod(X(), 8)(0) = HNMod(X(), 8)(8) = 0.5
 /// HNMod(X(), 8)(3) = 3.5
 /// HNMod(X(), 8)(4) = -0.5
 /// </c>
 /// </example>
 /// <param name="by">Period</param>
 /// <param name="x">Target function</param>
 /// <returns></returns>
 public static tfloat HNMod(tfloat by, tfloat x) => EEx.Resolve <float>(by.Div(E2), h => {
     var y = VFloat();
     return(Ex.Block(new[] { y },
                     y.Is(Mod(h.Mul(E2), x)),
                     Ex.Condition(y.LT(h), y.Add(Floor(h)).Add(E05).Sub(h), h.Sub(E05).Sub(y))
                     ));
 });
示例#5
0
 public override MSAst TransformCore(ScriptGenerator generator)
 {
     return(MSAst.Condition(
                Test.Transform(generator),
                IfTrue.Transform(generator),
                IfFalse.Transform(generator)));
 }
示例#6
0
 /// <summary>
 /// Samples an invokee exactly once.
 /// </summary>
 /// <param name="p">Target function</param>
 /// <returns></returns>
 public static Func <TExArgCtx, TEx <T> > SS0 <T>(Func <TExArgCtx, TEx <T> > p) =>
 bpi => {
     var key = bpi.Ctx.NameWithSuffix("_SampleIfKey");
     return(Ex.Condition(Ex.Not(bpi.FCtxHas <T>(key)),
                         bpi.FCtxSet <T>(key, p(bpi)),
                         bpi.FCtxGet <T>(key)
                         ));
 };
示例#7
0
 /// <summary>
 /// Normalize a vector.
 /// </summary>
 public static tv3 Norm3(ev3 v3) => EEx.ResolveV3(v3, xyz => {
     var mag = VFloat();
     return(Ex.Block(new[] { mag },
                     mag.Is(v3Mag(xyz)),
                     Ex.Condition(mag.GT(ExC(M.MAG_ERR)),
                                  xyz.Mul(E1.Div(mag)),
                                  xyz
                                  )
                     ));
 });
示例#8
0
 /// <summary>
 /// Normalize a vector.
 /// </summary>
 public static tv2 Norm(ev2 v2) => EEx.ResolveV2(v2, xy => {
     var mag = VFloat();
     return(Ex.Block(new[] { mag },
                     mag.Is(Mag(xy)),
                     Ex.Condition(mag.GT(ExC(M.MAG_ERR)),
                                  xy.Mul(E1.Div(mag)),
                                  xy
                                  )
                     ));
 });
示例#9
0
文件: ExMMod.cs 项目: Bagoum/danmokou
        private static tfloat _ModWithPause(tfloat by, tfloat pauseAt, tfloat pauseLen, tfloat x)
        {
            var val = VFloat();

            return(Ex.Block(new[] { val },
                            val.Is(Mod(pauseLen.Add(by), x)),
                            Ex.Condition(val.LT(pauseAt), val,
                                         Ex.Condition(ExUtils.SubAssign(val, pauseLen).LT(pauseAt), pauseAt, val))
                            ));
        }
示例#10
0
 /// <summary>
 /// Nest a predicate such that it only returns True once for a single bullet.
 /// </summary>
 /// <param name="pred"></param>
 /// <returns></returns>
 public static ExPred OnlyOnce(ExPred pred) =>
 bpi => {
     var b   = V <bool>();
     var key = bpi.Ctx.NameWithSuffix("_OnlyOnce_Set");
     return(Ex.Condition(FiringCtx.Contains <int>(bpi, key),
                         ExC(false),
                         Ex.Block(new[] { b },
                                  Ex.IfThen(b.Is(pred(bpi)), FiringCtx.SetValue <int>(bpi, key, ExC(1))),
                                  b
                                  )
                         ));
 };
示例#11
0
        /// <summary>Generates a method similar to this:
        /// <code>
        /// void Write(IO.BitStream s, TEnum v, int bitCount)
        /// {
        ///     s.Write((TStreamType)v, bitCount);
        /// }
        /// </code>
        /// </summary>
        /// <returns>The generated method.</returns>
        /// <param name="args"></param>
        /// <param name="writeMethodInfo"></param>
        /// <param name="bitSwapMethod"></param>
        /// <remarks>
        /// If <see cref="args.UnderlyingType"/> is the same as <typeparamref name="TStreamType"/>, no conversion code is generated
        /// </remarks>
        static Action <IO.BitStream, TEnum, int> GenerateWriteMethod(MethodGenerationArgs args, MethodInfo writeMethodInfo, MethodInfo bitSwapMethod)
        {
            //////////////////////////////////////////////////////////////////////////
            // Define the generated method's parameters
            var param_s  = Expr.Parameter(kBitStreamType, "s");                                                         // BitStream s
            var param_v  = Expr.Parameter(args.EnumType, "v");                                                          // TEnum v
            var param_bc = Expr.Parameter(typeof(int), "bitCount");                                                     // int bitCount

            //////////////////////////////////////////////////////////////////////////
            // Define the member access
            var param_v_member = Expr.PropertyOrField(param_v, EnumUtils.kMemberName);                  // i.e., 'v.value__'
            var write_param    = args.UnderlyingTypeNeedsConversion ?                                   // If the underlying type is different from the type we're writing,
                                 Expr.Convert(param_v_member, args.StreamType) :                        // we need to cast the Write param from UnderlyingType to TStreamType
                                 (Expr)param_v_member;

            if (args.Options.UseNoneSentinelEncoding)
            {
                write_param = Expr.Increment(write_param);
            }

            #region options.BitSwap
            if (args.Options.BitSwap)
            {
                // i.e., Bits.BitSwap( value, bitCount-1 );
                var  start_bit_index = Expr.Decrement(param_bc);
                Expr swap_call       = Expr.Call(null, bitSwapMethod, write_param, start_bit_index);

                // i.e., bitCount-1 ? Bits.BitSwap( value, bitCount-1 ) : value ;
                if (args.Options.BitSwapGuardAgainstOneBit)
                {
                    var start_bit_index_is_not_zero = Expr.NotEqual(start_bit_index, Expr.Constant(0, typeof(int)));
                    swap_call = Expr.Condition(start_bit_index_is_not_zero,
                                               swap_call, write_param);
                }

                write_param = swap_call;
            }
            #endregion

            //////////////////////////////////////////////////////////////////////////
            // Define the Write call
            // i.e., 's.Write(v.value__, bitCount)' or 's.Write((TStreamType)v.value__, bitCount)'
            var call_write = Expr.Call(param_s, writeMethodInfo, write_param, param_bc);

            //////////////////////////////////////////////////////////////////////////
            // Generate a method based on the expression tree we've built
            var lambda = Expr.Lambda <Action <IO.BitStream, TEnum, int> >(call_write, param_s, param_v, param_bc);
            return(lambda.Compile());
        }
示例#12
0
        public static Expr ConvertToNumberAndCheck(Context context, Expr expression, string format, params object[] args)
        {
            var numberVar    = Expr.Variable(typeof(double));
            var assignNumber = Expr.Assign(numberVar, ConvertToNumber(context, expression));

            return(Expr.Block(
                       new[] { numberVar },
                       assignNumber,
                       Expr.Condition(
                           Expr.Invoke(
                               Expr.Constant((Func <double, bool>)Double.IsNaN), numberVar),
                           Expr.Block(
                               Expr.Throw(Expr.New(MemberInfos.NewRuntimeException, Expr.Constant(format), Expr.Constant(args))),
                               Expr.Constant(Double.NaN)),
                           numberVar)));
        }
示例#13
0
        public IFunction ToInput(LExpression parameter, ICLRBoundaryMap rootTypeMap, CompilationContext context)
        {
            var arg = parameter;

            if (arg.Type != typeof(float))
            {
                if (arg.Type == typeof(bool))
                {
                    arg = LExpression.Condition(arg, LExpression.Constant(1f), LExpression.Constant(0f));
                }
                else
                {
                    arg = LExpression.Convert(arg, typeof(float));
                }
            }

            return(new SingleInputExpr(arg));
        }
示例#14
0
            public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
            {
                var valueVar = Expr.Variable(typeof(object));

                var getValue = Expr.Call(
                    Expr.Convert(Expression, typeof(LuaTable)),
                    MemberInfos.LuaTableGetValue,
                    Expr.Convert(indexes[0].Expression, typeof(object)));
                var valueAssign = Expr.Assign(valueVar, getValue);

                var expression = Expr.Block(
                    valueVar,
                    Expr.Condition(
                        Expr.Equal(valueVar, Expr.Constant(null)),
                        MetamethodFallbacks.Index(null, this, indexes),
                        valueVar));

                return(new DynamicMetaObject(expression, RuntimeHelpers.MergeTypeRestrictions(this)));
            }
示例#15
0
            public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
            {
                var getValue = Expr.Call(
                    Expr.Convert(Expression, typeof(LuaTable)),
                    MemberInfos.LuaTableGetValue,
                    Expr.Convert(indexes[0].Expression, typeof(object)));

                var setValue = Expr.Call(
                    Expr.Convert(Expression, typeof(LuaTable)),
                    MemberInfos.LuaTableSetValue,
                    Expr.Convert(indexes[0].Expression, typeof(object)),
                    Expr.Convert(value.Expression, typeof(object)));

                var expression = Expr.Condition(
                    Expr.Equal(getValue, Expr.Constant(null)),
                    MetamethodFallbacks.NewIndex(null, this, indexes, value),
                    setValue);

                return(new DynamicMetaObject(expression, RuntimeHelpers.MergeTypeRestrictions(this)));
            }
        Expr FallbackIfNumberIsNan(Expr conversionResult, DynamicMetaObject left, DynamicMetaObject right)
        {
            // If we have performed a string to number conversion check that conversion went well by checking
            // number for NaN. If conversion failed do metatable fallback. Also assign to temp variable for single evaluation.

            var conversionVar = Expr.Variable(typeof(double));

            var expr = Expr.Condition(
                Expr.Invoke(Expr.Constant((Func <double, bool>)Double.IsNaN), conversionVar),
                Expr.Invoke(
                    Expr.Constant((Func <Context, ExprType, object, object, object>)LuaOps.NumericMetamethod),
                    Expr.Constant(context),
                    Expr.Constant(Operation),
                    Expr.Convert(left.Expression, typeof(object)),
                    Expr.Convert(right.Expression, typeof(object))),
                Expr.Convert(conversionVar, typeof(object)));

            return(Expr.Block(
                       new[] { conversionVar },
                       Expr.Assign(conversionVar, conversionResult),
                       expr));
        }
示例#17
0
 /// <summary>
 /// Of two numbers, return the one with the larger absolute value.
 /// Not well-defined when x1 = -x2.
 /// </summary>
 public static tfloat MaxA(efloat x1, efloat x2) =>
 EEx.Resolve(x1, x2, (a, b) => Ex.Condition(Abs(a).GT(Abs(b)), a, b));
示例#18
0
 /// <summary>
 /// If the switcher is 1, return the result, otherwise the default value.
 /// </summary>
 public static TEx <T> If1 <T>(tfloat switcher, TEx <T> result) =>
 Ex.Condition(Ex.Equal(switcher, E1), result, Ex.Default(typeof(T)));
示例#19
0
 /// <summary>
 /// If the predicate is true, return the true branch, otherwise the false branch.
 /// </summary>
 public static TEx <T> If <T>(tbool pred, TEx <T> iftrue, TEx <T> iffalse) => Ex.Condition(pred, iftrue, iffalse);
示例#20
0
 static Expr GenerateModifyFlagsGuts(ExprParam paramV, ExprParam paramF, ExprParam paramCond)
 {
     return(Expr.Condition(paramCond,
                           GenerateAddFlagsGuts(paramV, paramF),
                           GenerateRemoveFlagsGuts(paramV, paramF)));
 }
示例#21
0
 /// <summary>
 /// Return either -1 or 1 based on the parametric ID.
 /// </summary>
 /// <returns></returns>
 public static ExBPY BRandpm1() => bpi => Ex.Condition(bpi.id.GT(ExC(uint.MaxValue / (uint)2)), EN1, E1);
示例#22
0
 /// <summary>
 /// Returns -1 if x lt 0 and 1 otherwise. (Note: Sign(0) = 1)
 /// </summary>
 public static tfloat Sign(efloat x) => EEx.Resolve(x, y => Ex.Condition(y.LT0(), EN1, E1));
示例#23
0
        /// <summary>Generates a method similar to this:
        /// <code>
        /// void Read(IO.BitStream s, out TEnum v, int bitCount)
        /// {
        ///     v = (UnderlyingType)s.Read[TStreamType](bitCount);
        /// }
        /// </code>
        /// </summary>
        /// <param name="args"></param>
        /// <param name="readMethodInfo"></param>
        /// <param name="bitSwapMethod"></param>
        /// <returns>The generated method.</returns>
        /// <remarks>
        /// If <see cref="args.UnderlyingType"/> is the same as <typeparamref name="TStreamType"/>, no conversion code is generated
        /// </remarks>
        static ReadDelegate GenerateReadMethod(MethodGenerationArgs args, MethodInfo readMethodInfo, MethodInfo bitSwapMethod)
        {
            // Get a "ref type" of the enum we're dealing with so we can define the enum value as an 'out' parameter
            var enum_ref = args.EnumType.MakeByRefType();

            //////////////////////////////////////////////////////////////////////////
            // Define the generated method's parameters
            var param_s  = Expr.Parameter(kBitStreamType, "s");                                                         // BitStream s
            var param_v  = Expr.Parameter(enum_ref, "v");                                                               // ref TEnum v
            var param_bc = Expr.Parameter(typeof(int), "bitCount");                                                     // int bitCount

            //////////////////////////////////////////////////////////////////////////
            // Define the Read call
            Expr call_read;

            if (args.StreamTypeIsSigned)
            {
                call_read = Expr.Call(param_s, readMethodInfo, param_bc, Expr.Constant(args.Options.SignExtend));
            }
            else
            {
                call_read = Expr.Call(param_s, readMethodInfo, param_bc);                                               // i.e., 's.Read<Type>(bitCount)'
            }
            if (args.Options.UseNoneSentinelEncoding)
            {
                call_read = Expr.Decrement(call_read);
            }

            #region options.BitSwap
            if (args.Options.BitSwap)
            {
                // i.e., Bits.BitSwap( Read(), bitCount-1 );
                var  start_bit_index = Expr.Decrement(param_bc);
                Expr swap_call       = Expr.Call(null, bitSwapMethod, call_read, start_bit_index);

                // i.e., bitCount-1 ? Bits.BitSwap( Read(), bitCount-1 ) : Read() ;
                if (args.Options.BitSwapGuardAgainstOneBit)
                {
                    var start_bit_index_is_not_zero = Expr.NotEqual(start_bit_index, Expr.Constant(0, typeof(int)));
                    swap_call = Expr.Condition(start_bit_index_is_not_zero,
                                               swap_call, call_read);
                }

                call_read = swap_call;
            }
            #endregion

            var read_result = args.UnderlyingTypeNeedsConversion ?                                                      // If the underlying type is different from the type we're reading,
                              Expr.Convert(call_read, args.UnderlyingType) :                                            // we need to cast the Read result from TStreamType to UnderlyingType
                              (Expr)call_read;

            //////////////////////////////////////////////////////////////////////////
            // Define the member assignment
            var param_v_member = Expr.PropertyOrField(param_v, EnumUtils.kMemberName);                  // i.e., 'v.value__'
            // i.e., 'v.value__ = s.Read<Type>()' or 'v.value__ = (UnderlyingType)s.Read<Type>()'
            var assign = Expr.Assign(param_v_member, read_result);

            //////////////////////////////////////////////////////////////////////////
            // Generate a method based on the expression tree we've built
            var lambda = Expr.Lambda <ReadDelegate>(assign, param_s, param_v, param_bc);
            return(lambda.Compile());
        }
示例#24
0
 /// <summary>
 /// Move a value in the range [-540, 540] to the range [-180, 180] by adding or subtracting 360.
 /// </summary>
 /// <param name="ang_rad"></param>
 /// <returns></returns>
 public static tfloat DegIntoRange(efloat ang_rad) =>
 EEx.Resolve(ang_rad, a => Ex.Condition(a.GT(ExC(180f)),
                                        a.Sub(ExC(360f)),
                                        Ex.Condition(a.LT(ExC(-180f)),
                                                     a.Add(ExC(360f)),
                                                     a)));
示例#25
0
 public static tfloat NPow(efloat bas, efloat exp) => EEx.Resolve(bas, exp, (x, y) =>
                                                                  Ex.Condition(Ex.LessThan(x, E0),
                                                                               Ex.Negate(Pow(Ex.Negate(x), y)),
                                                                               Pow(x, y)));
示例#26
0
 /// <summary>
 /// Move a value in the range [-2pi, 2pi] to the range [0,2pi] by adding tau.
 /// </summary>
 /// <param name="ang_rad"></param>
 /// <returns></returns>
 public static tfloat RadToPos(efloat ang_rad) => EEx.Resolve(ang_rad, a =>
                                                              Ex.Condition(a.LT0(), a.Add(tau), a));
示例#27
0
 /// <summary>
 /// Move a value in the range [-2pi, 2pi] to the range [-2pi, 0] by subtracting tau.
 /// </summary>
 /// <param name="ang_rad"></param>
 /// <returns></returns>
 public static tfloat RadToNeg(efloat ang_rad) => EEx.Resolve(ang_rad, a =>
                                                              Ex.Condition(a.GT0(), a.Sub(tau), a));
示例#28
0
 /// <summary>
 /// Move a value in the range [-3pi, 3pi] to the range [-pi, pi] by adding or subtracting tau.
 /// </summary>
 /// <param name="ang_rad"></param>
 /// <returns></returns>
 public static tfloat RadIntoRange(efloat ang_rad) =>
 EEx.Resolve(ang_rad, a => Ex.Condition(a.GT(pi),
                                        a.Sub(tau),
                                        Ex.Condition(a.LT(npi),
                                                     a.Add(tau),
                                                     a)));
示例#29
0
 /// <summary>
 /// If x's absolute value is greater than by, then return 0 instead.
 /// </summary>
 public static tfloat HighCut(tfloat by, efloat x) =>
 EEx.Resolve(x, _x => Ex.Condition(Abs(_x).GT(by), E0, _x));
示例#30
0
 /// <summary>
 /// Limit a value x to have absolute value leq by.
 /// </summary>
 /// <param name="by">Positive number for absolute value comparison</param>
 /// <param name="x">Number to be limited</param>
 /// <returns></returns>
 public static tfloat Limit(efloat by, efloat x) => EEx.Resolve(by, x, (_by, _x) =>
                                                                Ex.Condition(_x.GT0(), Min(_x, _by), Max(_x, Ex.Negate(_by))));