Example #1
0
        RichCompare(IntPtr ptr1, IntPtr ptr2, int opid)
        {
            object objResult = true;
            CMP    op        = (CMP)opid;

            switch (op)
            {
            case CMP.Py_LT:
                objResult = PythonOperator.lt(this.scratchContext, this.Retrieve(ptr1), this.Retrieve(ptr2));
                break;

            case CMP.Py_LE:
                objResult = PythonOperator.le(this.scratchContext, this.Retrieve(ptr1), this.Retrieve(ptr2));
                break;

            case CMP.Py_EQ:
                objResult = PythonOperator.eq(this.scratchContext, this.Retrieve(ptr1), this.Retrieve(ptr2));
                break;

            case CMP.Py_NE:
                objResult = PythonOperator.ne(this.scratchContext, this.Retrieve(ptr1), this.Retrieve(ptr2));
                break;

            case CMP.Py_GT:
                objResult = PythonOperator.gt(this.scratchContext, this.Retrieve(ptr1), this.Retrieve(ptr2));
                break;

            case CMP.Py_GE:
                objResult = PythonOperator.ge(this.scratchContext, this.Retrieve(ptr1), this.Retrieve(ptr2));
                break;
            }
            return(objResult);
        }
 private LazyValueInfo(Node node, LazyValueInfo left, PythonOperator op, LazyValueInfo right)
 {
     _node  = node;
     _left  = left;
     _op    = op;
     _right = right;
 }
        public static PythonOperator InvertComparison(this PythonOperator self)
        {
            switch (self)
            {
            case PythonOperator.LessThan: return(PythonOperator.GreaterThanOrEqual);

            case PythonOperator.LessThanOrEqual: return(PythonOperator.GreaterThan);

            case PythonOperator.GreaterThan: return(PythonOperator.LessThanOrEqual);

            case PythonOperator.GreaterThanOrEqual: return(PythonOperator.LessThan);

            case PythonOperator.Equal: return(PythonOperator.NotEqual);

            case PythonOperator.NotEqual: return(PythonOperator.Equal);

            case PythonOperator.In: return(PythonOperator.NotIn);

            case PythonOperator.NotIn: return(PythonOperator.In);

            case PythonOperator.IsNot: return(PythonOperator.Is);

            case PythonOperator.Is: return(PythonOperator.IsNot);
            }

            return(PythonOperator.None);
        }
Example #4
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
            IAnalysisSet res;

            switch (operation) {
                case PythonOperator.BitwiseOr:
                    var seq = (SetInfo)unit.Scope.GetOrMakeNodeValue(
                        node,
                        _ => new SetInfo(ProjectState, node, unit.ProjectEntry)
                    );
                    seq.AddTypes(unit, GetEnumeratorTypes(node, unit));
                    foreach (var type in rhs.Where(t => t.IsOfType(ClassInfo))) {
                        seq.AddTypes(unit, type.GetEnumeratorTypes(node, unit));
                    }
                    res = seq;
                    break;
                case PythonOperator.BitwiseAnd:
                case PythonOperator.ExclusiveOr:
                case PythonOperator.Subtract:
                    res = this;
                    break;
                default:
                    res = CallReverseBinaryOp(node, unit, operation, rhs);
                    break;
            }

            return res;
        }
 PySequence_Repeat(IntPtr objPtr, int count)
 {
     try
     {
         IntPtr typePtr = CPyMarshal.ReadPtrField(objPtr, typeof(PyObject), "ob_type");
         IntPtr seqPtr  = CPyMarshal.ReadPtrField(typePtr, typeof(PyTypeObject), "tp_as_sequence");
         if (seqPtr != IntPtr.Zero)
         {
             IntPtr sq_repeat = CPyMarshal.ReadPtrField(seqPtr, typeof(PySequenceMethods), "sq_repeat");
             if (sq_repeat != IntPtr.Zero)
             {
                 dgt_ptr_ptrint dgt = (dgt_ptr_ptrint)CPyMarshal.ReadFunctionPtrField(
                     seqPtr, typeof(PySequenceMethods), "sq_repeat", typeof(dgt_ptr_ptrint));
                 return(dgt(objPtr, count));
             }
         }
         object obj = this.Retrieve(objPtr);
         if ((!Builtin.isinstance(obj, TypeCache.PythonType)) &&
             Builtin.hasattr(this.scratchContext, obj, "__len__") &&
             Builtin.hasattr(this.scratchContext, obj, "__getitem__"))
         {
             return(this.Store(PythonOperator.mul(this.scratchContext, obj, (int)count)));
         }
         throw PythonOps.TypeError("PySequence_Repeat: failed to convert {0} to sequence", obj);
     }
     catch (Exception e)
     {
         this.LastException = e;
         return(IntPtr.Zero);
     }
 }
