Constant() public static method

Creates a ConstantExpression that has the ConstantExpression.Value property set to the specified value. .
public static Constant ( object value ) : ConstantExpression
value object An to set the property equal to.
return ConstantExpression
Esempio n. 1
0
 static Expression GetArgument(Expression Expression, int n)
 {
     if (Expression.Type == typeof(LuaArguments))
         return Expression.Property(Expression, "Item", Expression.Constant(n));
     else
         return Expression.ArrayAccess(Expression, Expression.Constant(n));
 }
Esempio n. 2
0
        static GlyphRunFormatter()
        {
            var refType = typeof(CharacterBufferReference);

            _textFormattingMode = typeof(GlyphRun).GetField("_textFormattingMode", BindingFlags.NonPublic | BindingFlags.Instance);

            {
                var property = refType.GetProperty("CharacterBuffer", BindingFlags.NonPublic | BindingFlags.Instance);
                var param0   = Expr.Parameter(refType);
                var expr     = Expr.Convert(Expr.Property(param0, property), typeof(IList <char>));
                var lambda   = Expr.Lambda <Func <CharacterBufferReference, IList <char> > >(expr, param0);
                getCharBuf = lambda.Compile();
            }

            {
                var property = refType.GetProperty("OffsetToFirstChar", BindingFlags.NonPublic | BindingFlags.Instance);
                var param0   = Expr.Parameter(refType);
                var expr     = Expr.Property(param0, property);
                var lambda   = Expr.Lambda <Func <CharacterBufferReference, int> >(expr, param0);
                getCharOffset = lambda.Compile();
            }

            {
                var ctor   = typeof(TextBounds).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0];
                var param0 = Expr.Parameter(typeof(Rect));
                var expr   = Expr.New(ctor, param0, Expr.Constant(FlowDirection.LeftToRight), Expr.Constant(null, typeof(IList <TextRunBounds>)));
                var lambda = Expr.Lambda <Func <Rect, TextBounds> >(expr, param0);
                makeBounds = lambda.Compile();
            }
        }
Esempio n. 3
0
 public void BinaryExpression_OrAssign() => UnsupportedBinaryExpr(Property.Id, id => Expr.OrAssign(id, Expr.Constant(3)), ExpressionType.OrAssign);
Esempio n. 4
0
        private static LinqExpression Compile(ElementExpression value, CompilationData data)
        {
            data.Cache ??= new Dictionary <CachedExpression, ParameterExpression>();
            data.GroupCache ??= new Dictionary <ExpressionGroup, LinqExpression[]>();
            switch (value)
            {
            case ICLRExpression s:
                return(s.Compile(e => Compile(e, data)));

            case Constant c:
                return(LinqExpression.Constant(c.Value));

            case Binary b:
                var ea = Compile(b.OpA, data);
                var eb = Compile(b.OpB, data);
                if (b.Operation == Binary.Op.Pow)
                {
                    var o = LinqExpression.Call(typeof(Math).GetMethod(nameof(Math.Pow)),
                                                LinqExpression.Convert(ea, typeof(double)), LinqExpression.Convert(eb, typeof(double)));
                    return(LinqExpression.Convert(o, typeof(float)));
                }

                if (b.Operation == Binary.Op.Atan2)
                {
                    var o = LinqExpression.Call(typeof(Math).GetMethod(nameof(Math.Atan2)),
                                                LinqExpression.Convert(ea, typeof(double)), LinqExpression.Convert(eb, typeof(double)));
                    return(LinqExpression.Convert(o, typeof(float)));
                }

                return(BinaryOps[b.Operation](ea, eb));

            case Unary u:
                var input  = Compile(u.Operand, data);
                var output = LinqExpression.Call(MethodOps[u.Operation], LinqExpression.Convert(input, typeof(double)));
                return(LinqExpression.Convert(output, typeof(float)));

            case CachedExpression v:
                if (!data.Cache.TryGetValue(v, out var varExpr))
                {
                    var result = Compile(v.Value, data);
                    data.Cache.Add(v, varExpr = LinqExpression.Parameter(result.Type));
                    data.Statements.Add(LinqExpression.Assign(varExpr, result));
                    data.Variables.Add(varExpr);
                }

                return(varExpr);

            case Mux m:
                if (m.Operands.Count == 2)
                {
                    return(LinqExpression.Condition(
                               LinqExpression.LessThan(Compile(m.Selector, data), LinqExpression.Constant(1f)),
                               Compile(m.Operands[0], data), Compile(m.Operands[1], data)));
                }

                var sel        = LinqExpression.Convert(Compile(m.Selector, data), typeof(int));
                var clampedSel =
                    LinqExpression.Condition(
                        LinqExpression.GreaterThanOrEqual(sel, LinqExpression.Constant(m.Operands.Count)),
                        LinqExpression.Constant(m.Operands.Count - 1), sel);
                var cases = m.Operands.Select(
                    (c, i) => LinqExpression.SwitchCase(Compile(c, data), LinqExpression.Constant(i)))
                            .ToArray();
                return(LinqExpression.Switch(clampedSel, cases[0].Body, cases));

            case State s:
                if (data.ResolveState == null)
                {
                    throw new Exception("Tried to compile a State expression outside of an ExpressionGroup");
                }

                return(data.ResolveState(s));

            case ExpressionGroupElement groupElement:
                if (!data.GroupCache.TryGetValue(groupElement.Group, out var groupList))
                {
                    data.GroupCache.Add(groupElement.Group, groupList = CompileGroup(groupElement.Group, data));
                }

                return(groupList[groupElement.Index]);
            }

            throw new Exception("Unknown expression " + value);
        }
