private static TotemOperationKind NormalizeOperator(TotemOperationKind op)
 {
     if ((op & TotemOperationKind.DisableCoerce) != 0)
     {
         op = op & ~TotemOperationKind.DisableCoerce;
     }
     return op;
 }
예제 #2
0
 private static ExpressionType? GetExpressionTypeFromUnaryOperator(TotemOperationKind operatorName)
 {
     switch(operatorName)
     {
         case TotemOperationKind.Positive: return ExpressionType.UnaryPlus;
         case TotemOperationKind.Negate: return ExpressionType.Negate;
         case TotemOperationKind.OnesComplement: return ExpressionType.OnesComplement;
         case TotemOperationKind.Not: return ExpressionType.Not;
         case TotemOperationKind.IsFalse: return ExpressionType.IsFalse;
     }
     return null;
 }
예제 #3
0
        public static DynamicMetaObjectBinder BinaryOperationBinder(TotemContext state, TotemOperationKind operatorName)
        {
            ExpressionType? et = GetExpressionTypeFromBinaryOperator(operatorName);

            if (et == null)
            {
                return state.Operation(
                    operatorName
                );
            }

            return state.BinaryOperation(et.Value);
        }
예제 #4
0
        internal override Expression TransformSet(SourceSpan span, Expression right, TotemOperationKind op)
        {
            Expression assignment;

            if (op != TotemOperationKind.None)
            {
                right = GlobalParent.Operation(
                    typeof(object),
                    op,
                    this,
                    right
                );
            }

            SourceSpan aspan = span.IsValid ? new SourceSpan(span.Start, span.End) : SourceSpan.None;

            ParameterExpression tmp = Expression.Variable(typeof(object), "$assignTmp");
            right = Expression.Assign(tmp, ConvertIfNeeded(right, typeof(object)));

            if (_variable != null)
            {
                assignment = AssignValue(
                    Parent.GetVariableExpression(_variable),
                    right
                );
            }
            else
            {
                throw new InvalidOperationException("No variable exists??");
            }

            assignment = Expression.Block(
                new[] { tmp },
                assignment,
                tmp
            );

            return GlobalParent.AddDebugInfo(assignment, aspan);
        }
