private static TotemOperationKind NormalizeOperator(TotemOperationKind op) { if ((op & TotemOperationKind.DisableCoerce) != 0) { op = op & ~TotemOperationKind.DisableCoerce; } return op; }
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; }
public static DynamicMetaObjectBinder BinaryOperationBinder(TotemContext state, TotemOperationKind operatorName) { ExpressionType? et = GetExpressionTypeFromBinaryOperator(operatorName); if (et == null) { return state.Operation( operatorName ); } return state.BinaryOperation(et.Value); }
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); }
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); }
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(); }
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 ); }
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; }
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; } }
public TotemOperationBinder(TotemContext context, TotemOperationKind operation) { _context = context; _operation = operation; }