Esempio n. 5
0
        private static LinqExpression[] CompileGroup(ExpressionGroup group, CompilationData data)
        {
            switch (group)
            {
            case Persist p:
                foreach (var s in p.State)
                {
                    if (!(s.InitialValue is Constant))
                    {
                        throw new Exception("Persist initial value is not constant");
                    }

                    data.StateValues.Add(((Constant)s.InitialValue).Value);
                }

                var assigns = new List <LinqExpression>();
                // TODO: Resolve parent scopes
                data.ResolveState = s => LinqExpression.ArrayAccess(data.StateArray, LinqExpression.Constant(s.Id));
                for (var i = 0; i < p.NewValue.Count; i++)
                {
                    var newValueExpr = Compile(p.NewValue[i], data);
                    assigns.Add(LinqExpression.Assign(
                                    LinqExpression.ArrayAccess(data.StateArray, LinqExpression.Constant(i)), newValueExpr));
                }

                data.Statements.AddRange(assigns);
                return(Enumerable.Range(0, p.Size)
                       .Select(i => LinqExpression.ArrayAccess(data.StateArray, LinqExpression.Constant(i)))
                       .ToArray());

            case Loop l:
                var stateList = new List <ParameterExpression>();
                foreach (var s in l.State)
                {
                    var initial  = Compile(s.InitialValue, data);
                    var variable = LinqExpression.Variable(initial.Type);
                    data.Statements.Add(LinqExpression.Assign(variable, initial));
                    data.Variables.Add(variable);
                    stateList.Add(variable);
                }

                // TODO: Resolve parent scopes
                data.ResolveState = s => stateList[s.Id];
                var parentStatements = data.Statements;
                // Make a new cache that copies in the old one, but won't leak State expressions
                data.Cache = new Dictionary <CachedExpression, ParameterExpression>(data.Cache);

                // Create a new statements list to put in the loop body
                var s1        = data.Statements = new List <LinqExpression>();
                var condition = Compile(l.Condition, data);
                var s2        = data.Statements = new List <LinqExpression>();
                var newState  = l.Body.Select(e => Compile(e, data)).ToArray();

                // Ensure that the entire state is only set at the end of the loop
                for (var i = 0; i < newState.Length; i++)
                {
                    var s = newState[i];
                    if (!(s is ParameterExpression))
                    {
                        var tmpVar = LinqExpression.Variable(s.Type);
                        data.Variables.Add(tmpVar);
                        s2.Add(LinqExpression.Assign(tmpVar, s));
                        newState[i] = tmpVar;
                    }
                }

                var breakLabel = LinqExpression.Label();
                var body       = LinqExpression.Block(s1
                                                      .Concat(new[]
                {
                    LinqExpression.IfThen(
                        LinqExpression.LessThan(condition, LinqExpression.Constant(1f)),
                        LinqExpression.Break(breakLabel))
                })
                                                      .Concat(s2)
                                                      .Concat(newState.Select((e, i) =>
                                                                              LinqExpression.Assign(stateList[i], e))));
                parentStatements.Add(LinqExpression.Loop(body, breakLabel));
                return(stateList.ToArray());

            default:
                throw new NotSupportedException();
            }
        }
        public LambdaExpression CreateLambda(Type from, Type to)
        {
            var input          = Ex.Parameter(from, "input");
            var eType          = to.GetElementType();
            var res            = Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(eType).MakeArrayType(), "res");
            var end            = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end");
            var fromParameters = from.GetTypeInfo().GenericTypeArguments;
            var converters     = fromParameters.Select(t => new { Lambda = Ref.GetLambda(t, eType), Input = t }).ToArray();

            var block = Ex.Block(new[] { res },
                                 Ex.Assign(res, Ex.NewArrayBounds(typeof(ConversionResult <>).MakeGenericType(eType), Ex.Constant(fromParameters.Length))),
                                 Ex.Block(converters.Select((con, i) =>
                                                            Ex.Block(
                                                                Ex.Assign(Ex.ArrayAccess(res, Ex.Constant(i)), con.Lambda.ApplyTo(Ex.PropertyOrField(input, $"Item{i + 1}"))),
                                                                Ex.IfThen(Ex.Not(Ex.Property(Ex.ArrayIndex(res, Ex.Constant(i)), nameof(IConversionResult.IsSuccessful))),
                                                                          Ex.Goto(end, NoResult(to)))))),
                                 Ex.Label(end, Result(to,
                                                      Ex.NewArrayInit(eType,
                                                                      Enumerable.Range(0, fromParameters.Length)
                                                                      .Select(idx => Ex.Property(Ex.ArrayIndex(res, Ex.Constant(idx)), nameof(IConversionResult.Result)))))));
            var lambda = Ex.Lambda(block, input);

            return(lambda);
        }
