diff options
Diffstat (limited to 'pkg/lang/vm/exec.go')
| -rw-r--r-- | pkg/lang/vm/exec.go | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go index 41b7019..d4426e1 100644 --- a/pkg/lang/vm/exec.go +++ b/pkg/lang/vm/exec.go @@ -47,6 +47,16 @@ func (vm *VM) execPushFunction(pc int) { vm.stack.Push(value.NewFunction(pc, 0)) } +func (vm *VM) execPushObject() error { + obj, err := value.NewObject(vm.memory, mem.NullPtr) + if err != nil { + return err + } + + vm.stack.Push(obj) + return nil +} + func (vm *VM) execGetLocal(offset int) error { local, err := vm.stack.Local(int(offset)) if err != nil { @@ -65,6 +75,28 @@ func (vm *VM) execGetMember(name string) error { return err } + if parent.Type() == value.ObjectType { + obj := parent.Data().(value.ObjectData) + ptr := obj.Ptr() + + cell, err := vm.getMemCell(ptr, mem.CellKindObject, false) + if err != nil { + return err + } + + objCell := cell.(value.ObjectCell) + member, ok := objCell.Get()[name] + if ok { + member = member.Clone(vm.memory) + } else { + member = value.NewNull() + } + + vm.stack.Push(member) + parent.Drop(vm.memory) + return nil + } + typeCell, err := vm.getMemCell(parent.TypePtr(), mem.CellKindType, false) if err != nil { return err @@ -135,6 +167,46 @@ func (vm *VM) execGetMember(name string) error { return nil } +func (vm *VM) execSetMember(name string) error { + parent, err := vm.stack.Pop() + if err != nil { + return err + } + + v, err := vm.stack.Pop() + if err != nil { + return err + } + + if parent.Type() != value.ObjectType { + return ErrInvalidOperandType{ + Op: code.OpSetMember, + X: parent.Type(), + } + } + + ptr := parent.Data().(value.ObjectData).Ptr() + + cell, err := vm.getMemCell(ptr, mem.CellKindObject, false) + if err != nil { + return err + } + + objCell := cell.(value.ObjectCell) + obj := objCell.Get() + + obj[name] = v + + if err := vm.memory.Set(ptr, value.ObjectCell{Members: obj}); err != nil { + return err + } + + parent.Drop(vm.memory) + // v was moved, no need to drop it. + + return nil +} + func (vm *VM) execGetEnv(envIndex int) error { envCell, err := vm.getMemCell(vm.stack.CurrentCallEnv(), mem.CellKindEnv, false) if err != nil { @@ -522,7 +594,7 @@ func (vm *VM) execCall(argCount uint) error { if argCount != fn.Args() { return ErrNotEnoughArguments{ - Got: argCount, + Got: argCount, Needed: fn.Args(), } } |