Example #6
0
 public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
     var res = AnalysisSet.Empty;
     foreach (var member in _members) {
         res = res.Union(member.BinaryOperation(node, unit, operation, rhs));
     }
     return res;
 }
Example #7
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs)
        {
            IAnalysisSet res;

            switch (operation)
            {
            case PythonOperator.BitwiseOr:
                var seq = (SetInfo)unit.Scope.GetOrMakeNodeValue(
                    node,
                    _ => new SetInfo(ProjectState, node, unit.ProjectEntry)
                    );
                seq.AddTypes(unit, GetEnumeratorTypes(node, unit));
                foreach (var type in rhs.Where(t => t.IsOfType(ClassInfo)))
                {
                    seq.AddTypes(unit, type.GetEnumeratorTypes(node, unit));
                }
                res = seq;
                break;

            case PythonOperator.BitwiseAnd:
            case PythonOperator.ExclusiveOr:
            case PythonOperator.Subtract:
                res = this;
                break;

            default:
                res = CallReverseBinaryOp(node, unit, operation, rhs);
                break;
            }

            return(res);
        }
Example #8
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs)
        {
            switch (operation)
            {
            case PythonOperator.GreaterThan:
            case PythonOperator.LessThan:
            case PythonOperator.LessThanOrEqual:
            case PythonOperator.GreaterThanOrEqual:
            case PythonOperator.Equal:
            case PythonOperator.NotEqual:
            case PythonOperator.Is:
            case PythonOperator.IsNot:
                return(ProjectState.ClassInfos[BuiltinTypeId.Bool].Instance);

            case PythonOperator.TrueDivide:
            case PythonOperator.Add:
            case PythonOperator.Subtract:
            case PythonOperator.Multiply:
            case PythonOperator.MatMultiply:
            case PythonOperator.Divide:
            case PythonOperator.Mod:
            case PythonOperator.BitwiseAnd:
            case PythonOperator.BitwiseOr:
            case PythonOperator.Xor:
            case PythonOperator.LeftShift:
            case PythonOperator.RightShift:
            case PythonOperator.Power:
            case PythonOperator.FloorDivide:
                return(ConstantInfo.NumericOp(node, this, unit, operation, rhs) ?? CallReverseBinaryOp(node, unit, operation, rhs));
            }
            return(CallReverseBinaryOp(node, unit, operation, rhs));
        }
Example #9
0
        public Node GetNode()
        {
            switch (NodeType)
            {
            case "NameExpression":
                return(new NameExpression(Value));

            case "CallExpression":
                var target = (Expression)Children[0].GetNode();
                var args   = new List <Arg>();
                if (Children.Count > 1)
                {
                    for (var i = 1; i < Children.Count; i++)
                    {
                        args.Add((Arg)Children[i].GetNode());
                    }
                }
                return(new CallExpression(target, args.ToArray()));

            case "Arg":
                var expression = (Expression)Children[0].GetNode();
                return((Value == null) ? new Arg(expression) :
                       new Arg(Value, expression));

            case "BinaryExpression":

                var            left  = (Expression)Children[0].GetNode();
                var            right = (Expression)Children[1].GetNode();
                PythonOperator op    = Value;
                return(new BinaryExpression(op, left, right));

            default:
                throw new NotImplementedException(NodeType);
            }
        }
Example #10
0
        public override IAnalysisSet UnaryOperation(Node node, AnalysisUnit unit, PythonOperator operation)
        {
            if (operation == PythonOperator.Not)
            {
                return(unit.State.ClassInfos[BuiltinTypeId.Bool].Instance);
            }

            string methodName = UnaryOpToString(unit.State, operation);

            if (methodName != null)
            {
                var method = GetTypeMember(node, unit, methodName);
                if (method.Count > 0)
                {
                    var res = method.Call(
                        node,
                        unit,
                        new[] { this },
                        ExpressionEvaluator.EmptyNames
                        );

                    return(res);
                }
            }
            return(base.UnaryOperation(node, unit, operation));
        }
        private static IAnalysisSet QuickOp(IAnalysisSet lhs, PythonOperator op, IAnalysisSet rhs, PythonAnalyzer state)
        {
            // Concrete return for known (or conventional) operations
            switch (op)
            {
            case PythonOperator.Equal:
            case PythonOperator.In:
            case PythonOperator.Is:
            case PythonOperator.IsNot:
            case PythonOperator.Not:
            case PythonOperator.NotEqual:
            case PythonOperator.NotIn:
                return(state.ClassInfos[BuiltinTypeId.Bool].Instance);

            case PythonOperator.GreaterThan:
            case PythonOperator.GreaterThanOrEqual:
            case PythonOperator.LessThan:
            case PythonOperator.LessThanOrEqual:
                return(lhs.Union(rhs));

            case PythonOperator.Negate:
            case PythonOperator.Pos:
                return(rhs);
            }
            return(null);
        }
        private IAnalysisSet NumericOp(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs)
        {
            string methodName = InstanceInfo.BinaryOpToString(operation);

            if (methodName != null)
            {
                var method = GetMember(node, unit, methodName);
                if (method.Count > 0)
                {
                    var res = method.Call(
                        node,
                        unit,
                        new[] { this, rhs },
                        ExpressionEvaluator.EmptyNames
                        );

                    if (res.IsObjectOrUnknown())
                    {
                        // the type defines the operator, assume it returns
                        // some combination of the input types.
                        return(SelfSet.Union(rhs));
                    }

                    return(res);
                }
            }

            return(base.BinaryOperation(node, unit, operation, rhs));
        }