예제 #5
0
        private static ExpressionType? GetExpressionTypeFromBinaryOperator(TotemOperationKind operatorName)
        {
            switch (operatorName)
            {
                case TotemOperationKind.Add: return ExpressionType.Add;
                case TotemOperationKind.BitwiseAnd: return ExpressionType.And;
                case TotemOperationKind.Divide: return ExpressionType.Divide;
                case TotemOperationKind.ExclusiveOr: return ExpressionType.ExclusiveOr;
                case TotemOperationKind.Mod: return ExpressionType.Modulo;
                case TotemOperationKind.Multiply: return ExpressionType.Multiply;
                case TotemOperationKind.BitwiseOr: return ExpressionType.Or;
                case TotemOperationKind.Power: return ExpressionType.Power;
                case TotemOperationKind.RightShift: return ExpressionType.RightShift;
                case TotemOperationKind.LeftShift: return ExpressionType.LeftShift;
                case TotemOperationKind.Subtract: return ExpressionType.Subtract;

                case TotemOperationKind.InPlaceAdd: return ExpressionType.AddAssign;
                case TotemOperationKind.InPlaceBitwiseAnd: return ExpressionType.AndAssign;
                case TotemOperationKind.InPlaceDivide: return ExpressionType.DivideAssign;
                case TotemOperationKind.InPlaceExclusiveOr: return ExpressionType.ExclusiveOrAssign;
                case TotemOperationKind.InPlaceMod: return ExpressionType.ModuloAssign;
                case TotemOperationKind.InPlaceMultiply: return ExpressionType.MultiplyAssign;
                case TotemOperationKind.InPlaceBitwiseOr: return ExpressionType.OrAssign;
                case TotemOperationKind.InPlacePower: return ExpressionType.PowerAssign;
                case TotemOperationKind.InPlaceRightShift: return ExpressionType.RightShiftAssign;
                case TotemOperationKind.InPlaceLeftShift: return ExpressionType.LeftShiftAssign;
                case TotemOperationKind.InPlaceSubtract: return ExpressionType.SubtractAssign;

                case TotemOperationKind.Equal: return ExpressionType.Equal;
                case TotemOperationKind.GreaterThan: return ExpressionType.GreaterThan;
                case TotemOperationKind.GreaterThanOrEqual: return ExpressionType.GreaterThanOrEqual;
                case TotemOperationKind.LessThan: return ExpressionType.LessThan;
                case TotemOperationKind.LessThanOrEqual: return ExpressionType.LessThanOrEqual;
                case TotemOperationKind.NotEqual: return ExpressionType.NotEqual;
            }
            return null;
        }
 private static bool IsComparison(TotemOperationKind op)
 {
     return IsComparisonOperator(NormalizeOperator(op));
 }
 private static bool IsComparisonOperator(TotemOperationKind op)
 {
     return (op & TotemOperationKind.Comparison) != 0;
 }
 private static DynamicMetaObject MakeUnaryOperation(DynamicMetaObjectBinder binder, DynamicMetaObject self, TotemOperationKind symbol, DynamicMetaObject errorSuggestion, Type retType)
 {
     self = self.Restrict(self.GetLimitType());
     throw new NotImplementedException();
 }
        private static DynamicMetaObject MakeSimpleOperation(DynamicMetaObject[] types, DynamicMetaObjectBinder operation, TotemOperationKind opString, DynamicMetaObject errorSuggestion)
        {
            RestrictTypes(types);

            TotemType ltype = MetaTotemObject.GetTotemType(types[0]);
            TotemType rtype = MetaTotemObject.GetTotemType(types[1]);

            var matches = ltype.GetOperatorFunctions(opString)
                .Union(rtype.GetOperatorFunctions(opString))
                .ToList();

            var overloadResolver = GetTotemContext(operation).SharedOverloadResolverFactory.CreateOverloadResolver(types, new CallSignature(2), CallTypes.None);
            var ret = overloadResolver.ResolveOverload(opString.ToString(), ArrayUtils.ToArray(matches, m => CreateOverloadInfo(m)), NarrowingLevel.None, NarrowingLevel.All);

            if (!ret.Success)
            {
                return new DynamicMetaObject(
                    Expression.Throw(
                        Expression.Call(
                            AstMethods.TypeError,
                            Utils.Constant("No operator {0} found between types {1} and {2}."),
                            Expression.NewArrayInit(
                                typeof(string),
                                Expression.Constant(opString.ToString()),
                                Expression.Constant(ltype.Name),
                                Expression.Constant(rtype.Name)
                            )
                        )
                    ),
                    BindingRestrictions.Combine(types)
                );
            }
            return new DynamicMetaObject(ret.MakeExpression(), ret.RestrictedArguments.GetAllRestrictions());
        }
 private static DynamicMetaObject MakeComparisonOperation(DynamicMetaObject[] types, DynamicMetaObjectBinder operation, TotemOperationKind opString, DynamicMetaObject errorSuggestion)
 {
     throw new NotImplementedException();
 }
 private static DynamicMetaObject MakeBinaryOperation(DynamicMetaObjectBinder operation, DynamicMetaObject[] args, TotemOperationKind opStr, DynamicMetaObject errorSuggestion)
 {
     if (IsComparison(opStr))
         return MakeComparisonOperation(args, operation, opStr, errorSuggestion);
     return MakeSimpleOperation(args, operation, opStr, errorSuggestion);
 }
예제 #12
0
 internal virtual Expression TransformSet(SourceSpan span, Expression right, TotemOperationKind op)
 {
     // unreachable, CheckAssign prevents us from calling this at parse time.
     Debug.Assert(false);
     throw new InvalidOperationException();
 }
예제 #13
0
        internal Expression Operation(Type resultType, TotemOperationKind operation, Expression arg0, Expression arg1)
        {
            if (resultType == typeof(object))
            {
                return new TotemDynamicExpression2(
                    Binders.BinaryOperationBinder(
                        TotemContext,
                        operation
                    ),
                    CompilationMode,
                    arg0,
                    arg1
                );
            }

            return CompilationMode.Dynamic(
                Binders.BinaryOperationBinder(
                    TotemContext,
                    operation
                ),
                resultType,
                arg0,
                arg1
            );
        }
예제 #14
0
        internal IEnumerable<MethodOrFunction> GetOperatorFunctions(TotemOperationKind op)
        {
            if (_operators == null)
                Interlocked.CompareExchange(ref _operators, GetOperators(this), null);

            ReadOnlyCollection<MethodOrFunction> ret;
            if (!_operators.TryGetValue(op, out ret))
                return new MethodOrFunction[0];

            return ret;
        }
예제 #15
0
        internal TotemOperationBinder Operation(TotemOperationKind operation)
        {
            if (_operationBinders == null)
            {
                Interlocked.CompareExchange(
                    ref _operationBinders,
                    new Dictionary<TotemOperationKind, TotemOperationBinder>(),
                    null
                );
            }

            lock (_operationBinders)
            {
                TotemOperationBinder res;
                if (!_operationBinders.TryGetValue(operation, out res))
                    _operationBinders[operation] = res = new TotemOperationBinder(this, operation);

                return res;
            }
        }
예제 #16
0
 public TotemOperationBinder(TotemContext context, TotemOperationKind operation)
 {
     _context = context;
     _operation = operation;
 }