예제 #1
0
        protected virtual Expression CompileDereference(Compiler compiler, Frame frame, Expression left, Parse.BinaryExpression expression, System.Type typeHint)
        {
            left = compiler.MaterializeReference(left);

            var local = compiler.AddFrame(frame, expression);
            var memberType = left.Type.GenericTypeArguments[0];
            var parameters = new List<ParameterExpression>();

            var valueParam = compiler.CreateValueParam(expression, local, left, memberType);
            parameters.Add(valueParam);

            var indexParam = compiler.CreateIndexParam(expression, local);
            parameters.Add(indexParam);

            var right =
                compiler.MaterializeReference
                (
                    compiler.CompileExpression(local, expression.Right, typeHint)
                );

            var selection = Expression.Lambda(right, parameters);
            var select =
                typeof(Enumerable).GetMethodExt
                (
                    "Select",
                    new System.Type[] { typeof(IEnumerable<ReflectionUtility.T>), typeof(Func<ReflectionUtility.T, int, ReflectionUtility.T>) }
                );
            select = select.MakeGenericMethod(memberType, selection.ReturnType);
            return Expression.Call(select, left, selection);
        }
예제 #2
0
        public override Expression CompileBinaryExpression(Compiler compiler, Frame frame, Expression left, Parse.BinaryExpression expression, System.Type typeHint)
        {
            switch (expression.Operator)
            {
                case Parse.Operator.Equal:
                case Parse.Operator.NotEqual:
                    left = compiler.MaterializeReference(left);
                    var right = compiler.MaterializeReference(compiler.CompileExpression(frame, expression.Right));

                    switch (expression.Operator)
                    {
                        case Parse.Operator.Equal: return Expression.Equal(left, right);
                        case Parse.Operator.NotEqual: return Expression.NotEqual(left, right);
                        default: throw new NotSupportedException();
                    }

                case Parse.Operator.Dereference: return CompileDereference(compiler, frame, left, expression, typeHint);

                default: throw new NotSupportedException(String.Format("Operator {0} is not supported.", expression.Operator));
            }
        }
예제 #3
0
        public override Expression CompileBinaryExpression(Compiler compiler, Frame frame, Expression left, Parse.BinaryExpression expression, System.Type typeHint)
        {
            left = compiler.MaterializeReference(left);

            switch (expression.Operator)
            {
                case Parse.Operator.Addition:
                case Parse.Operator.Subtract:
                case Parse.Operator.Multiply:
                case Parse.Operator.Modulo:
                case Parse.Operator.Divide:
                case Parse.Operator.Power:

                case Parse.Operator.BitwiseAnd:
                case Parse.Operator.And:
                case Parse.Operator.BitwiseOr:
                case Parse.Operator.Or:
                case Parse.Operator.BitwiseXor:
                case Parse.Operator.Xor:
                case Parse.Operator.ShiftLeft:
                case Parse.Operator.ShiftRight:
                    {
                        var right = compiler.MaterializeReference(compiler.CompileExpression(frame, expression.Right, typeHint));
                        return CompileOperator(left, right, expression.Operator);
                    }

                case Parse.Operator.Equal:
                case Parse.Operator.NotEqual:
                case Parse.Operator.InclusiveGreater:
                case Parse.Operator.InclusiveLess:
                case Parse.Operator.Greater:
                case Parse.Operator.Less:
                    {
                        var right = compiler.MaterializeReference(compiler.CompileExpression(frame, expression.Right));	// (no type hint)
                        return CompileOperator(left, right, expression.Operator);
                    }

                default: throw new NotSupportedException(String.Format("Operator {0} is not supported.", expression.Operator));
            }
        }
예제 #4
0
        private Expression CompileDereference(Compiler compiler, Frame frame, Expression left, Parse.BinaryExpression expression, System.Type typeHint)
        {
            left = compiler.MaterializeReference(left);

            var local = compiler.AddFrame(frame, expression);
            foreach (var field in left.Type.GetFields(BindingFlags.Public | BindingFlags.Instance))
            {
                local.Add(expression, Name.FromNative(field.Name), field);
                var fieldExpression = Expression.Field(left, field);
                compiler.ExpressionsBySymbol.Add(field, fieldExpression);
            }
            return compiler.CompileExpression(local, expression.Right, typeHint);
        }
예제 #5
0
        public override Expression CompileUnaryExpression(Compiler compiler, Frame frame, Expression inner, Parse.UnaryExpression expression, System.Type typeHint)
        {
            inner = compiler.MaterializeReference(inner);

            switch (expression.Operator)
            {
                case Parse.Operator.Exists:
                    return Expression.GreaterThan
                    (
                        Expression.Property(inner, typeof(ICollection<>).MakeGenericType(inner.Type).GetProperty("Count")),
                        Expression.Constant(0)
                    );
                case Parse.Operator.IsNull: return Expression.Constant(false);

                default: throw new NotSupportedException(String.Format("Operator {0} is not supported.", expression.Operator));
            }
        }
예제 #6
0
        public override Expression CompileUnaryExpression(Compiler compiler, Frame frame, Expression inner, Parse.UnaryExpression expression, System.Type typeHint)
        {
            inner = compiler.MaterializeReference(inner);

            switch (expression.Operator)
            {
                case Parse.Operator.Exists: return Expression.Constant(true);
                case Parse.Operator.IsNull: return Expression.Constant(false);
                case Parse.Operator.Negate: return Expression.Negate(inner);
                case Parse.Operator.Not: return Expression.Not(inner);
                //case Parse.Operator.Successor:
                //case Parse.Operator.Predicessor:

                default: throw new NotSupportedException(String.Format("Operator {0} is not supported.", expression.Operator));
            }
        }