Example #13
0
 public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
     switch (operation) {
         case PythonOperator.GreaterThan:
         case PythonOperator.LessThan:
         case PythonOperator.LessThanOrEqual:
         case PythonOperator.GreaterThanOrEqual:
         case PythonOperator.Equal:
         case PythonOperator.NotEqual:
         case PythonOperator.Is:
         case PythonOperator.IsNot:
             return ProjectState.ClassInfos[BuiltinTypeId.Bool].Instance;
         case PythonOperator.TrueDivide:
         case PythonOperator.Add:
         case PythonOperator.Subtract:
         case PythonOperator.Multiply:
         case PythonOperator.MatMultiply:
         case PythonOperator.Divide:
         case PythonOperator.Mod:
         case PythonOperator.BitwiseAnd:
         case PythonOperator.BitwiseOr:
         case PythonOperator.Xor:
         case PythonOperator.LeftShift:
         case PythonOperator.RightShift:
         case PythonOperator.Power:
         case PythonOperator.FloorDivide:
             return ConstantInfo.NumericOp(node, this, unit, operation, rhs) ?? CallReverseBinaryOp(node, unit, operation, rhs);
     }
     return CallReverseBinaryOp(node, unit, operation, rhs);
 }
Example #14
0
 public override IAnalysisSet UnaryOperation(Node node, AnalysisUnit unit, PythonOperator operation)
 {
     if (_original == null)
     {
         return(AnalysisSet.Empty);
     }
     return(_original.UnaryOperation(node, unit, operation));
 }
Example #15
0
 public BinaryExpression(PythonOperator op, Expression left, Expression right)
 {
     _op    = op;
     _left  = left;
     _right = right;
     //StartIndex = left.StartIndex;
     //EndIndex = right.EndIndex;
 }
        private static (string name, string swappedName) OpMethodName(PythonOperator op)
        {
            switch (op)
            {
            // Unary operators
            // Not cannot be overridden, there is no method for it.
            case PythonOperator.Pos: return("__pos__", null);

            case PythonOperator.Invert: return("__invert__", null);

            case PythonOperator.Negate: return("__neg__", null);

            // Numeric operators, can be swapped
            case PythonOperator.Add: return("__add__", "__radd__");

            case PythonOperator.Subtract: return("__sub__", "__rsub__");

            case PythonOperator.Multiply: return("__mul__", "__rmul__");

            case PythonOperator.MatMultiply: return("__matmul__", "__rmatmul__");

            case PythonOperator.Divide: return("__div__", "__rdiv__");      // The parser has already chosen the correct operator here; no need to check versions.

            case PythonOperator.TrueDivide: return("__truediv__", "__rtruediv__");

            case PythonOperator.Mod: return("__mod__", "__rmod__");

            case PythonOperator.BitwiseAnd: return("__and__", "__rand__");

            case PythonOperator.BitwiseOr: return("__or__", "__ror__");

            case PythonOperator.Xor: return("__xor__", "__rxor__");

            case PythonOperator.LeftShift: return("__lshift__", "__rlshift__");

            case PythonOperator.RightShift: return("__rshift__", "__rrshift__");

            case PythonOperator.Power: return("__pow__", "__rpow__");

            case PythonOperator.FloorDivide: return("__floordiv__", "__rfloordiv__");

            // Comparison operators
            case PythonOperator.LessThan: return("__lt__", null);

            case PythonOperator.LessThanOrEqual: return("__le__", null);

            case PythonOperator.GreaterThan: return("__gt__", null);

            case PythonOperator.GreaterThanOrEqual: return("__ge__", null);

            case PythonOperator.Equal: return("__eq__", null);

            case PythonOperator.NotEqual: return("__ne__", null);
            }

            return(null, null);
        }
