Change assignment into expressions
Some checks failed
Test / build (push) Waiting to run
Build / build (push) Has been cancelled

This commit is contained in:
Chuck Smith
2024-03-19 20:30:30 -04:00
parent aa0582ed72
commit be81b9a6d6
12 changed files with 478 additions and 153 deletions

View File

@@ -186,6 +186,11 @@ func (vm *VM) Run() error {
vm.currentFrame().ip += 2
vm.globals[globalIndex] = vm.pop()
err := vm.push(Null)
if err != nil {
return err
}
case code.OpAssignLocal:
localIndex := code.ReadUint8(ins[ip+1:])
vm.currentFrame().ip += 1
@@ -193,6 +198,11 @@ func (vm *VM) Run() error {
frame := vm.currentFrame()
vm.stack[frame.basePointer+int(localIndex)] = vm.pop()
err := vm.push(Null)
if err != nil {
return err
}
case code.OpGetGlobal:
globalIndex := code.ReadUint16(ins[ip+1:])
vm.currentFrame().ip += 2
@@ -229,11 +239,21 @@ func (vm *VM) Run() error {
return err
}
case code.OpIndex:
case code.OpSetItem:
value := vm.pop()
index := vm.pop()
left := vm.pop()
err := vm.executeIndexExpressions(left, index)
err := vm.executeSetItem(left, index, value)
if err != nil {
return err
}
case code.OpGetItem:
index := vm.pop()
left := vm.pop()
err := vm.executeGetItem(left, index)
if err != nil {
return err
}
@@ -328,20 +348,39 @@ func (vm *VM) Run() error {
return nil
}
func (vm *VM) executeIndexExpressions(left, index object.Object) error {
func (vm *VM) executeSetItem(left, index, value object.Object) error {
switch {
case left.Type() == object.STRING_OBJ && index.Type() == object.INTEGER_OBJ:
return vm.executeStringIndex(left, index)
case left.Type() == object.ARRAY_OBJ && index.Type() == object.INTEGER_OBJ:
return vm.executeArrayIndex(left, index)
return vm.executeArraySetItem(left, index, value)
case left.Type() == object.HASH_OBJ:
return vm.executeHashIndex(left, index)
return vm.executeHashSetItem(left, index, value)
default:
return fmt.Errorf("index operator not supported: %s", left.Type())
return fmt.Errorf(
"set item operation not supported: left=%s index=%s",
left.Type(), index.Type(),
)
}
}
func (vm *VM) executeArrayIndex(array, index object.Object) error {
func (vm *VM) executeGetItem(left, index object.Object) error {
switch {
case left.Type() == object.STRING_OBJ && index.Type() == object.INTEGER_OBJ:
return vm.executeStringGetItem(left, index)
case left.Type() == object.STRING_OBJ && index.Type() == object.STRING_OBJ:
return vm.executeStringIndex(left, index)
case left.Type() == object.ARRAY_OBJ && index.Type() == object.INTEGER_OBJ:
return vm.executeArrayGetItem(left, index)
case left.Type() == object.HASH_OBJ:
return vm.executeHashGetItem(left, index)
default:
return fmt.Errorf(
"index operator not supported: left=%s index=%s",
left.Type(), index.Type(),
)
}
}
func (vm *VM) executeArrayGetItem(array, index object.Object) error {
arrayObject := array.(*object.Array)
i := index.(*object.Integer).Value
max := int64(len(arrayObject.Elements) - 1)
@@ -353,7 +392,20 @@ func (vm *VM) executeArrayIndex(array, index object.Object) error {
return vm.push(arrayObject.Elements[i])
}
func (vm *VM) executeHashIndex(hash, index object.Object) error {
func (vm *VM) executeArraySetItem(array, index, value object.Object) error {
arrayObject := array.(*object.Array)
i := index.(*object.Integer).Value
max := int64(len(arrayObject.Elements) - 1)
if i < 0 || i > max {
return fmt.Errorf("index out of bounds: %d", i)
}
arrayObject.Elements[i] = value
return vm.push(Null)
}
func (vm *VM) executeHashGetItem(hash, index object.Object) error {
hashObject := hash.(*object.Hash)
key, ok := index.(object.Hashable)
@@ -369,6 +421,20 @@ func (vm *VM) executeHashIndex(hash, index object.Object) error {
return vm.push(pair.Value)
}
func (vm *VM) executeHashSetItem(hash, index, value object.Object) error {
hashObject := hash.(*object.Hash)
key, ok := index.(object.Hashable)
if !ok {
return fmt.Errorf("unusable as hash key: %s", index.Type())
}
hashed := key.HashKey()
hashObject.Pairs[hashed] = object.HashPair{Key: index, Value: value}
return vm.push(Null)
}
func (vm *VM) buildHash(startIndex, endIndex int) (object.Object, error) {
hashedPairs := make(map[object.HashKey]object.HashPair)
@@ -621,7 +687,7 @@ func (vm *VM) pushClosure(constIndex, numFree int) error {
return vm.push(closure)
}
func (vm *VM) executeStringIndex(str, index object.Object) error {
func (vm *VM) executeStringGetItem(str, index object.Object) error {
stringObject := str.(*object.String)
i := index.(*object.Integer).Value
max := int64(len(stringObject.Value) - 1)
@@ -633,6 +699,17 @@ func (vm *VM) executeStringIndex(str, index object.Object) error {
return vm.push(&object.String{Value: string(stringObject.Value[i])})
}
func (vm *VM) executeStringIndex(str, index object.Object) error {
stringObject := str.(*object.String)
substr := index.(*object.String).Value
return vm.push(
&object.Integer{
Value: int64(strings.Index(stringObject.Value, substr)),
},
)
}
func (vm *VM) executeStringComparison(op code.Opcode, left, right object.Object) error {
leftValue := left.(*object.String).Value
rightValue := right.(*object.String).Value