Example #1
0
 public override MSAst.Expression Reduce()
 {
     return(AstUtils.Try(
                Ast.Assign(
                    FunctionStackVariable,
                    Ast.Call(
                        AstMethods.PushFrame,
                        _localContext,
                        _codeObject
                        )
                    ),
                Body
                ).Finally(
                Ast.Call(
                    FunctionStackVariable,
                    typeof(List <FunctionStack>).GetMethod("RemoveAt"),
                    Ast.Add(
                        Ast.Property(
                            FunctionStackVariable,
                            "Count"
                            ),
                        Ast.Constant(-1)
                        )
                    )
                ));
 }
Example #2
0
 public static Expression FlAdd(params Expression[] args)
 {
     if (Expect <double>(args, 2))
     {
         return(Ast.Add(UnwrapAndCast <double>(args[0]), UnwrapAndCast <double>(args[1])));
     }
     return(null);
 }
Example #3
0
 public static Expression FxOdd(params Expression[] args)
 {
     if (Expect <int>(args, 1))
     {
         return(Ast.Equal(Ast.Add(UnwrapAndCast <int>(args[0]), Ast.Constant(1)), Ast.Constant(1)));
     }
     return(null);
 }
Example #4
0
        private static DynamicMetaObject TryPrimitiveOperator(OperatorInfo info, DynamicMetaObject[] args)
        {
            if (args.Length == 2 &&
                TypeUtils.GetNonNullableType(args[0].GetLimitType()) == TypeUtils.GetNonNullableType(args[1].GetLimitType()) &&
                TypeUtils.IsArithmetic(args[0].GetLimitType()))
            {
                // TODO: Nullable<PrimitveType> Support
                Expression        expr;
                DynamicMetaObject self = args[0].Restrict(args[0].GetLimitType());
                DynamicMetaObject arg0 = args[1].Restrict(args[0].GetLimitType());

                switch (info.Operator)
                {
                case ExpressionType.Add: expr = Ast.Add(self.Expression, arg0.Expression); break;

                case ExpressionType.Subtract: expr = Ast.Subtract(self.Expression, arg0.Expression); break;

                case ExpressionType.Divide: expr = Ast.Divide(self.Expression, arg0.Expression); break;

                case ExpressionType.Modulo: expr = Ast.Modulo(self.Expression, arg0.Expression); break;

                case ExpressionType.Multiply: expr = Ast.Multiply(self.Expression, arg0.Expression); break;

                case ExpressionType.LeftShift: expr = Ast.LeftShift(self.Expression, arg0.Expression); break;

                case ExpressionType.RightShift: expr = Ast.RightShift(self.Expression, arg0.Expression); break;

                case ExpressionType.And: expr = Ast.And(self.Expression, arg0.Expression); break;

                case ExpressionType.Or: expr = Ast.Or(self.Expression, arg0.Expression); break;

                case ExpressionType.ExclusiveOr: expr = Ast.ExclusiveOr(self.Expression, arg0.Expression); break;

                default: throw new InvalidOperationException();
                }

                return(new DynamicMetaObject(
                           expr,
                           self.Restrictions.Merge(arg0.Restrictions)
                           ));
            }

            return(null);
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] // TODO: fix
        private void MakeOperatorRule(OperatorInfo info)
        {
            MethodInfo[] targets = GetApplicableMembers(info);
            if (targets.Length == 0)
            {
                targets = GetFallbackMembers(_types[0], info);
            }

            if (targets.Length > 0 && TryMakeBindingTarget(targets))
            {
                return;
            }

            if (_types.Length > 1)
            {
                targets = GetApplicableMembers(_types[1], info);
                if (targets.Length > 0 && TryMakeBindingTarget(targets))
                {
                    return;
                }
            }

            Operators op = CompilerHelpers.InPlaceOperatorToOperator(info.Operator);

            if (op != Operators.None)
            {
                // recurse to try and get the non-inplace action...
                MakeOperatorRule(OperatorInfo.GetOperatorInfo(op));
                return;
            }

            if (_types.Length == 2 &&
                TypeUtils.GetNonNullableType(_types[0]) == TypeUtils.GetNonNullableType(_types[1]) &&
                TypeUtils.IsArithmetic(_types[0]))
            {
                // TODO: Nullable<PrimitveType> Support
                Expression expr;
                switch (info.Operator)
                {
                case Operators.Add: expr = Ast.Add(Param0, Param1); break;

                case Operators.Subtract: expr = Ast.Subtract(Param0, Param1); break;

                case Operators.Divide: expr = Ast.Divide(Param0, Param1); break;

                case Operators.Mod: expr = Ast.Modulo(Param0, Param1); break;

                case Operators.Multiply: expr = Ast.Multiply(Param0, Param1); break;

                case Operators.LeftShift: expr = Ast.LeftShift(Param0, Param1); break;

                case Operators.RightShift: expr = Ast.RightShift(Param0, Param1); break;

                case Operators.BitwiseAnd: expr = Ast.And(Param0, Param1); break;

                case Operators.BitwiseOr: expr = Ast.Or(Param0, Param1); break;

                case Operators.ExclusiveOr: expr = Ast.ExclusiveOr(Param0, Param1); break;

                default: throw new InvalidOperationException();
                }
                _rule.Target = _rule.MakeReturn(Binder, expr);
                return;
            }
            else if (_types.Length == 1 && TryMakeDefaultUnaryRule(info))
            {
                return;
            }

            SetErrorTarget(info);
        }
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed)
        {
            var actualArgs     = resolver.GetActualArguments();
            int splatIndex     = actualArgs.SplatIndex;
            int collapsedCount = actualArgs.CollapsedCount;
            int firstSplatted  = actualArgs.FirstSplattedArg;

            var result        = new Expression[2 + _expandedCount + (collapsedCount > 0 ? 2 : 0)];
            var arrayVariable = resolver.GetTemporary(_elementType.MakeArrayType(), "a");
            int e             = 0;

            result[e++] = Ast.Assign(arrayVariable, Ast.NewArrayBounds(_elementType, Ast.Constant(_expandedCount + collapsedCount)));

            int itemIndex = 0;
            int i         = _start;

            while (true)
            {
                // inject loop copying collapsed items:
                if (i == splatIndex)
                {
                    var indexVariable = resolver.GetTemporary(typeof(int), "t");

                    // for (int t = 0; t <= {collapsedCount}; t++) {
                    //   a[{itemIndex} + t] = CONVERT<ElementType>(list.get_Item({splatIndex - firstSplatted} + t))
                    // }
                    result[e++] = Ast.Assign(indexVariable, AstUtils.Constant(0));
                    result[e++] = AstUtils.Loop(
                        Ast.LessThan(indexVariable, Ast.Constant(collapsedCount)),
                        // TODO: not implemented in the old interpreter
                        // Ast.PostIncrementAssign(indexVariable),
                        Ast.Assign(indexVariable, Ast.Add(indexVariable, AstUtils.Constant(1))),
                        Ast.Assign(
                            Ast.ArrayAccess(arrayVariable, Ast.Add(AstUtils.Constant(itemIndex), indexVariable)),
                            resolver.Convert(
                                new DynamicMetaObject(
                                    resolver.GetSplattedItemExpression(Ast.Add(AstUtils.Constant(splatIndex - firstSplatted), indexVariable)),
                                    BindingRestrictions.Empty
                                    ),
                                null,
                                ParameterInfo,
                                _elementType
                                )
                            ),
                        null
                        );

                    itemIndex += collapsedCount;
                }

                if (i >= _start + _expandedCount)
                {
                    break;
                }

                Debug.Assert(!hasBeenUsed[i]);
                hasBeenUsed[i] = true;

                result[e++] = Ast.Assign(
                    Ast.ArrayAccess(arrayVariable, AstUtils.Constant(itemIndex++)),
                    resolver.Convert(args.GetObject(i), args.GetType(i), ParameterInfo, _elementType)
                    );

                i++;
            }

            result[e++] = arrayVariable;

            Debug.Assert(e == result.Length);
            return(Ast.Block(result));
        }