Example #17
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs)
        {
            SequenceInfo seq = null;
            VariableDef  idx = null;
            var          res = AnalysisSet.Empty;

            switch (operation)
            {
            case PythonOperator.Add:
                foreach (var type in rhs.Where(t => !t.IsOfType(ClassInfo)))
                {
                    res = res.Union(CallReverseBinaryOp(node, unit, operation, rhs));
                }

                foreach (var type in rhs.Where(t => t.IsOfType(ClassInfo)))
                {
                    if (seq == null)
                    {
                        seq = (SequenceInfo)unit.Scope.GetOrMakeNodeValue(node,
                                                                          NodeValueKind.Sequence,
                                                                          _ => new SequenceInfo(new[] { new VariableDef() }, ClassInfo, node, unit.ProjectEntry)
                                                                          );
                        idx = seq.IndexTypes[0];
                        idx.AddTypes(unit, GetEnumeratorTypes(node, unit), true, DeclaringModule);
                    }
                    idx.AddTypes(unit, type.GetEnumeratorTypes(node, unit), true, DeclaringModule);
                    idx.MakeUnionStrongerIfMoreThan(ProjectState.Limits.IndexTypes);
                }

                if (seq != null)
                {
                    res = res.Union(seq);
                }
                break;

            case PythonOperator.Multiply:
                foreach (var type in rhs)
                {
                    var typeId = type.TypeId;

                    if (typeId == BuiltinTypeId.Int || typeId == BuiltinTypeId.Long)
                    {
                        res = res.Union(this);
                    }
                    else
                    {
                        res = res.Union(CallReverseBinaryOp(node, unit, operation, type));
                    }
                }
                break;

            default:
                res = CallReverseBinaryOp(node, unit, operation, rhs);
                break;
            }
            return(res);
        }
Example #18
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs)
        {
            if (_original == null)
            {
                return(base.BinaryOperation(node, unit, operation, rhs));
            }

            return(_original.BinaryOperation(node, unit, operation, rhs));
        }
 public static bool IsComparison(this PythonOperator self) => self == PythonOperator.LessThan ||
 self == PythonOperator.LessThanOrEqual ||
 self == PythonOperator.GreaterThan ||
 self == PythonOperator.GreaterThanOrEqual ||
 self == PythonOperator.Equal ||
 self == PythonOperator.NotEqual ||
 self == PythonOperator.In ||
 self == PythonOperator.NotIn ||
 self == PythonOperator.IsNot ||
 self == PythonOperator.Is;
Example #20
0
        public override IAnalysisSet UnaryOperation(Node node, AnalysisUnit unit, PythonOperator operation)
        {
            var res = AnalysisSet.Empty;

            foreach (var member in _members)
            {
                res = res.Union(member.UnaryOperation(node, unit, operation));
            }
            return(res);
        }
Example #21
0
        internal static IAnalysisSet NumericOp(Node node, BuiltinInstanceInfo lhs, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
            var res = AnalysisSet.Empty;
            var lhsType = lhs.TypeId;

            foreach(var ns in rhs) {
                var rhsType = ns.TypeId;

                // First handle string operations
                if (lhsType == BuiltinTypeId.Bytes || lhsType == BuiltinTypeId.Unicode) {
                    if (operation == PythonOperator.Mod) {
                        res = res.Union(lhs.ClassInfo.Instance);
                    } else if (operation == PythonOperator.Add &&
                        (rhsType == BuiltinTypeId.Bytes || rhsType == BuiltinTypeId.Unicode)) {
                        res = res.Union(lhs.ClassInfo.Instance);
                    } else if (operation == PythonOperator.Multiply &&
                        (rhsType == BuiltinTypeId.Int || rhsType == BuiltinTypeId.Long)) {
                        res = res.Union(lhs.ClassInfo.Instance);
                    }
                    continue;
                } else if (operation == PythonOperator.Multiply &&
                           (lhsType == BuiltinTypeId.Int || lhsType == BuiltinTypeId.Long)) {
                    if (rhsType == BuiltinTypeId.Str || rhsType == BuiltinTypeId.Bytes || rhsType == BuiltinTypeId.Unicode ||
                        rhsType == BuiltinTypeId.Tuple || rhsType == BuiltinTypeId.List) {
                        res = res.Union(unit.ProjectState.ClassInfos[rhsType].Instance);
                        continue;
                    }
                }

                // These specializations change rhsType before type promotion
                // rules are applied.
                if ((operation == PythonOperator.TrueDivide || 
                    (operation == PythonOperator.Divide && unit.ProjectState.LanguageVersion.Is3x())) &&
                    (lhsType == BuiltinTypeId.Int || lhsType == BuiltinTypeId.Long) &&
                    (rhsType == BuiltinTypeId.Int || rhsType == BuiltinTypeId.Long)) {
                    rhsType = BuiltinTypeId.Float;
                }

                // Type promotion rules are applied 
                if (lhsType == BuiltinTypeId.Unknown || lhsType > BuiltinTypeId.Complex || 
                    rhsType == BuiltinTypeId.Unknown || rhsType > BuiltinTypeId.Complex) {
                    // Non-numeric types require the reverse operation
                    res = res.Union(ns.ReverseBinaryOperation(node, unit, operation, lhs));
                } else if (lhsType == BuiltinTypeId.Complex || rhsType == BuiltinTypeId.Complex) {
                    res = res.Union(unit.ProjectState.ClassInfos[BuiltinTypeId.Complex].Instance);
                } else if (lhsType == BuiltinTypeId.Float || rhsType == BuiltinTypeId.Float) {
                    res = res.Union(unit.ProjectState.ClassInfos[BuiltinTypeId.Float].Instance);
                } else if (lhsType == BuiltinTypeId.Long || rhsType == BuiltinTypeId.Long) {
                    res = res.Union(unit.ProjectState.ClassInfos[BuiltinTypeId.Long].Instance);
                } else {
                    res = res.Union(unit.ProjectState.ClassInfos[BuiltinTypeId.Int].Instance);
                }
            }

            return res.Count > 0 ? res : null;
        }
