@@ -9,10 +9,10 @@ package py
9
9
// A python Range object
10
10
// FIXME one day support BigInts too!
11
11
type Range struct {
12
- Start Int
13
- Stop Int
14
- Step Int
15
- // Length Object
12
+ Start Int
13
+ Stop Int
14
+ Step Int
15
+ Length Int
16
16
}
17
17
18
18
// A python Range iterator
@@ -53,10 +53,12 @@ func RangeNew(metatype *Type, args Tuple, kwargs StringDict) (Object, error) {
53
53
return nil , err
54
54
}
55
55
if len (args ) == 1 {
56
+ length := computeRangeLength (0 , startIndex , 1 )
56
57
return & Range {
57
- Start : Int (0 ),
58
- Stop : startIndex ,
59
- Step : Int (1 ),
58
+ Start : Int (0 ),
59
+ Stop : startIndex ,
60
+ Step : Int (1 ),
61
+ Length : length ,
60
62
}, nil
61
63
}
62
64
stopIndex , err := Index (stop )
@@ -67,10 +69,12 @@ func RangeNew(metatype *Type, args Tuple, kwargs StringDict) (Object, error) {
67
69
if err != nil {
68
70
return nil , err
69
71
}
72
+ length := computeRangeLength (startIndex , stopIndex , stepIndex )
70
73
return & Range {
71
- Start : startIndex ,
72
- Stop : stopIndex ,
73
- Step : stepIndex ,
74
+ Start : startIndex ,
75
+ Stop : stopIndex ,
76
+ Step : stepIndex ,
77
+ Length : length ,
74
78
}, nil
75
79
}
76
80
@@ -82,6 +86,10 @@ func (r *Range) M__iter__() (Object, error) {
82
86
}, nil
83
87
}
84
88
89
+ func (r * Range ) M__len__ () (Object , error ) {
90
+ return r .Length , nil
91
+ }
92
+
85
93
// Range iterator
86
94
func (it * RangeIterator ) M__iter__ () (Object , error ) {
87
95
return it , nil
@@ -97,6 +105,25 @@ func (it *RangeIterator) M__next__() (Object, error) {
97
105
return r , nil
98
106
}
99
107
108
+ func computeRangeLength (start , stop , step Int ) Int {
109
+ var lo , hi Int
110
+ if step > 0 {
111
+ lo = start
112
+ hi = stop
113
+ step = step
114
+ } else {
115
+ lo = stop
116
+ hi = start
117
+ step = (- step )
118
+ }
119
+
120
+ if lo >= hi {
121
+ return Int (0 )
122
+ }
123
+ res := (hi - lo - 1 )/ step + 1
124
+ return res
125
+ }
126
+
100
127
// Check interface is satisfied
101
128
var _ I__iter__ = (* Range )(nil )
102
129
var _ I_iterator = (* RangeIterator )(nil )
0 commit comments