Skip to content

Commit 107f6ef

Browse files
committed
Add support for negative indexes
1 parent bdd6f70 commit 107f6ef

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

expr_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,10 @@ func TestExpr(t *testing.T) {
876876
`Array[0] + Array[1]`,
877877
3,
878878
},
879+
{
880+
`Array[-1]`,
881+
5,
882+
},
879883
{
880884
`Array[1:2]`,
881885
[]int{2},
@@ -884,6 +888,10 @@ func TestExpr(t *testing.T) {
884888
`Array[1:4]`,
885889
[]int{2, 3, 4},
886890
},
891+
{
892+
`Array[-4:-1]`,
893+
[]int{2, 3, 4},
894+
},
887895
{
888896
`Array[:3]`,
889897
[]int{1, 2, 3},

vm/runtime/runtime.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,15 @@ func Fetch(from, i interface{}) interface{} {
3232
kind = v.Kind()
3333
}
3434

35+
// TODO: We can create separate opcodes for each of the cases below to make
36+
// the little bit faster.
3537
switch kind {
36-
3738
case reflect.Array, reflect.Slice, reflect.String:
38-
value := v.Index(ToInt(i))
39+
index := ToInt(i)
40+
if index < 0 {
41+
index = v.Len() + index
42+
}
43+
value := v.Index(index)
3944
if value.IsValid() {
4045
return value.Interface()
4146
}
@@ -168,14 +173,18 @@ func Slice(array, from, to interface{}) interface{} {
168173
case reflect.Array, reflect.Slice, reflect.String:
169174
length := v.Len()
170175
a, b := ToInt(from), ToInt(to)
171-
176+
if a < 0 {
177+
a = length + a
178+
}
179+
if b < 0 {
180+
b = length + b
181+
}
172182
if b > length {
173183
b = length
174184
}
175185
if a > b {
176186
a = b
177187
}
178-
179188
value := v.Slice(a, b)
180189
if value.IsValid() {
181190
return value.Interface()

0 commit comments

Comments
 (0)