Example #22
0
        public BinaryExpression(PythonOperator op, Expression left, Expression right) {
            Contract.Assert(left != null);
            Contract.Assert(right != null);
            if (op == PythonOperator.None) throw new ArgumentException("bad operator");

            _op = op;
            _left = left;
            _right = right;
            StartIndex = left.StartIndex;
            EndIndex = right.EndIndex;
        }
Example #23
0
 PyNumber_Index(IntPtr numberPtr)
 {
     try
     {
         object result = PythonOperator.index(this.Retrieve(numberPtr));
         return(this.Store(result));
     }
     catch (Exception e)
     {
         this.LastException = e;
         return(IntPtr.Zero);
     }
 }
Example #24
0
 PyObject_DelItemString(IntPtr objPtr, string key)
 {
     try
     {
         PythonOperator.delitem(this.scratchContext, this.Retrieve(objPtr), key);
         return(0);
     }
     catch (Exception e)
     {
         this.LastException = e;
         return(-1);
     }
 }
Example #25
0
 PyObject_SetItem(IntPtr objPtr, IntPtr keyPtr, IntPtr valuePtr)
 {
     try
     {
         PythonOperator.setitem(this.scratchContext, this.Retrieve(objPtr), this.Retrieve(keyPtr), this.Retrieve(valuePtr));
         return(0);
     }
     catch (Exception e)
     {
         this.LastException = e;
         return(-1);
     }
 }
Example #26
0
 PySequence_Concat(IntPtr seq1Ptr, IntPtr seq2Ptr)
 {
     try
     {
         return(this.Store(PythonOperator.add(
                               this.scratchContext, this.Retrieve(seq1Ptr), this.Retrieve(seq2Ptr))));
     }
     catch (Exception e)
     {
         this.LastException = e;
         return(IntPtr.Zero);
     }
 }
 internal static bool IsComparison(this PythonOperator self)
 {
     return(self == PythonOperator.LessThan ||
            self == PythonOperator.LessThanOrEqual ||
            self == PythonOperator.GreaterThan ||
            self == PythonOperator.GreaterThanOrEqual ||
            self == PythonOperator.Equal ||
            self == PythonOperator.NotEqual ||
            self == PythonOperator.In ||
            self == PythonOperator.NotIn ||
            self == PythonOperator.IsNot ||
            self == PythonOperator.Is);
 }
 PyMapping_GetItemString(IntPtr mappingPtr, string key)
 {
     try
     {
         object result = PythonOperator.getitem(this.scratchContext, this.Retrieve(mappingPtr), key);
         return(this.Store(result));
     }
     catch (Exception e)
     {
         this.LastException = e;
         return(IntPtr.Zero);
     }
 }
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs)
        {
            var res = AnalysisSet.Empty;

            switch (operation)
            {
            case PythonOperator.Add:
                foreach (var type in rhs)
                {
                    if (type.IsOfType(ClassInfo))
                    {
                        res = res.Union(ClassInfo.Instance);
                    }
                    else
                    {
                        res = res.Union(type.ReverseBinaryOperation(node, unit, operation, SelfSet));
                    }
                }
                break;

            case PythonOperator.Mod:
                if (_supportsMod)
                {
                    res = SelfSet;
                }
                break;

            case PythonOperator.Multiply:
                foreach (var type in rhs)
                {
                    if (type.IsOfType(ProjectState.ClassInfos[BuiltinTypeId.Int]) || type.IsOfType(ProjectState.ClassInfos[BuiltinTypeId.Long]))
                    {
                        res = res.Union(ClassInfo.Instance);
                    }
                    else
                    {
                        var partialRes = ConstantInfo.NumericOp(node, this, unit, operation, rhs);
                        if (partialRes != null)
                        {
                            res = res.Union(partialRes);
                        }
                    }
                }
                break;
            }
            if (res.Count == 0)
            {
                return(CallReverseBinaryOp(node, unit, operation, rhs));
            }
            return(res);
        }
        private IMember HandleStringLike(PythonOperator op, BuiltinTypeId str, BuiltinTypeId other)
        {
            switch (op)
            {
            case PythonOperator.Multiply when other == BuiltinTypeId.Bool || other == BuiltinTypeId.Int || other == BuiltinTypeId.Long:
            case PythonOperator.Add when str == other:
                return(Interpreter.GetBuiltinType(str));

            case PythonOperator.Add when str == BuiltinTypeId.Unicode || other == BuiltinTypeId.Unicode:
                return(Interpreter.GetBuiltinType(BuiltinTypeId.Unicode));
            }

            return(UnknownType);
        }
