string like array access
This commit is contained in:
@@ -376,6 +376,8 @@ func unwrapReturnValue(obj object.Object) object.Object {
|
||||
|
||||
func evalIndexExpression(left, index object.Object) object.Object {
|
||||
switch {
|
||||
case left.Type() == object.STRING_OBJ && index.Type() == object.INTEGER_OBJ:
|
||||
return evalStringIndexExpression(left, index)
|
||||
case left.Type() == object.ARRAY_OBJ && index.Type() == object.INTEGER_OBJ:
|
||||
return evalArrayIndexExpression(left, index)
|
||||
case left.Type() == object.HASH_OBJ:
|
||||
@@ -385,6 +387,18 @@ func evalIndexExpression(left, index object.Object) object.Object {
|
||||
}
|
||||
}
|
||||
|
||||
func evalStringIndexExpression(str, index object.Object) object.Object {
|
||||
stringObject := str.(*object.String)
|
||||
idx := index.(*object.Integer).Value
|
||||
max := int64((len(stringObject.Value)) - 1)
|
||||
|
||||
if idx < 0 || idx > max {
|
||||
return &object.String{Value: ""}
|
||||
}
|
||||
|
||||
return &object.String{Value: string(stringObject.Value[idx])}
|
||||
}
|
||||
|
||||
func evalHashIndexExpression(hash, index object.Object) object.Object {
|
||||
hashObject := hash.(*object.Hash)
|
||||
|
||||
|
||||
@@ -647,3 +647,53 @@ func TestExamples(t *testing.T) {
|
||||
testEval(string(b))
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringIndexExpressions(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected interface{}
|
||||
}{
|
||||
{
|
||||
`"abc"[0]`,
|
||||
"a",
|
||||
},
|
||||
{
|
||||
`"abc"[1]`,
|
||||
"b",
|
||||
},
|
||||
{
|
||||
`"abc"[2]`,
|
||||
"c",
|
||||
},
|
||||
{
|
||||
`let i = 0; "abc"[i];`,
|
||||
"a",
|
||||
},
|
||||
{
|
||||
`"abc"[1 + 1];`,
|
||||
"c",
|
||||
},
|
||||
{
|
||||
`let myString = "abc"; myString[0] + myString[1] + myString[2];`,
|
||||
"abc",
|
||||
},
|
||||
{
|
||||
`"abc"[3]`,
|
||||
"",
|
||||
},
|
||||
{
|
||||
`"foo"[-1]`,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
evaluated := testEval(tt.input)
|
||||
str, ok := tt.expected.(string)
|
||||
if ok {
|
||||
testStringObject(t, evaluated, string(str))
|
||||
} else {
|
||||
testNullObject(t, evaluated)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user