diff options
| author | Mel <einebeere@gmail.com> | 2022-05-31 01:01:32 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-31 01:02:20 +0000 |
| commit | 338744d066704e48e22d8ec56a43acb4b20da7f1 (patch) | |
| tree | b508eb6764efc64ac611b6ea063ab44d9e6b0a9c /pkg/lang/vm/exec.go | |
| parent | 78a29c41098db5e5f8291e0345a3cd443c52b329 (diff) | |
| download | jinx-338744d066704e48e22d8ec56a43acb4b20da7f1.tar.zst jinx-338744d066704e48e22d8ec56a43acb4b20da7f1.zip | |
Add untyped Objects (for now)
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(), } } |