Example #31
0
        public BinaryExpression(PythonOperator op, Expression left, Expression right, int operatorIndex)
        {
            if (op == PythonOperator.None)
            {
                throw new ArgumentException("bad operator");
            }

            Operator      = op;
            Left          = left ?? throw new ArgumentNullException(nameof(left));
            Right         = right ?? throw new ArgumentNullException(nameof(right));
            StartIndex    = left.StartIndex;
            EndIndex      = right.EndIndex;
            OperatorIndex = operatorIndex;
        }
Example #32
0
        private MSAst.Expression MakeBinaryOperation(PythonOperator op, MSAst.Expression left, MSAst.Expression right, SourceSpan span)
        {
            if (op == PythonOperator.NotIn)
            {
                return(AstUtils.Convert(
                           Ast.Not(
                               GlobalParent.Operation(
                                   typeof(bool),
                                   PythonOperationKind.Contains,
                                   left,
                                   right
                                   )
                               ),
                           typeof(object)
                           ));
            }
            else if (op == PythonOperator.In)
            {
                return(AstUtils.Convert(
                           GlobalParent.Operation(
                               typeof(bool),
                               PythonOperationKind.Contains,
                               left,
                               right
                               ),
                           typeof(object)
                           ));
            }

            PythonOperationKind action = PythonOperatorToAction(op);

            if (action != PythonOperationKind.None)
            {
                return(GlobalParent.Operation(
                           typeof(object),
                           action,
                           left,
                           right
                           ));
            }
            else
            {
                // Call helper method
                return(Ast.Call(
                           GetHelperMethod(op),
                           ConvertIfNeeded(left, typeof(object)),
                           ConvertIfNeeded(right, typeof(object))
                           ));
            }
        }
        private static PythonOperationKind PythonOperatorToAction(PythonOperator op)
        {
            switch (op)
            {
            // Binary
            case PythonOperator.Add:
                return(PythonOperationKind.InPlaceAdd);

            case PythonOperator.Subtract:
                return(PythonOperationKind.InPlaceSubtract);

            case PythonOperator.Multiply:
                return(PythonOperationKind.InPlaceMultiply);

            case PythonOperator.MatMult:
                return(PythonOperationKind.InPlaceMatMult);

            case PythonOperator.FloorDivide:
                return(PythonOperationKind.InPlaceFloorDivide);

            case PythonOperator.TrueDivide:
                return(PythonOperationKind.InPlaceTrueDivide);

            case PythonOperator.Mod:
                return(PythonOperationKind.InPlaceMod);

            case PythonOperator.BitwiseAnd:
                return(PythonOperationKind.InPlaceBitwiseAnd);

            case PythonOperator.BitwiseOr:
                return(PythonOperationKind.InPlaceBitwiseOr);

            case PythonOperator.Xor:
                return(PythonOperationKind.InPlaceExclusiveOr);

            case PythonOperator.LeftShift:
                return(PythonOperationKind.InPlaceLeftShift);

            case PythonOperator.RightShift:
                return(PythonOperationKind.InPlaceRightShift);

            case PythonOperator.Power:
                return(PythonOperationKind.InPlacePower);

            default:
                Debug.Assert(false, "Unexpected PythonOperator: " + op.ToString());
                return(PythonOperationKind.None);
            }
        }
        public BinaryExpression(PythonOperator op, Expression left, Expression right)
        {
            ContractUtils.RequiresNotNull(left, "left");
            ContractUtils.RequiresNotNull(right, "right");
            if (op == PythonOperator.None)
            {
                throw new ValueErrorException("bad operator");
            }

            _op        = op;
            _left      = left;
            _right     = right;
            StartIndex = left.StartIndex;
            EndIndex   = right.EndIndex;
        }
