Skip to content

Commit 14646a7

Browse files
committed
Add Slice function for range type
Crate a new range object by calculating start, stop, and step when slice is entered as argument to the __getitem__ function of the range Fixes #77
1 parent eb115a9 commit 14646a7

File tree

1 file changed

+49
-4
lines changed

1 file changed

+49
-4
lines changed

py/range.go

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,20 @@ func RangeNew(metatype *Type, args Tuple, kwargs StringDict) (Object, error) {
7979
}
8080

8181
func (r *Range) M__getitem__(key Object) (Object, error) {
82+
if slice, ok := key.(*Slice); ok {
83+
return computeRangeSlice(r, slice)
84+
}
85+
8286
index, err := Index(key)
8387
if err != nil {
8488
return nil, err
8589
}
86-
// TODO(corona10): Support slice case
87-
length := computeRangeLength(r.Start, r.Stop, r.Step)
90+
8891
if index < 0 {
89-
index += length
92+
index += r.Length
9093
}
9194

92-
if index < 0 || index >= length {
95+
if index < 0 || index >= r.Length {
9396
return nil, ExceptionNewf(TypeError, "range object index out of range")
9497
}
9598
result := computeItem(r, index)
@@ -152,6 +155,48 @@ func computeRangeLength(start, stop, step Int) Int {
152155
return res
153156
}
154157

158+
func computeRangeSlice(r *Range, s *Slice) (Object, error) {
159+
length, err := r.Length.GoInt()
160+
if err != nil {
161+
return nil, err
162+
}
163+
start, stop, step, sliceLength, err := s.GetIndices(length)
164+
if err != nil {
165+
return nil, err
166+
}
167+
168+
if step == 0 {
169+
return nil, ExceptionNewf(ValueError, "slice step cannot be zero")
170+
}
171+
if start < 0 {
172+
start += length
173+
}
174+
if stop < 0 {
175+
stop += length
176+
}
177+
if start < 0 {
178+
start = 0
179+
} else if start >= length {
180+
start = length
181+
}
182+
if stop < 0 {
183+
stop = 0
184+
} else if stop >= length {
185+
stop = length
186+
}
187+
188+
startIndex := computeItem(r, Int(start))
189+
stopIndex := computeItem(r, Int(stop))
190+
stepIndex := Int(step) * r.Step
191+
192+
return &Range{
193+
Start: startIndex,
194+
Stop: stopIndex,
195+
Step: stepIndex,
196+
Length: Int(sliceLength),
197+
}, nil
198+
}
199+
155200
// Check interface is satisfied
156201
var _ I__getitem__ = (*Range)(nil)
157202
var _ I__iter__ = (*Range)(nil)

0 commit comments

Comments
 (0)