indexes
Some checks failed
Build / build (push) Failing after 5m57s
Test / build (push) Failing after 5m41s

This commit is contained in:
Chuck Smith
2024-02-27 16:45:22 -05:00
parent 0a1201f1bc
commit 4185926e3e
5 changed files with 116 additions and 0 deletions

View File

@@ -160,12 +160,60 @@ func (vm *VM) Run() error {
return err
}
case code.OpIndex:
index := vm.pop()
left := vm.pop()
err := vm.executeIndexExpressions(left, index)
if err != nil {
return err
}
}
}
return nil
}
func (vm *VM) executeIndexExpressions(left, index object.Object) error {
switch {
case left.Type() == object.ARRAY_OBJ && index.Type() == object.INTEGER_OBJ:
return vm.executeArrayIndex(left, index)
case left.Type() == object.HASH_OBJ:
return vm.executeHashIndex(left, index)
default:
return fmt.Errorf("index operator not supported: %s", left.Type())
}
}
func (vm *VM) executeArrayIndex(array, index object.Object) error {
arrayObject := array.(*object.Array)
i := index.(*object.Integer).Value
max := int64(len(arrayObject.Elements) - 1)
if i < 0 || i > max {
return vm.push(Null)
}
return vm.push(arrayObject.Elements[i])
}
func (vm *VM) executeHashIndex(hash, index object.Object) error {
hashObject := hash.(*object.Hash)
key, ok := index.(object.Hashable)
if !ok {
return fmt.Errorf("unusable as hash key: %s", index.Type())
}
pair, ok := hashObject.Pairs[key.HashKey()]
if !ok {
return vm.push(Null)
}
return vm.push(pair.Value)
}
func (vm *VM) buildHash(startIndex, endIndex int) (object.Object, error) {
hashedPairs := make(map[object.HashKey]object.HashPair)

View File

@@ -279,3 +279,20 @@ func TestHashLiterals(t *testing.T) {
runVmTests(t, tests)
}
func TestIndexExpressions(t *testing.T) {
tests := []vmTestCase{
{"[1, 2, 3][1]", 2},
{"[1, 2, 3][0 + 2]", 3},
{"[[1, 1, 1]][0][0]", 1},
{"[][0]", Null},
{"[1, 2, 3][99]", Null},
{"[1][-1]", Null},
{"{1: 1, 2: 2}[1]", 1},
{"{1: 1, 2: 2}[2]", 2},
{"{1: 1}[0]", Null},
{"{}[0]", Null},
}
runVmTests(t, tests)
}