Example #35
0
        private static MethodInfo GetHelperMethod(PythonOperator op)
        {
            switch (op)
            {
            case PythonOperator.IsNot:
                return(AstMethods.IsNot);

            case PythonOperator.Is:
                return(AstMethods.Is);

            default:
                Debug.Assert(false, "Invalid PythonOperator: " + op.ToString());
                return(null);
            }
        }
Example #36
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
            SequenceInfo seq = null;
            VariableDef idx = null;
            var res = AnalysisSet.Empty;
            switch (operation) {
                case PythonOperator.Add:
                    foreach (var type in rhs.Where(t => !t.IsOfType(ClassInfo))) {
                        res = res.Union(CallReverseBinaryOp(node, unit, operation, rhs));
                    }
                    
                    foreach (var type in rhs.Where(t => t.IsOfType(ClassInfo))) {
                        if (seq == null) {
                            seq = (SequenceInfo)unit.Scope.GetOrMakeNodeValue(node,
                                NodeValueKind.Sequence,
                                _ => new SequenceInfo(new[] { new VariableDef() }, ClassInfo, node, unit.ProjectEntry)
                            );
                            idx = seq.IndexTypes[0];
                            idx.AddTypes(unit, GetEnumeratorTypes(node, unit), true, DeclaringModule);
                        }
                        idx.AddTypes(unit, type.GetEnumeratorTypes(node, unit), true, DeclaringModule);
                    }

                    if (seq != null) {
                        res = res.Union(seq);
                    }
                    break;
                case PythonOperator.Multiply:
                    foreach (var type in rhs) {
                        var typeId = type.TypeId;

                        if (typeId == BuiltinTypeId.Int || typeId == BuiltinTypeId.Long) {
                            res = res.Union(this);
                        } else {
                            res = res.Union(CallReverseBinaryOp(node, unit, operation, type));
                        }

                    }
                    break;
                default:
                    res = CallReverseBinaryOp(node, unit, operation, rhs);
                    break;
            }
            return res;
        }
Example #37
0
 private static string ReverseBinaryOpToString(PythonOperator operation) {
     string op = null;
     switch (operation) {
         case PythonOperator.Multiply: op = "__rmul__"; break;
         case PythonOperator.MatMultiply: op = "__rmatmul__"; break;
         case PythonOperator.Add: op = "__radd__"; break;
         case PythonOperator.Subtract: op = "__rsub__"; break;
         case PythonOperator.Xor: op = "__rxor__"; break;
         case PythonOperator.BitwiseAnd: op = "__rand__"; break;
         case PythonOperator.BitwiseOr: op = "__ror__"; break;
         case PythonOperator.Divide: op = "__rdiv__"; break;
         case PythonOperator.FloorDivide: op = "__rfloordiv__"; break;
         case PythonOperator.LeftShift: op = "__rlshift__"; break;
         case PythonOperator.Mod: op = "__rmod__"; break;
         case PythonOperator.Power: op = "__rpow__"; break;
         case PythonOperator.RightShift: op = "__rrshift__"; break;
         case PythonOperator.TrueDivide: op = "__rtruediv__"; break;
     }
     return op;
 }
Example #38
0
 public UnaryExpression(PythonOperator op, Expression expression) {
     _op = op;
     _expression = expression;
     EndIndex = expression.EndIndex;
 }
Example #39
0
 internal static string BinaryOpToString(PythonOperator operation) {
     string op = null;
     switch (operation) {
         case PythonOperator.Multiply: op = "__mul__"; break;
         case PythonOperator.MatMultiply: op = "__matmul__"; break;
         case PythonOperator.Add: op = "__add__"; break;
         case PythonOperator.Subtract: op = "__sub__"; break;
         case PythonOperator.Xor: op = "__xor__"; break;
         case PythonOperator.BitwiseAnd: op = "__and__"; break;
         case PythonOperator.BitwiseOr: op = "__or__"; break;
         case PythonOperator.Divide: op = "__div__"; break;
         case PythonOperator.FloorDivide: op = "__floordiv__"; break;
         case PythonOperator.LeftShift: op = "__lshift__"; break;
         case PythonOperator.Mod: op = "__mod__"; break;
         case PythonOperator.Power: op = "__pow__"; break;
         case PythonOperator.RightShift: op = "__rshift__"; break;
         case PythonOperator.TrueDivide: op = "__truediv__"; break;
     }
     return op;
 }
