diff options
| author | Mel <einebeere@gmail.com> | 2022-06-01 19:51:40 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-01 19:51:40 +0000 |
| commit | edca72c160967f1918b65c91a40de89ecd8badda (patch) | |
| tree | b79feabc0889a3f6cfddf09906a486d09e5c60a1 /pkg/lang/vm/core.go | |
| parent | 33671436680e7922001df9921ee582c486c7c3f4 (diff) | |
| download | jinx-edca72c160967f1918b65c91a40de89ecd8badda.tar.zst jinx-edca72c160967f1918b65c91a40de89ecd8badda.zip | |
Implement proper object types
Diffstat (limited to 'pkg/lang/vm/core.go')
| -rw-r--r-- | pkg/lang/vm/core.go | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/pkg/lang/vm/core.go b/pkg/lang/vm/core.go index 9796a11..59dcaed 100644 --- a/pkg/lang/vm/core.go +++ b/pkg/lang/vm/core.go @@ -50,27 +50,70 @@ func (vm *VM) createCoreFunctionType() value.Type { } } +func (vm *VM) createCoreTypeRefType() value.Type { + return value.Type{ + Kind: value.TypeRefType, + Methods: map[string]value.FunctionData{ + "$add_method": makeCoreFn(vm.coreTypeRefIntrAddMethod, 2), + }, + } +} + func (vm *VM) coreArrayLength(args []value.Value) (value.Value, error) { - a, err := vm.getThis() + a, err := ensureTypeThis[value.ArrayData](vm, value.ArrayType) if err != nil { return value.Value{}, err } - switch a.Type() { - case value.ArrayType: - arr := a.Data().(value.ArrayData) - len, err := arr.Len(vm.memory) - if err != nil { - return value.Value{}, err - } - res := value.NewInt(int64(len)) - return res, nil - default: - return value.Value{}, ErrInvalidOperandType{ - Op: code.OpTempArrLen, - X: a.Type(), + len, err := a.Len(vm.memory) + if err != nil { + return value.Value{}, err + } + res := value.NewInt(int64(len)) + return res, nil +} + +func (vm *VM) coreTypeRefIntrAddMethod(args []value.Value) (value.Value, error) { + ref, err := ensureTypeThis[value.TypeRefData](vm, value.TypeRefType) + if err != nil { + return value.Value{}, err + } + + nameData, err := ensureType[value.StringData](args[0], value.StringType) + if err != nil { + return value.Value{}, err + } + name, err := nameData.RawString(vm.memory) + if err != nil { + return value.Value{}, err + } + + fn, err := ensureType[value.FunctionData](args[1], value.FunctionType) + if err != nil { + return value.Value{}, err + } + + return value.Value{}, ref.AddMethod(vm.memory, name, fn) +} + +func ensureTypeThis[D value.Data](vm *VM, t value.TypeKind) (D, error) { + this, err := vm.getThis() + if err != nil { + return *new(D), err + } + + return ensureType[D](this, t) +} + +func ensureType[D value.Data](val value.Value, t value.TypeKind) (D, error) { + if val.Type() != t { + return *new(D), ErrInvalidOperandType{ + Op: code.OpNop, // TODO: Add error not dependent on op. + X: val.Type(), } } + + return val.Data().(D), nil } func makeCoreFn(f value.NativeFunc, argCount uint) value.FunctionData { |
