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) ) ) )); }
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); }
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); }
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)); }