Esempio n. 7
0
        public virtual Expr ToExpression()
        {
            var blockBody = new List <Expr>();

#if EXPERIMENTAL_GENERATOR
            var variables = new HashSet <ParameterExpression>();
#endif
            // AccessExpression is null on the root node (It's a dummy node)
            // ReadExpression.Count > 1 can only happen if we decided to roll a loop, in which case all elements are identical.
            // ReadExpression.Count = 0 can happen if the type is a value type. Otherwise this is new T[...] or new T().
            if (AccessExpression != null)
            {
                if (ReadExpression.Count > 0)
                {
                    blockBody.Add(Expr.Assign(AccessExpression, ReadExpression[0]));
                }
                else if (TypeToken.IsArray)
                {
                    blockBody.Add(Expr.Assign(AccessExpression,
                                              TypeToken.GetElementTypeToken().NewArrayBounds(Expr.Constant(MemberToken.Cardinality))));
                }
                else if (TypeToken.IsClass)
                {
                    if (!TypeToken.HasDefaultConstructor)
                    {
                        throw new InvalidOperationException("Missing default constructor for " + TypeToken.Name);
                    }

                    blockBody.Add(Expr.Assign(AccessExpression, TypeToken.NewExpression()));
                }
            }

            if (Children.Count > 0)
            {
                // Produce children if there are any
                foreach (var child in Children)
                {
                    var subExpression = child.ToExpression();
#if EXPERIMENTAL_GENERATOR
                    if (subExpression is BlockExpression subBlockExpression)
                    {
                        blockBody.AddRange(subBlockExpression.Expressions);
                        foreach (var subBlockVariable in subBlockExpression.Variables)
                        {
                            variables.Add(subBlockVariable);
                        }
                    }
                    else
                    {
                        blockBody.Add(subExpression);
                    }
#else
                    blockBody.Add(subExpression);
#endif
                }

                // Assert that there is at least one node in the block emitted.
                if (blockBody.Count == 0)
                {
                    throw new InvalidOperationException("Empty block");
                }
            }

            // We allow empty blocks if there are no children for primitive types
            if (blockBody.Count == 0)
            {
                return(Expr.Empty());
            }

            // If there's only one expression, just return it.
#if EXPERIMENTAL_GENERATOR
            if (blockBody.Count == 1 && variables.Count == 0)
            {
                return(blockBody[0]);
            }

            return(Expression.Block(variables, blockBody));
#else
            if (blockBody.Count == 1)
            {
                return(blockBody[0]);
            }

            return(Expr.Block(blockBody));
#endif
        }
Esempio n. 8
0
        public override TreeNode TryUnroll()
        {
            if (!MustUnroll)
            {
                return(this);
            }

            // Reduce begins now
            var bodyExpression = new TreeNode()
            {
                TypeToken        = Array.TypeToken.GetElementTypeToken(),
                MemberToken      = Array.MemberToken,
                AccessExpression = Array.AccessExpression
            };

            // Array initializer added now and only now
            bodyExpression.ReadExpression.Add(bodyExpression.TypeToken.NewArrayBounds(Expr.Constant(IterationCount - InitialValue)));

            // Create N blocks of body
            for (var i = 0; i < IterationCount - InitialValue; ++i)
            {
                var invocationNode = new TreeNode()
                {
                    // Can't reuse this.AccessExpression because it's bound on the iterator.
                    AccessExpression = Expr.ArrayAccess(Array.AccessExpression, Expr.Constant(i)),
                    MemberToken      = Array.MemberToken,
                    TypeToken        = Array.TypeToken.GetElementTypeToken()
                };

                // Insert ctor if class
                if (invocationNode.TypeToken.IsClass)
                {
                    invocationNode.ReadExpression.Add(invocationNode.TypeToken.NewExpression());
                }

                // Insert all children
                foreach (var childNode in Children)
                {
                    var newChildNode = new TreeNode()
                    {
                        AccessExpression = Expr.MakeMemberAccess(invocationNode.AccessExpression, childNode.MemberToken.MemberInfo),
                        MemberToken      = childNode.MemberToken,
                        TypeToken        = childNode.TypeToken
                    };

                    // Now that we created a new block we must try to unroll it if it needs to
                    foreach (var subChildNode in childNode.Children)
                    {
                        newChildNode.AddChild(subChildNode.TryUnroll());
                    }

                    // If deserialization calls were found select the one corresponding to the currently unrolling iteration.
                    if (childNode.ReadExpression.Count > 0)
                    {
                        newChildNode.ReadExpression.Add(childNode.ReadExpression[i]);
                    }

                    invocationNode.AddChild(newChildNode);
                }

                bodyExpression.AddChild(invocationNode);
            }

            return(bodyExpression);
        }