Example #40
0
        public override IAnalysisSet ReverseBinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
            string op = ReverseBinaryOpToString(operation);

            if (op != null) {
                var invokeMem = GetTypeMember(node, unit, op);
                if (invokeMem.Count > 0) {
                    // call __r*__ method
                    return invokeMem.Call(node, unit, new[] { rhs }, ExpressionEvaluator.EmptyNames);
                }
            }

            return base.ReverseBinaryOperation(node, unit, operation, rhs);
        }
Example #41
0
        public override IAnalysisSet UnaryOperation(Node node, AnalysisUnit unit, PythonOperator operation) {
            if (operation == PythonOperator.Not) {
                return unit.ProjectState.ClassInfos[BuiltinTypeId.Bool].Instance;
            }
            
            string methodName = UnaryOpToString(unit.ProjectState, operation);
            if (methodName != null) {
                var method = GetTypeMember(node, unit, methodName);
                if (method.Count > 0) {
                    var res = method.Call(
                        node,
                        unit,
                        new[] { this },
                        ExpressionEvaluator.EmptyNames
                    );

                    return res;
                }
            }
            return base.UnaryOperation(node, unit, operation);
        }
Example #42
0
 internal static string UnaryOpToString(PythonAnalyzer state, PythonOperator operation) {
     string op = null;
     switch (operation) {
         case PythonOperator.Not: op = state.LanguageVersion.Is3x() ? "__bool__" : "__nonzero__"; break;
         case PythonOperator.Pos: op = "__pos__"; break;
         case PythonOperator.Invert: op = "__invert__"; break;
         case PythonOperator.Negate: op = "__neg__"; break;
     }
     return op;
 }
Example #43
0
 public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
     return NumericOp(node, this, unit, operation, rhs) ?? _builtinInfo.BinaryOperation(node, unit, operation, rhs);
 }
Example #44
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
            string op = BinaryOpToString(operation);
            if (op != null) {
                IAnalysisSet res;
                if (TryInvokeMethod(node, unit, op, new[] { rhs }, out res)) {
                    return res;
                }
            }

            return _instances.BinaryOperation(
                node,
                unit,
                operation,
                rhs
            );
        }
Example #45
0
        private static Action<Statement> CheckAssignment(Action<Expression> lhs, PythonOperator op, Action<Expression> rhs) {
            return stmt => {
                Assert.AreEqual(typeof(AugmentedAssignStatement), stmt.GetType());
                var assign = (AugmentedAssignStatement)stmt;

                Assert.AreEqual(assign.Operator, op);

                lhs(assign.Left);
                rhs(assign.Right);
            };
        }
Example #46
0
 public override ISet<Namespace> UnaryOperation(IronPython.Compiler.Ast.Node node, AnalysisUnit unit, PythonOperator operation)
 {
     return _builtinInfo.UnaryOperation(node, unit, operation);
 }
Example #47
0
        /// <summary>
        /// Performs the specified operation on the value.
        /// </summary>
        public static IAnalysisSet UnaryOperation(this IAnalysisSet self, Node node, AnalysisUnit unit, PythonOperator operation) {
            var res = AnalysisSet.Empty;
            foreach (var ns in self) {
                res = res.Union(ns.UnaryOperation(node, unit, operation));
            }

            return res;
        }
Example #48
0
 private static Action<Expression> CheckBinaryExpression(Action<Expression> lhs, PythonOperator op, Action<Expression> rhs) {
     return expr => {
         Assert.AreEqual(typeof(BinaryExpression), expr.GetType());
         BinaryExpression bin = (BinaryExpression)expr;
         Assert.AreEqual(bin.Operator, op);
         lhs(bin.Left);
         rhs(bin.Right);
     };
 }
Example #49
0
 private static Action<Statement> CheckUnaryStmt(PythonOperator op, Action<Expression> value) {
     return CheckExprStmt(CheckUnaryExpression(op, value));
 }
Example #50
0
 private static Action<Expression> CheckUnaryExpression(PythonOperator op, Action<Expression> value) {
     return expr => {
         Assert.AreEqual(typeof(UnaryExpression), expr.GetType());
         var unary = (UnaryExpression)expr;
         Assert.AreEqual(unary.Op, op);
         value(unary.Expression);
     };
 }
Example #51
0
 private static Action<Statement> CheckBinaryStmt(Action<Expression> lhs, PythonOperator op, Action<Expression> rhs) {
     return CheckExprStmt(CheckBinaryExpression(lhs, op, rhs));
 }
Example #52
0
 public AugmentedAssignStatement(PythonOperator op, Expression left, Expression right) {
     _op = op;
     _left = left; 
     _right = right;
 }
Example #53
0
 public override IAnalysisSet UnaryOperation(Node node, AnalysisUnit unit, PythonOperator operation) {
     return _builtinInfo.UnaryOperation(node, unit, operation);
 }