diff --git a/internal/builtins/abs.go b/internal/builtins/abs.go index 586155c..fc0ab7f 100644 --- a/internal/builtins/abs.go +++ b/internal/builtins/abs.go @@ -15,10 +15,10 @@ func Abs(args ...object.Object) object.Object { return newError(err.Error()) } - i := args[0].(*object.Integer) + i := args[0].(object.Integer) value := i.Value if value < 0 { value = value * -1 } - return &object.Integer{Value: value} + return object.Integer{Value: value} } diff --git a/internal/builtins/accept.go b/internal/builtins/accept.go index 9ee1c43..ea9f906 100644 --- a/internal/builtins/accept.go +++ b/internal/builtins/accept.go @@ -21,12 +21,12 @@ func Accept(args ...object.Object) object.Object { err error ) - fd := int(args[0].(*object.Integer).Value) + fd := int(args[0].(object.Integer).Value) nfd, _, err = syscall.Accept(fd) if err != nil { return newError("SocketError: %s", err) } - return &object.Integer{Value: int64(nfd)} + return object.Integer{Value: int64(nfd)} } diff --git a/internal/builtins/args.go b/internal/builtins/args.go index c91b28e..65d6c4a 100644 --- a/internal/builtins/args.go +++ b/internal/builtins/args.go @@ -16,7 +16,7 @@ func args(args ...object.Object) object.Object { elements := make([]object.Object, len(object.Args)) for i, arg := range object.Args { - elements[i] = &object.String{Value: arg} + elements[i] = object.String{Value: arg} } return &object.Array{Elements: elements} } diff --git a/internal/builtins/assert.go b/internal/builtins/assert.go index 6d69d9a..b11b7fa 100644 --- a/internal/builtins/assert.go +++ b/internal/builtins/assert.go @@ -17,8 +17,8 @@ func Assert(args ...object.Object) object.Object { return newError(err.Error()) } - if !args[0].(*object.Boolean).Value { - fmt.Printf("Assertion Error: %s", args[1].(*object.String).Value) + if !args[0].(object.Boolean).Value { + fmt.Printf("Assertion Error: %s", args[1].(object.String).Value) os.Exit(1) } diff --git a/internal/builtins/bin.go b/internal/builtins/bin.go index 1b6795e..1357773 100644 --- a/internal/builtins/bin.go +++ b/internal/builtins/bin.go @@ -17,6 +17,6 @@ func Bin(args ...object.Object) object.Object { return newError(err.Error()) } - i := args[0].(*object.Integer) - return &object.String{Value: fmt.Sprintf("0b%s", strconv.FormatInt(i.Value, 2))} + i := args[0].(object.Integer) + return object.String{Value: fmt.Sprintf("0b%s", strconv.FormatInt(i.Value, 2))} } diff --git a/internal/builtins/bind.go b/internal/builtins/bind.go index 4365ad4..90483c5 100644 --- a/internal/builtins/bind.go +++ b/internal/builtins/bind.go @@ -21,8 +21,8 @@ func Bind(args ...object.Object) object.Object { sockaddr syscall.Sockaddr ) - fd := int(args[0].(*object.Integer).Value) - address := args[1].(*object.String).Value + fd := int(args[0].(object.Integer).Value) + address := args[1].(object.String).Value sockaddr, err = syscall.Getsockname(fd) if err != nil { @@ -50,5 +50,5 @@ func Bind(args ...object.Object) object.Object { return newError("SocketError: %s", err) } - return &object.Null{} + return object.Null{} } diff --git a/internal/builtins/bool.go b/internal/builtins/bool.go index 0c361d9..13f8136 100644 --- a/internal/builtins/bool.go +++ b/internal/builtins/bool.go @@ -14,5 +14,5 @@ func Bool(args ...object.Object) object.Object { return newError(err.Error()) } - return &object.Boolean{Value: args[0].Bool()} + return object.Boolean{Value: args[0].Bool()} } diff --git a/internal/builtins/builtins.go b/internal/builtins/builtins.go index b46a891..26e5d27 100644 --- a/internal/builtins/builtins.go +++ b/internal/builtins/builtins.go @@ -72,6 +72,6 @@ func init() { } } -func newError(format string, a ...interface{}) *object.Error { - return &object.Error{Message: fmt.Sprintf(format, a...)} +func newError(format string, a ...interface{}) object.Error { + return object.Error{Message: fmt.Sprintf(format, a...)} } diff --git a/internal/builtins/chr.go b/internal/builtins/chr.go index 9df165c..f8cbb69 100644 --- a/internal/builtins/chr.go +++ b/internal/builtins/chr.go @@ -16,6 +16,6 @@ func Chr(args ...object.Object) object.Object { return newError(err.Error()) } - i := args[0].(*object.Integer) - return &object.String{Value: fmt.Sprintf("%c", rune(i.Value))} + i := args[0].(object.Integer) + return object.String{Value: fmt.Sprintf("%c", rune(i.Value))} } diff --git a/internal/builtins/close.go b/internal/builtins/close.go index 1cc63bb..6f72b44 100644 --- a/internal/builtins/close.go +++ b/internal/builtins/close.go @@ -16,12 +16,12 @@ func Close(args ...object.Object) object.Object { return newError(err.Error()) } - fd := int(args[0].(*object.Integer).Value) + fd := int(args[0].(object.Integer).Value) err := syscall.Close(fd) if err != nil { return newError("IOError: %s", err) } - return &object.Null{} + return object.Null{} } diff --git a/internal/builtins/connect.go b/internal/builtins/connect.go index 38161b1..c5e2eee 100644 --- a/internal/builtins/connect.go +++ b/internal/builtins/connect.go @@ -18,8 +18,8 @@ func Connect(args ...object.Object) object.Object { var sa syscall.Sockaddr - fd := int(args[0].(*object.Integer).Value) - address := args[1].(*object.String).Value + fd := int(args[0].(object.Integer).Value) + address := args[1].(object.String).Value sockaddr, err := syscall.Getsockname(fd) if err != nil { @@ -46,5 +46,5 @@ func Connect(args ...object.Object) object.Object { return newError("SocketError: %s", err) } - return &object.Null{} + return object.Null{} } diff --git a/internal/builtins/divmod.go b/internal/builtins/divmod.go index a23ecbf..cd21a24 100644 --- a/internal/builtins/divmod.go +++ b/internal/builtins/divmod.go @@ -15,10 +15,10 @@ func Divmod(args ...object.Object) object.Object { return newError(err.Error()) } - a := args[0].(*object.Integer) - b := args[1].(*object.Integer) + a := args[0].(object.Integer) + b := args[1].(object.Integer) elements := make([]object.Object, 2) - elements[0] = &object.Integer{Value: a.Value / b.Value} - elements[1] = &object.Integer{Value: a.Value % b.Value} + elements[0] = object.Integer{Value: a.Value / b.Value} + elements[1] = object.Integer{Value: a.Value % b.Value} return &object.Array{Elements: elements} } diff --git a/internal/builtins/exit.go b/internal/builtins/exit.go index 3f7b9d1..f440507 100644 --- a/internal/builtins/exit.go +++ b/internal/builtins/exit.go @@ -17,7 +17,7 @@ func Exit(args ...object.Object) object.Object { var status int if len(args) == 1 { - status = int(args[0].(*object.Integer).Value) + status = int(args[0].(object.Integer).Value) } object.ExitFunction(status) diff --git a/internal/builtins/ffi.go b/internal/builtins/ffi.go index a43c8bc..d18a552 100644 --- a/internal/builtins/ffi.go +++ b/internal/builtins/ffi.go @@ -20,8 +20,8 @@ func FFI(args ...object.Object) object.Object { return newError(err.Error()) } - name := args[0].(*object.String).Value - symbol := args[1].(*object.String).Value + name := args[0].(object.String).Value + symbol := args[1].(object.String).Value p, err := plugin.Open(fmt.Sprintf("%s.so", name)) if err != nil { diff --git a/internal/builtins/find.go b/internal/builtins/find.go index 99a3a1b..49057b7 100644 --- a/internal/builtins/find.go +++ b/internal/builtins/find.go @@ -20,7 +20,7 @@ func Find(args ...object.Object) object.Object { } // find substring in string - if haystack, ok := args[0].(*object.String); ok { + if haystack, ok := args[0].(object.String); ok { if err := typing.Check( "find", args, typing.WithTypes(object.StringType, object.StringType), @@ -28,9 +28,9 @@ func Find(args ...object.Object) object.Object { return newError(err.Error()) } - needle := args[1].(*object.String) + needle := args[1].(object.String) index := strings.Index(haystack.Value, needle.Value) - return &object.Integer{Value: int64(index)} + return object.Integer{Value: int64(index)} } // find in array @@ -40,9 +40,9 @@ func Find(args ...object.Object) object.Object { return needle.Compare(haystack.Elements[i]) == 0 }) if i < len(haystack.Elements) && needle.Compare(haystack.Elements[i]) == 0 { - return &object.Integer{Value: int64(i)} + return object.Integer{Value: int64(i)} } - return &object.Integer{Value: -1} + return object.Integer{Value: -1} } return newError( diff --git a/internal/builtins/hash.go b/internal/builtins/hash.go index 85cf451..072be42 100644 --- a/internal/builtins/hash.go +++ b/internal/builtins/hash.go @@ -15,7 +15,7 @@ func HashOf(args ...object.Object) object.Object { } if hash, ok := args[0].(object.Hashable); ok { - return &object.Integer{Value: int64(hash.HashKey().Value)} + return object.Integer{Value: int64(hash.HashKey().Value)} } return newError("TypeError: hash() expected argument #1 to be hashable") diff --git a/internal/builtins/hex.go b/internal/builtins/hex.go index a2d48a2..7c1c3e6 100644 --- a/internal/builtins/hex.go +++ b/internal/builtins/hex.go @@ -17,6 +17,6 @@ func Hex(args ...object.Object) object.Object { return newError(err.Error()) } - i := args[0].(*object.Integer) - return &object.String{Value: fmt.Sprintf("0x%s", strconv.FormatInt(i.Value, 16))} + i := args[0].(object.Integer) + return object.String{Value: fmt.Sprintf("0x%s", strconv.FormatInt(i.Value, 16))} } diff --git a/internal/builtins/id.go b/internal/builtins/id.go index ab41d0b..5df86e8 100644 --- a/internal/builtins/id.go +++ b/internal/builtins/id.go @@ -17,25 +17,24 @@ func IdOf(args ...object.Object) object.Object { arg := args[0] - if n, ok := arg.(*object.Null); ok { - return &object.String{Value: fmt.Sprintf("%p", n)} - } else if b, ok := arg.(*object.Boolean); ok { - return &object.String{Value: fmt.Sprintf("%p", b)} - } else if i, ok := arg.(*object.Integer); ok { - return &object.String{Value: fmt.Sprintf("%p", i)} - } else if s, ok := arg.(*object.String); ok { - return &object.String{Value: fmt.Sprintf("%p", s)} + if n, ok := arg.(object.Null); ok { + return object.String{Value: fmt.Sprintf("%p", &n)} + } else if b, ok := arg.(object.Boolean); ok { + return object.String{Value: fmt.Sprintf("%p", &b)} + } else if i, ok := arg.(object.Integer); ok { + return object.String{Value: fmt.Sprintf("%p", &i)} + } else if s, ok := arg.(object.String); ok { + return object.String{Value: fmt.Sprintf("%p", &s)} } else if a, ok := arg.(*object.Array); ok { - return &object.String{Value: fmt.Sprintf("%p", a)} + return object.String{Value: fmt.Sprintf("%p", a)} } else if h, ok := arg.(*object.Hash); ok { - return &object.String{Value: fmt.Sprintf("%p", h)} + return object.String{Value: fmt.Sprintf("%p", h)} } else if f, ok := arg.(*object.Function); ok { - return &object.String{Value: fmt.Sprintf("%p", f)} + return object.String{Value: fmt.Sprintf("%p", f)} } else if c, ok := arg.(*object.Closure); ok { - return &object.String{Value: fmt.Sprintf("%p", c)} + return object.String{Value: fmt.Sprintf("%p", c)} } else if b, ok := arg.(*object.Builtin); ok { - return &object.String{Value: fmt.Sprintf("%p", b)} + return object.String{Value: fmt.Sprintf("%p", b)} } - return nil } diff --git a/internal/builtins/input.go b/internal/builtins/input.go index b8b8c58..82ff13b 100644 --- a/internal/builtins/input.go +++ b/internal/builtins/input.go @@ -20,7 +20,7 @@ func Input(args ...object.Object) object.Object { } if len(args) == 1 { - prompt := args[0].(*object.String).Value + prompt := args[0].(object.String).Value fmt.Fprintf(os.Stdout, prompt) } @@ -30,5 +30,5 @@ func Input(args ...object.Object) object.Object { if err != nil && err != io.EOF { return newError(fmt.Sprintf("error reading input from stdin: %s", err)) } - return &object.String{Value: string(line)} + return object.String{Value: string(line)} } diff --git a/internal/builtins/int.go b/internal/builtins/int.go index b77be9a..a9179cc 100644 --- a/internal/builtins/int.go +++ b/internal/builtins/int.go @@ -16,20 +16,20 @@ func Int(args ...object.Object) object.Object { } switch arg := args[0].(type) { - case *object.Boolean: + case object.Boolean: if arg.Value { - return &object.Integer{Value: 1} + return object.Integer{Value: 1} } - return &object.Integer{Value: 0} - case *object.Integer: + return object.Integer{Value: 0} + case object.Integer: return arg - case *object.String: + case object.String: n, err := strconv.ParseInt(arg.Value, 10, 64) if err != nil { return newError("could not parse string to int: %s", err) } - return &object.Integer{Value: n} + return object.Integer{Value: n} default: - return &object.Integer{} + return object.Integer{} } } diff --git a/internal/builtins/join.go b/internal/builtins/join.go index d7f698b..eabf90d 100644 --- a/internal/builtins/join.go +++ b/internal/builtins/join.go @@ -17,10 +17,10 @@ func Join(args ...object.Object) object.Object { } arr := args[0].(*object.Array) - sep := args[1].(*object.String) + sep := args[1].(object.String) a := make([]string, len(arr.Elements)) for i, el := range arr.Elements { a[i] = el.String() } - return &object.String{Value: strings.Join(a, sep.Value)} + return object.String{Value: strings.Join(a, sep.Value)} } diff --git a/internal/builtins/len.go b/internal/builtins/len.go index a73fd15..65fd41a 100644 --- a/internal/builtins/len.go +++ b/internal/builtins/len.go @@ -15,7 +15,7 @@ func Len(args ...object.Object) object.Object { } if size, ok := args[0].(object.Sizeable); ok { - return &object.Integer{Value: int64(size.Len())} + return object.Integer{Value: int64(size.Len())} } return newError("TypeError: object of type '%s' has no len()", args[0].Type()) } diff --git a/internal/builtins/listen.go b/internal/builtins/listen.go index 6430380..a322dad 100644 --- a/internal/builtins/listen.go +++ b/internal/builtins/listen.go @@ -16,12 +16,12 @@ func Listen(args ...object.Object) object.Object { return newError(err.Error()) } - fd := int(args[0].(*object.Integer).Value) - backlog := int(args[1].(*object.Integer).Value) + fd := int(args[0].(object.Integer).Value) + backlog := int(args[1].(object.Integer).Value) if err := syscall.Listen(fd, backlog); err != nil { return newError("SocketError: %s", err) } - return &object.Null{} + return object.Null{} } diff --git a/internal/builtins/lower.go b/internal/builtins/lower.go index 808910c..9362b8a 100644 --- a/internal/builtins/lower.go +++ b/internal/builtins/lower.go @@ -16,6 +16,6 @@ func Lower(args ...object.Object) object.Object { return newError(err.Error()) } - str := args[0].(*object.String) - return &object.String{Value: strings.ToLower(str.Value)} + str := args[0].(object.String) + return object.String{Value: strings.ToLower(str.Value)} } diff --git a/internal/builtins/max.go b/internal/builtins/max.go index 6c3f3e3..0dac2f0 100644 --- a/internal/builtins/max.go +++ b/internal/builtins/max.go @@ -20,12 +20,12 @@ func Max(args ...object.Object) object.Object { // TODO: Make this more generic xs := []int{} //make([]int, len(a.Elements)) for n, e := range a.Elements { - if i, ok := e.(*object.Integer); ok { + if i, ok := e.(object.Integer); ok { xs = append(xs, int(i.Value)) } else { return newError("item #%d not an `int` got=%d", n, e.Type()) } } sort.Ints(xs) - return &object.Integer{Value: int64(xs[len(xs)-1])} + return object.Integer{Value: int64(xs[len(xs)-1])} } diff --git a/internal/builtins/min.go b/internal/builtins/min.go index ceeb999..4f4a279 100644 --- a/internal/builtins/min.go +++ b/internal/builtins/min.go @@ -20,12 +20,12 @@ func Min(args ...object.Object) object.Object { // TODO: Make this more generic xs := []int{} //make([]int, len(a.Elements)) for n, e := range a.Elements { - if i, ok := e.(*object.Integer); ok { + if i, ok := e.(object.Integer); ok { xs = append(xs, int(i.Value)) } else { return newError("item #%d not an `int` got=%d", n, e.Type()) } } sort.Ints(xs) - return &object.Integer{Value: int64(xs[0])} + return object.Integer{Value: int64(xs[0])} } diff --git a/internal/builtins/oct.go b/internal/builtins/oct.go index 4cd5151..2e82f74 100644 --- a/internal/builtins/oct.go +++ b/internal/builtins/oct.go @@ -17,6 +17,6 @@ func Oct(args ...object.Object) object.Object { return newError(err.Error()) } - i := args[0].(*object.Integer) - return &object.String{Value: fmt.Sprintf("0%s", strconv.FormatInt(i.Value, 8))} + i := args[0].(object.Integer) + return object.String{Value: fmt.Sprintf("0%s", strconv.FormatInt(i.Value, 8))} } diff --git a/internal/builtins/open.go b/internal/builtins/open.go index c240b5e..933bd3b 100644 --- a/internal/builtins/open.go +++ b/internal/builtins/open.go @@ -66,10 +66,10 @@ func Open(args ...object.Object) object.Object { perm uint32 = 0640 ) - filename = args[0].(*object.String).Value + filename = args[0].(object.String).Value if len(args) == 2 { - mode = args[1].(*object.String).Value + mode = args[1].(object.String).Value } flag, err := parseMode(mode) @@ -82,5 +82,5 @@ func Open(args ...object.Object) object.Object { return newError("IOError: %s", err) } - return &object.Integer{Value: int64(fd)} + return object.Integer{Value: int64(fd)} } diff --git a/internal/builtins/ord.go b/internal/builtins/ord.go index 151e22d..1497523 100644 --- a/internal/builtins/ord.go +++ b/internal/builtins/ord.go @@ -15,9 +15,9 @@ func Ord(args ...object.Object) object.Object { return newError(err.Error()) } - s := args[0].(*object.String) + s := args[0].(object.String) if len(s.Value) == 1 { - return &object.Integer{Value: int64(s.Value[0])} + return object.Integer{Value: int64(s.Value[0])} } return newError( "TypeError: ord() expected a single character `str` got=%s", diff --git a/internal/builtins/pow.go b/internal/builtins/pow.go index a6d8a85..cf7d859 100644 --- a/internal/builtins/pow.go +++ b/internal/builtins/pow.go @@ -27,8 +27,8 @@ func Pow(args ...object.Object) object.Object { return newError(err.Error()) } - x := args[0].(*object.Integer) - y := args[1].(*object.Integer) + x := args[0].(object.Integer) + y := args[1].(object.Integer) value := pow(x.Value, y.Value) - return &object.Integer{Value: value} + return object.Integer{Value: value} } diff --git a/internal/builtins/read.go b/internal/builtins/read.go index c119379..d11ec16 100644 --- a/internal/builtins/read.go +++ b/internal/builtins/read.go @@ -24,10 +24,10 @@ func Read(args ...object.Object) object.Object { n = DefaultBufferSize ) - fd = int(args[0].(*object.Integer).Value) + fd = int(args[0].(object.Integer).Value) if len(args) == 2 { - n = int(args[1].(*object.Integer).Value) + n = int(args[1].(object.Integer).Value) } buf := make([]byte, n) @@ -36,5 +36,5 @@ func Read(args ...object.Object) object.Object { return newError("IOError: %s", err) } - return &object.String{Value: string(buf[:n])} + return object.String{Value: string(buf[:n])} } diff --git a/internal/builtins/readfile.go b/internal/builtins/readfile.go index 988a106..c127de1 100644 --- a/internal/builtins/readfile.go +++ b/internal/builtins/readfile.go @@ -16,11 +16,11 @@ func ReadFile(args ...object.Object) object.Object { return newError(err.Error()) } - filename := args[0].(*object.String).Value + filename := args[0].(object.String).Value data, err := os.ReadFile(filename) if err != nil { return newError("IOError: error reading from file %s: %s", filename, err) } - return &object.String{Value: string(data)} + return object.String{Value: string(data)} } diff --git a/internal/builtins/seek.go b/internal/builtins/seek.go index 761a7e9..8fd27a3 100644 --- a/internal/builtins/seek.go +++ b/internal/builtins/seek.go @@ -21,11 +21,11 @@ func Seek(args ...object.Object) object.Object { whence = 0 ) - fd = int(args[0].(*object.Integer).Value) - offset := args[1].(*object.Integer).Value + fd = int(args[0].(object.Integer).Value) + offset := args[1].(object.Integer).Value if len(args) == 3 { - whence = int(args[2].(*object.Integer).Value) + whence = int(args[2].(object.Integer).Value) } offset, err := syscall.Seek(fd, offset, whence) @@ -33,5 +33,5 @@ func Seek(args ...object.Object) object.Object { return newError("IOError: %s", err) } - return &object.Integer{Value: offset} + return object.Integer{Value: offset} } diff --git a/internal/builtins/socket.go b/internal/builtins/socket.go index 85f9242..fb21399 100644 --- a/internal/builtins/socket.go +++ b/internal/builtins/socket.go @@ -23,7 +23,7 @@ func Socket(args ...object.Object) object.Object { proto int ) - arg := args[0].(*object.String).Value + arg := args[0].(object.String).Value switch strings.ToLower(arg) { case "unix": @@ -61,5 +61,5 @@ func Socket(args ...object.Object) object.Object { } } - return &object.Integer{Value: int64(fd)} + return object.Integer{Value: int64(fd)} } diff --git a/internal/builtins/split.go b/internal/builtins/split.go index f98973f..989fab7 100644 --- a/internal/builtins/split.go +++ b/internal/builtins/split.go @@ -17,16 +17,16 @@ func Split(args ...object.Object) object.Object { } var sep string - s := args[0].(*object.String).Value + s := args[0].(object.String).Value if len(args) == 2 { - sep = args[1].(*object.String).Value + sep = args[1].(object.String).Value } tokens := strings.Split(s, sep) elements := make([]object.Object, len(tokens)) for i, token := range tokens { - elements[i] = &object.String{Value: token} + elements[i] = object.String{Value: token} } return &object.Array{Elements: elements} } diff --git a/internal/builtins/str.go b/internal/builtins/str.go index 01e74dd..b45447c 100644 --- a/internal/builtins/str.go +++ b/internal/builtins/str.go @@ -14,5 +14,5 @@ func Str(args ...object.Object) object.Object { return newError(err.Error()) } - return &object.String{Value: args[0].String()} + return object.String{Value: args[0].String()} } diff --git a/internal/builtins/typeof.go b/internal/builtins/typeof.go index be7c7c6..95b5ef1 100644 --- a/internal/builtins/typeof.go +++ b/internal/builtins/typeof.go @@ -14,5 +14,5 @@ func TypeOf(args ...object.Object) object.Object { return newError(err.Error()) } - return &object.String{Value: args[0].Type().String()} + return object.String{Value: args[0].Type().String()} } diff --git a/internal/builtins/upper.go b/internal/builtins/upper.go index 5e82a54..c8702ea 100644 --- a/internal/builtins/upper.go +++ b/internal/builtins/upper.go @@ -16,5 +16,5 @@ func Upper(args ...object.Object) object.Object { return newError(err.Error()) } - return &object.String{Value: strings.ToUpper(args[0].(*object.String).Value)} + return object.String{Value: strings.ToUpper(args[0].(object.String).Value)} } diff --git a/internal/builtins/write.go b/internal/builtins/write.go index c5bbe50..6b801f4 100644 --- a/internal/builtins/write.go +++ b/internal/builtins/write.go @@ -16,13 +16,13 @@ func Write(args ...object.Object) object.Object { return newError(err.Error()) } - fd := int(args[0].(*object.Integer).Value) - data := []byte(args[1].(*object.String).Value) + fd := int(args[0].(object.Integer).Value) + data := []byte(args[1].(object.String).Value) n, err := syscall.Write(fd, data) if err != nil { return newError("IOError: %s", err) } - return &object.Integer{Value: int64(n)} + return object.Integer{Value: int64(n)} } diff --git a/internal/builtins/writefile.go b/internal/builtins/writefile.go index a185687..8fd385b 100644 --- a/internal/builtins/writefile.go +++ b/internal/builtins/writefile.go @@ -16,13 +16,13 @@ func WriteFile(args ...object.Object) object.Object { return newError(err.Error()) } - filename := args[0].(*object.String).Value - data := []byte(args[1].(*object.String).Value) + filename := args[0].(object.String).Value + data := []byte(args[1].(object.String).Value) err := os.WriteFile(filename, data, 0755) if err != nil { return newError("IOError: error writing file %s: %s", filename, err) } - return &object.Null{} + return object.Null{} } diff --git a/internal/compiler/bytecode.go b/internal/compiler/bytecode.go index 19c336a..1123dbb 100644 --- a/internal/compiler/bytecode.go +++ b/internal/compiler/bytecode.go @@ -70,13 +70,13 @@ func (e *encoder) WriteObjects(objs ...object.Object) (err error) { err = errors.Join(err, e.WriteValue(obj.Type())) switch o := obj.(type) { - case *object.Null: + case object.Null: break - case *object.Boolean: + case object.Boolean: err = errors.Join(err, e.WriteValue(o.Value)) - case *object.Integer: + case object.Integer: err = errors.Join(err, e.WriteValue(o.Value)) - case *object.String: + case object.String: err = errors.Join(err, e.WriteValue(len(o.Value))) err = errors.Join(err, e.WriteValue(o.Value)) case *object.CompiledFunction: @@ -146,13 +146,13 @@ func (d *decoder) Objects(len int) (o []object.Object) { for i := 0; i < len; i++ { switch t := object.Type(d.Int()); t { case object.NullType: - o = append(o, &object.Null{}) + o = append(o, object.Null{}) case object.BooleanType: - o = append(o, &object.Boolean{Value: d.Byte() == 1}) + o = append(o, object.Boolean{Value: d.Byte() == 1}) case object.IntegerType: - o = append(o, &object.Integer{Value: d.Int64()}) + o = append(o, object.Integer{Value: d.Int64()}) case object.StringType: - o = append(o, &object.String{Value: d.String(d.Int())}) + o = append(o, object.String{Value: d.String(d.Int())}) case object.CFunctionType: // The order of the fields has to reflect the data layout in the encoded bytecode. o = append(o, &object.CompiledFunction{ diff --git a/internal/compiler/compiler.go b/internal/compiler/compiler.go index 17a2cdb..776641c 100644 --- a/internal/compiler/compiler.go +++ b/internal/compiler/compiler.go @@ -173,7 +173,7 @@ func (c *Compiler) Compile(node ast.Node) error { } case *ast.IntegerLiteral: - integer := &object.Integer{Value: node.Value} + integer := object.Integer{Value: node.Value} c.emit(code.OpConstant, c.addConstant(integer)) case *ast.Null: @@ -356,7 +356,7 @@ func (c *Compiler) Compile(node ast.Node) error { c.loadSymbol(symbol) case *ast.StringLiteral: - str := &object.String{Value: node.Value} + str := object.String{Value: node.Value} c.emit(code.OpConstant, c.addConstant(str)) case *ast.ArrayLiteral: diff --git a/internal/compiler/compiler_test.go b/internal/compiler/compiler_test.go index 9dc4356..c4a48a3 100644 --- a/internal/compiler/compiler_test.go +++ b/internal/compiler/compiler_test.go @@ -1220,16 +1220,16 @@ func testConstants2(t *testing.T, expected []interface{}, actual []object.Object ) case string: - assert.Equal(constant, actual[i].(*object.String).Value) + assert.Equal(constant, actual[i].(object.String).Value) case int: - assert.Equal(int64(constant), actual[i].(*object.Integer).Value) + assert.Equal(int64(constant), actual[i].(object.Integer).Value) } } } func testIntegerObject(expected int64, actual object.Object) interface{} { - result, ok := actual.(*object.Integer) + result, ok := actual.(object.Integer) if !ok { return fmt.Errorf("object is not Integer. got=%T (%+v", actual, actual) } @@ -1242,7 +1242,7 @@ func testIntegerObject(expected int64, actual object.Object) interface{} { } func testStringObject(expected string, actual object.Object) error { - result, ok := actual.(*object.String) + result, ok := actual.(object.String) if !ok { return fmt.Errorf("object is not String. got %T (%+v", actual, actual) } diff --git a/internal/evaluator/evaluator.go b/internal/evaluator/evaluator.go index 54fbc4a..ba4937e 100644 --- a/internal/evaluator/evaluator.go +++ b/internal/evaluator/evaluator.go @@ -13,9 +13,9 @@ import ( ) var ( - NULL = &object.Null{} - TRUE = &object.Boolean{Value: true} - FALSE = &object.Boolean{Value: false} + NULL = object.Null{} + TRUE = object.Boolean{Value: true} + FALSE = object.Boolean{Value: false} ) func isError(obj object.Object) bool { @@ -52,7 +52,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object { if isError(val) { return val } - return &object.ReturnValue{Value: val} + return object.ReturnValue{Value: val} case *ast.BindExpression: value := Eval(node.Value, env) @@ -95,7 +95,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object { if isError(index) { return index } - if idx, ok := index.(*object.Integer); ok { + if idx, ok := index.(object.Integer); ok { array.Elements[idx.Value] = value } else { return newError("cannot index array with %#v", index) @@ -130,7 +130,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object { // Expressions case *ast.IntegerLiteral: - return &object.Integer{Value: node.Value} + return object.Integer{Value: node.Value} case *ast.Boolean: return nativeBoolToBooleanObject(node.Value) @@ -169,7 +169,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object { return applyFunction(function, args) case *ast.StringLiteral: - return &object.String{Value: node.Value} + return object.String{Value: node.Value} case *ast.ArrayLiteral: elements := evalExpressions(node.Elements, env) @@ -203,12 +203,12 @@ func evalImportExpression(ie *ast.ImportExpression, env *object.Environment) obj return name } - if s, ok := name.(*object.String); ok { + if s, ok := name.(object.String); ok { attrs := EvalModule(s.Value) if isError(attrs) { return attrs } - return &object.Module{Name: s.Value, Attrs: attrs} + return object.Module{Name: s.Value, Attrs: attrs} } return newError("ImportError: invalid import path '%s'", name) } @@ -243,9 +243,9 @@ func evalProgram(program *ast.Program, env *object.Environment) object.Object { result = Eval(statement, env) switch result := result.(type) { - case *object.ReturnValue: + case object.ReturnValue: return result.Value - case *object.Error: + case object.Error: return result } @@ -271,7 +271,7 @@ func evalBlockStatements(block *ast.BlockStatement, env *object.Environment) obj return result } -func nativeBoolToBooleanObject(input bool) object.Object { +func nativeBoolToBooleanObject(input bool) object.Boolean { if input { return TRUE } @@ -314,14 +314,14 @@ func evalIntegerPrefixOperatorExpression(operator string, right object.Object) o return newError("unknown operator: -%s", right.Type()) } - value := right.(*object.Integer).Value + value := right.(object.Integer).Value switch operator { case "!": return FALSE case "~": - return &object.Integer{Value: ^value} + return object.Integer{Value: ^value} case "-": - return &object.Integer{Value: -value} + return object.Integer{Value: -value} default: return newError("unknown operator: %s", operator) } @@ -354,7 +354,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje // [1] * 3 case operator == "*" && left.Type() == object.ArrayType && right.Type() == object.IntegerType: leftVal := left.(*object.Array).Elements - rightVal := int(right.(*object.Integer).Value) + rightVal := int(right.(object.Integer).Value) elements := leftVal for i := rightVal; i > 1; i-- { elements = append(elements, leftVal...) @@ -363,7 +363,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje // 3 * [1] case operator == "*" && left.Type() == object.IntegerType && right.Type() == object.ArrayType: - leftVal := int(left.(*object.Integer).Value) + leftVal := int(left.(object.Integer).Value) rightVal := right.(*object.Array).Elements elements := rightVal for i := leftVal; i > 1; i-- { @@ -373,15 +373,15 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje // " " * 4 case operator == "*" && left.Type() == object.StringType && right.Type() == object.IntegerType: - leftVal := left.(*object.String).Value - rightVal := right.(*object.Integer).Value - return &object.String{Value: strings.Repeat(leftVal, int(rightVal))} + leftVal := left.(object.String).Value + rightVal := right.(object.Integer).Value + return object.String{Value: strings.Repeat(leftVal, int(rightVal))} // 4 * " " case operator == "*" && left.Type() == object.IntegerType && right.Type() == object.StringType: - leftVal := left.(*object.Integer).Value - rightVal := right.(*object.String).Value - return &object.String{Value: strings.Repeat(rightVal, int(leftVal))} + leftVal := left.(object.Integer).Value + rightVal := right.(object.String).Value + return object.String{Value: strings.Repeat(rightVal, int(leftVal))} case operator == "==": return nativeBoolToBooleanObject(left.(object.Comparable).Compare(right) == 0) @@ -409,8 +409,8 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje } func evalBooleanInfixExpression(operator string, left, right object.Object) object.Object { - leftVal := left.(*object.Boolean).Value - rightVal := right.(*object.Boolean).Value + leftVal := left.(object.Boolean).Value + rightVal := right.(object.Boolean).Value switch operator { case "&&": @@ -423,42 +423,42 @@ func evalBooleanInfixExpression(operator string, left, right object.Object) obje } func evalStringInfixExpression(operator string, left object.Object, right object.Object) object.Object { - leftVal := left.(*object.String).Value - rightVal := right.(*object.String).Value + leftVal := left.(object.String).Value + rightVal := right.(object.String).Value switch operator { case "+": - return &object.String{Value: leftVal + rightVal} + return object.String{Value: leftVal + rightVal} default: return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type()) } } func evalIntegerInfixExpression(operator string, left, right object.Object) object.Object { - leftVal := left.(*object.Integer).Value - rightVal := right.(*object.Integer).Value + leftVal := left.(object.Integer).Value + rightVal := right.(object.Integer).Value switch operator { case "+": - return &object.Integer{Value: leftVal + rightVal} + return object.Integer{Value: leftVal + rightVal} case "-": - return &object.Integer{Value: leftVal - rightVal} + return object.Integer{Value: leftVal - rightVal} case "*": - return &object.Integer{Value: leftVal * rightVal} + return object.Integer{Value: leftVal * rightVal} case "/": - return &object.Integer{Value: leftVal / rightVal} + return object.Integer{Value: leftVal / rightVal} case "%": - return &object.Integer{Value: leftVal % rightVal} + return object.Integer{Value: leftVal % rightVal} case "|": - return &object.Integer{Value: leftVal | rightVal} + return object.Integer{Value: leftVal | rightVal} case "^": - return &object.Integer{Value: leftVal ^ rightVal} + return object.Integer{Value: leftVal ^ rightVal} case "&": - return &object.Integer{Value: leftVal & rightVal} + return object.Integer{Value: leftVal & rightVal} case "<<": - return &object.Integer{Value: leftVal << uint64(rightVal)} + return object.Integer{Value: leftVal << uint64(rightVal)} case ">>": - return &object.Integer{Value: leftVal >> uint64(rightVal)} + return object.Integer{Value: leftVal >> uint64(rightVal)} case "<": return nativeBoolToBooleanObject(leftVal < rightVal) case "<=": @@ -504,11 +504,11 @@ func isTruthy(obj object.Object) bool { } } -func newError(format string, a ...interface{}) *object.Error { - return &object.Error{Message: fmt.Sprintf(format, a...)} +func newError(format string, a ...interface{}) object.Error { + return object.Error{Message: fmt.Sprintf(format, a...)} } -// EvalModule evaluates the named module and returns a *object.Module objec +// EvalModule evaluates the named module and returns a object.Module objec func EvalModule(name string) object.Object { filename := utils.FindModule(name) @@ -588,7 +588,7 @@ func extendFunctionEnv(fn *object.Function, args []object.Object) *object.Enviro } func unwrapReturnValue(obj object.Object) object.Object { - if returnValue, ok := obj.(*object.ReturnValue); ok { + if returnValue, ok := obj.(object.ReturnValue); ok { return returnValue.Value } @@ -611,20 +611,20 @@ func evalIndexExpression(left, index object.Object) object.Object { } func EvalModuleIndexExpression(module, index object.Object) object.Object { - moduleObject := module.(*object.Module) + moduleObject := module.(object.Module) return evalHashIndexExpression(moduleObject.Attrs, index) } func evalStringIndexExpression(str, index object.Object) object.Object { - stringObject := str.(*object.String) - idx := index.(*object.Integer).Value + stringObject := str.(object.String) + idx := index.(object.Integer).Value max := int64((len(stringObject.Value)) - 1) if idx < 0 || idx > max { - return &object.String{Value: ""} + return object.String{Value: ""} } - return &object.String{Value: string(stringObject.Value[idx])} + return object.String{Value: string(stringObject.Value[idx])} } func evalHashIndexExpression(hash, index object.Object) object.Object { @@ -645,7 +645,7 @@ func evalHashIndexExpression(hash, index object.Object) object.Object { func evalArrayIndexExpression(array, index object.Object) object.Object { arrayObject := array.(*object.Array) - idx := index.(*object.Integer).Value + idx := index.(object.Integer).Value maxInx := int64(len(arrayObject.Elements) - 1) if idx < 0 || idx > maxInx { diff --git a/internal/evaluator/evaluator_test.go b/internal/evaluator/evaluator_test.go index 49f6e3a..3e10172 100644 --- a/internal/evaluator/evaluator_test.go +++ b/internal/evaluator/evaluator_test.go @@ -25,25 +25,25 @@ func assertEvaluated(t *testing.T, expected interface{}, actual object.Object) { switch expected.(type) { case nil: - if _, ok := actual.(*object.Null); ok { + if _, ok := actual.(object.Null); ok { assert.True(ok) } else { assert.Equal(expected, actual) } case int: - if i, ok := actual.(*object.Integer); ok { + if i, ok := actual.(object.Integer); ok { assert.Equal(int64(expected.(int)), i.Value) } else { assert.Equal(expected, actual) } case error: - if e, ok := actual.(*object.Integer); ok { + if e, ok := actual.(object.Integer); ok { assert.Equal(expected.(error).Error(), e.Value) } else { assert.Equal(expected, actual) } case string: - if s, ok := actual.(*object.String); ok { + if s, ok := actual.(object.String); ok { assert.Equal(expected.(string), s.Value) } else { assert.Equal(expected, actual) @@ -161,7 +161,6 @@ func TestIfElseExpression(t *testing.T) { } for _, tt := range tests { - t.Log(tt.input) evaluated := testEval(tt.input) integer, ok := tt.expected.(int) if ok { @@ -279,7 +278,7 @@ func TestErrorHandling(t *testing.T) { for _, tt := range tests { evaluated := testEval(tt.input) - errObj, ok := evaluated.(*object.Error) + errObj, ok := evaluated.(object.Error) if !ok { t.Errorf("no error object returned. got=%T(%+v)", evaluated, evaluated) @@ -409,7 +408,7 @@ func TestStringLiteral(t *testing.T) { input := `"Hello World!"` evaluated := testEval(input) - str, ok := evaluated.(*object.String) + str, ok := evaluated.(object.String) if !ok { t.Fatalf("object is not String. got=%T (+%v)", evaluated, evaluated) } @@ -423,7 +422,7 @@ func TestStringConcatenation(t *testing.T) { input := `"Hello" + " " + "World!"` evaluated := testEval(input) - str, ok := evaluated.(*object.String) + str, ok := evaluated.(object.String) if !ok { t.Fatalf("object is not String. got=%T (+%v)", evaluated, evaluated) } @@ -495,7 +494,7 @@ func TestBuiltinFunctions(t *testing.T) { case string: testStringObject(t, evaluated, expected) case error: - errObj, ok := evaluated.(*object.Error) + errObj, ok := evaluated.(object.Error) if !ok { t.Errorf("object is not Error. got=%T (%+v)", evaluated, evaluated) @@ -641,12 +640,12 @@ func TestHashLiterals(t *testing.T) { } expected := map[object.HashKey]int64{ - (&object.String{Value: "one"}).HashKey(): 1, - (&object.String{Value: "two"}).HashKey(): 2, - (&object.String{Value: "three"}).HashKey(): 3, - (&object.Integer{Value: 4}).HashKey(): 4, - TRUE.HashKey(): 5, - FALSE.HashKey(): 6, + (object.String{Value: "one"}).HashKey(): 1, + (object.String{Value: "two"}).HashKey(): 2, + (object.String{Value: "three"}).HashKey(): 3, + (object.Integer{Value: 4}).HashKey(): 4, + TRUE.HashKey(): 5, + FALSE.HashKey(): 6, } if len(result.Pairs) != len(expected) { @@ -672,8 +671,8 @@ func TestHashMerging(t *testing.T) { } expected := map[object.HashKey]int64{ - (&object.String{Value: "a"}).HashKey(): 1, - (&object.String{Value: "b"}).HashKey(): 2, + (object.String{Value: "a"}).HashKey(): 1, + (object.String{Value: "b"}).HashKey(): 2, } if len(result.Pairs) != len(expected) { @@ -804,7 +803,7 @@ func testEval(input string) object.Object { } func testIntegerObject(t *testing.T, obj object.Object, expected int64) bool { - result, ok := obj.(*object.Integer) + result, ok := obj.(object.Integer) if !ok { t.Errorf("object is not Integer. got=%T (%+v)", obj, obj) return false @@ -823,7 +822,7 @@ func TestNullExpression(t *testing.T) { } func testBooleanObject(t *testing.T, obj object.Object, expected bool) bool { - result, ok := obj.(*object.Boolean) + result, ok := obj.(object.Boolean) if !ok { t.Errorf("object is not Boolean. got=%T (%+v)", obj, obj) return false @@ -845,7 +844,7 @@ func testNullObject(t *testing.T, obj object.Object) bool { } func testStringObject(t *testing.T, obj object.Object, expected string) bool { - result, ok := obj.(*object.String) + result, ok := obj.(object.String) if !ok { t.Errorf("object is not String. got=%T (%+v)", obj, obj) return false diff --git a/internal/lexer/lexer.go b/internal/lexer/lexer.go index e5d5092..7fb3f5e 100644 --- a/internal/lexer/lexer.go +++ b/internal/lexer/lexer.go @@ -232,7 +232,7 @@ func (l *Lexer) skipWhitespace() { } func (l *Lexer) readString() (string, error) { - b := &strings.Builder{} + b := strings.Builder{} for { l.readChar() if l.ch == '\\' { diff --git a/internal/object/array.go b/internal/object/array.go index aced0e5..e8c24e1 100644 --- a/internal/object/array.go +++ b/internal/object/array.go @@ -25,7 +25,7 @@ func (ao *Array) PopLeft() Object { ao.Elements = ao.Elements[1:] return e } - return &Null{} + return Null{} } func (ao *Array) PopRight() Object { @@ -34,7 +34,7 @@ func (ao *Array) PopRight() Object { ao.Elements = ao.Elements[:(len(ao.Elements) - 1)] return e } - return &Null{} + return Null{} } func (ao *Array) Prepend(obj Object) { @@ -89,7 +89,7 @@ func (ao *Array) Mul(other Object) (Object, error) { } var elements []Object - N := int(other.(*Integer).Value) + N := int(other.(Integer).Value) for i := 0; i < N; i++ { elements = append(elements, ao.Elements...) } @@ -102,10 +102,10 @@ func (ao *Array) Get(index Object) (Object, error) { return nil, fmt.Errorf("invalid type for array index, expected Integer got %s", index.Type()) } - i := index.(*Integer).Value + i := index.(Integer).Value N := int64(len(ao.Elements)) if i < 0 || i >= N { - return &Null{}, nil + return Null{}, nil } return ao.Elements[i], nil @@ -116,7 +116,7 @@ func (ao *Array) Set(index, other Object) error { return fmt.Errorf("invalid type for array index, expected Integer got %s", index.Type()) } - i := index.(*Integer).Value + i := index.(Integer).Value N := int64(len(ao.Elements)) if i < 0 || i >= N { return fmt.Errorf("index out of bounds %d with array length %d", i, N) diff --git a/internal/object/bool.go b/internal/object/bool.go index dac75a9..0948706 100644 --- a/internal/object/bool.go +++ b/internal/object/bool.go @@ -8,53 +8,53 @@ type Boolean struct { Value bool } -func (b *Boolean) Bool() bool { +func (b Boolean) Bool() bool { return b.Value } -func (b *Boolean) Type() Type { +func (b Boolean) Type() Type { return BooleanType } -func (b *Boolean) Inspect() string { +func (b Boolean) Inspect() string { return fmt.Sprintf("%t", b.Value) } -func (b *Boolean) Clone() Object { - return &Boolean{Value: b.Value} +func (b Boolean) Clone() Object { + return Boolean{Value: b.Value} } -func (b *Boolean) String() string { +func (b Boolean) String() string { return b.Inspect() } -func (b *Boolean) Int() int { +func (b Boolean) Int() int { if b.Value { return 1 } return 0 } -func (b *Boolean) LogicalAnd(other Object) (Object, error) { +func (b Boolean) LogicalAnd(other Object) (Object, error) { if !AssertTypes(other, BooleanType, IntegerType) { return nil, NewBinaryOpError(b, other, "&&") } - return &Boolean{b.Value && other.Bool()}, nil + return Boolean{b.Value && other.Bool()}, nil } -func (b *Boolean) LogicalOr(other Object) (Object, error) { +func (b Boolean) LogicalOr(other Object) (Object, error) { if !AssertTypes(other, BooleanType, IntegerType) { return nil, NewBinaryOpError(b, other, "||") } - return &Boolean{b.Value || other.Bool()}, nil + return Boolean{b.Value || other.Bool()}, nil } -func (b *Boolean) LogicalNot() Object { - return &Boolean{!b.Value} +func (b Boolean) LogicalNot() Object { + return Boolean{!b.Value} } -func (b *Boolean) Compare(other Object) int { - if obj, ok := other.(*Boolean); ok { +func (b Boolean) Compare(other Object) int { + if obj, ok := other.(Boolean); ok { return b.Int() - obj.Int() } return 1 diff --git a/internal/object/environment.go b/internal/object/environment.go index 83fcc1d..7d98b4c 100644 --- a/internal/object/environment.go +++ b/internal/object/environment.go @@ -39,7 +39,7 @@ func (e *Environment) ExportedHash() *Hash { pairs := make(map[HashKey]HashPair) for k, v := range e.store { if unicode.IsUpper(rune(k[0])) { - s := &String{Value: k} + s := String{Value: k} pairs[s.HashKey()] = HashPair{Key: s, Value: v} } } diff --git a/internal/object/error.go b/internal/object/error.go index 1764530..c06d632 100644 --- a/internal/object/error.go +++ b/internal/object/error.go @@ -6,22 +6,22 @@ type Error struct { Message string } -func (e *Error) Bool() bool { +func (e Error) Bool() bool { return false } -func (e *Error) Type() Type { +func (e Error) Type() Type { return ErrorType } -func (e *Error) Inspect() string { +func (e Error) Inspect() string { return "Error: " + e.Message } -func (e *Error) Clone() Object { - return &Error{Message: e.Message} +func (e Error) Clone() Object { + return Error{Message: e.Message} } -func (e *Error) String() string { +func (e Error) String() string { return e.Message } diff --git a/internal/object/function.go b/internal/object/function.go index c6e7406..b56c07f 100644 --- a/internal/object/function.go +++ b/internal/object/function.go @@ -12,15 +12,15 @@ type Function struct { Env *Environment } -func (f *Function) Bool() bool { +func (f Function) Bool() bool { return false } -func (f *Function) Type() Type { +func (f Function) Type() Type { return FunctionType } -func (f *Function) Inspect() string { +func (f Function) Inspect() string { var out bytes.Buffer params := []string{} @@ -38,7 +38,7 @@ func (f *Function) Inspect() string { return out.String() } -func (f *Function) String() string { +func (f Function) String() string { return f.Inspect() } @@ -46,18 +46,18 @@ type ReturnValue struct { Value Object } -func (rv *ReturnValue) Bool() bool { +func (rv ReturnValue) Bool() bool { return true } -func (rv *ReturnValue) Type() Type { +func (rv ReturnValue) Type() Type { return ReturnType } -func (rv *ReturnValue) Inspect() string { +func (rv ReturnValue) Inspect() string { return rv.Value.Inspect() } -func (rv *ReturnValue) String() string { +func (rv ReturnValue) String() string { return rv.Inspect() } diff --git a/internal/object/hash.go b/internal/object/hash.go index 8966587..6ef3a39 100644 --- a/internal/object/hash.go +++ b/internal/object/hash.go @@ -12,7 +12,7 @@ type HashKey struct { Value uint64 } -func (b *Boolean) HashKey() HashKey { +func (b Boolean) HashKey() HashKey { var value uint64 if b.Value { @@ -24,11 +24,11 @@ func (b *Boolean) HashKey() HashKey { return HashKey{Type: b.Type(), Value: value} } -func (i *Integer) HashKey() HashKey { +func (i Integer) HashKey() HashKey { return HashKey{Type: i.Type(), Value: uint64(i.Value)} } -func (s *String) HashKey() HashKey { +func (s String) HashKey() HashKey { h := fnv.New64a() h.Write([]byte(s.Value)) @@ -98,7 +98,7 @@ func (h *Hash) Get(index Object) (Object, error) { pair, found := h.Pairs[key.HashKey()] if !found { - return &Null{}, nil + return Null{}, nil } return pair.Value, nil diff --git a/internal/object/int.go b/internal/object/int.go index 34e9df5..5a7c06e 100644 --- a/internal/object/int.go +++ b/internal/object/int.go @@ -6,44 +6,44 @@ type Integer struct { Value int64 } -func (i *Integer) Bool() bool { +func (i Integer) Bool() bool { return i.Value != 0 } -func (i *Integer) Type() Type { +func (i Integer) Type() Type { return IntegerType } -func (i *Integer) Inspect() string { +func (i Integer) Inspect() string { return fmt.Sprintf("%d", i.Value) } -func (i *Integer) Clone() Object { - return &Integer{Value: i.Value} +func (i Integer) Clone() Object { + return Integer{Value: i.Value} } -func (i *Integer) String() string { +func (i Integer) String() string { return i.Inspect() } -func (i *Integer) Add(other Object) (Object, error) { +func (i Integer) Add(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { return nil, NewBinaryOpError(i, other, "+") } - return &Integer{i.Value + other.(*Integer).Value}, nil + return Integer{i.Value + other.(Integer).Value}, nil } -func (i *Integer) Sub(other Object) (Object, error) { +func (i Integer) Sub(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { return nil, NewBinaryOpError(i, other, "-") } - return &Integer{i.Value - other.(*Integer).Value}, nil + return Integer{i.Value - other.(Integer).Value}, nil } -func (i *Integer) Mul(other Object) (Object, error) { +func (i Integer) Mul(other Object) (Object, error) { switch other.Type() { case IntegerType: - return &Integer{i.Value * other.(*Integer).Value}, nil + return Integer{i.Value * other.(Integer).Value}, nil case StringType: return other.(Mul).Mul(i) case ArrayType: @@ -53,69 +53,69 @@ func (i *Integer) Mul(other Object) (Object, error) { } } -func (i *Integer) Div(other Object) (Object, error) { +func (i Integer) Div(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { return nil, NewBinaryOpError(i, other, "/") } - return &Integer{i.Value / other.(*Integer).Value}, nil + return Integer{i.Value / other.(Integer).Value}, nil } -func (i *Integer) Mod(other Object) (Object, error) { +func (i Integer) Mod(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { return nil, NewBinaryOpError(i, other, "%") } - return &Integer{i.Value % other.(*Integer).Value}, nil + return Integer{i.Value % other.(Integer).Value}, nil } -func (i *Integer) BitwiseOr(other Object) (Object, error) { +func (i Integer) BitwiseOr(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { return nil, NewBinaryOpError(i, other, "|") } - return &Integer{i.Value | other.(*Integer).Value}, nil + return Integer{i.Value | other.(Integer).Value}, nil } -func (i *Integer) BitwiseXor(other Object) (Object, error) { +func (i Integer) BitwiseXor(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { return nil, NewBinaryOpError(i, other, "^") } - return &Integer{i.Value ^ other.(*Integer).Value}, nil + return Integer{i.Value ^ other.(Integer).Value}, nil } -func (i *Integer) BitwiseAnd(other Object) (Object, error) { +func (i Integer) BitwiseAnd(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { - return nil, NewBinaryOpError(i, other, "&") + return nil, NewBinaryOpError(i, other, "") } - return &Integer{i.Value & other.(*Integer).Value}, nil + return Integer{i.Value & other.(Integer).Value}, nil } -func (i *Integer) BitwiseNot() Object { - return &Integer{^i.Value} +func (i Integer) BitwiseNot() Object { + return Integer{^i.Value} } -func (i *Integer) LeftShift(other Object) (Object, error) { +func (i Integer) LeftShift(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { return nil, NewBinaryOpError(i, other, "<<") } - return &Integer{i.Value << other.(*Integer).Value}, nil + return Integer{i.Value << other.(Integer).Value}, nil } -func (i *Integer) RightShift(other Object) (Object, error) { +func (i Integer) RightShift(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { return nil, NewBinaryOpError(i, other, ">>") } - return &Integer{i.Value >> other.(*Integer).Value}, nil + return Integer{i.Value >> other.(Integer).Value}, nil } -func (i *Integer) LogicalNot() Object { - return &Boolean{!i.Bool()} +func (i Integer) LogicalNot() Object { + return Boolean{!i.Bool()} } -func (i *Integer) Negate() Object { - return &Integer{-i.Value} +func (i Integer) Negate() Object { + return Integer{-i.Value} } -func (i *Integer) Compare(other Object) int { - if obj, ok := other.(*Integer); ok { +func (i Integer) Compare(other Object) int { + if obj, ok := other.(Integer); ok { switch { case i.Value < obj.Value: return -1 diff --git a/internal/object/module.go b/internal/object/module.go index 595f87d..67a068b 100644 --- a/internal/object/module.go +++ b/internal/object/module.go @@ -24,7 +24,7 @@ func (m Module) Inspect() string { return fmt.Sprintf("", m.Name) } -func (m *Module) Get(index Object) (Object, error) { +func (m Module) Get(index Object) (Object, error) { key, ok := index.(Hashable) if !ok { return nil, fmt.Errorf("invalid module attribute %s", index.Type()) @@ -32,7 +32,7 @@ func (m *Module) Get(index Object) (Object, error) { attr, found := m.Attrs.(*Hash).Pairs[key.HashKey()] if !found { - return &Null{}, nil + return Null{}, nil } return attr.Value, nil diff --git a/internal/object/null.go b/internal/object/null.go index f0b59cd..50a6a92 100644 --- a/internal/object/null.go +++ b/internal/object/null.go @@ -2,28 +2,28 @@ package object type Null struct{} -func (n *Null) Bool() bool { +func (n Null) Bool() bool { return false } -func (n *Null) Type() Type { +func (n Null) Type() Type { return NullType } -func (n *Null) Inspect() string { +func (n Null) Inspect() string { return "null" } -func (n *Null) String() string { +func (n Null) String() string { return n.Inspect() } -func (n *Null) LogicalNot() Object { - return &Boolean{!n.Bool()} +func (n Null) LogicalNot() Object { + return Boolean{!n.Bool()} } -func (n *Null) Compare(other Object) int { - if _, ok := other.(*Null); ok { +func (n Null) Compare(other Object) int { + if _, ok := other.(Null); ok { return 0 } return 1 diff --git a/internal/object/object_test.go b/internal/object/object_test.go index c52b0a6..b74aa87 100644 --- a/internal/object/object_test.go +++ b/internal/object/object_test.go @@ -3,10 +3,10 @@ package object import "testing" func TestStringHashKey(t *testing.T) { - hello1 := &String{Value: "Hello World"} - hello2 := &String{Value: "Hello World"} - diff1 := &String{Value: "My name is johnny"} - diff2 := &String{Value: "My name is johnny"} + hello1 := String{Value: "Hello World"} + hello2 := String{Value: "Hello World"} + diff1 := String{Value: "My name is johnny"} + diff2 := String{Value: "My name is johnny"} if hello1.HashKey() != hello2.HashKey() { t.Errorf("string with same content have different hash keys") diff --git a/internal/object/str.go b/internal/object/str.go index fab48e1..6809e82 100644 --- a/internal/object/str.go +++ b/internal/object/str.go @@ -10,59 +10,59 @@ type String struct { Value string } -func (s *String) Len() int { +func (s String) Len() int { return utf8.RuneCountInString(s.Value) } -func (s *String) Bool() bool { +func (s String) Bool() bool { return s.Value != "" } -func (s *String) Type() Type { +func (s String) Type() Type { return StringType } -func (s *String) Inspect() string { +func (s String) Inspect() string { return fmt.Sprintf("%#v", s.Value) } -func (s *String) Clone() Object { - return &String{Value: s.Value} +func (s String) Clone() Object { + return String{Value: s.Value} } -func (s *String) String() string { +func (s String) String() string { return s.Value } -func (s *String) Add(other Object) (Object, error) { +func (s String) Add(other Object) (Object, error) { if !AssertTypes(other, StringType) { return nil, NewBinaryOpError(s, other, "+") } - return &String{s.Value + other.(*String).Value}, nil + return String{s.Value + other.(String).Value}, nil } -func (s *String) Mul(other Object) (Object, error) { +func (s String) Mul(other Object) (Object, error) { if !AssertTypes(other, IntegerType) { return nil, NewBinaryOpError(s, other, "*") } - return &String{strings.Repeat(s.Value, int(other.(*Integer).Value))}, nil + return String{strings.Repeat(s.Value, int(other.(Integer).Value))}, nil } -func (s *String) Get(index Object) (Object, error) { +func (s String) Get(index Object) (Object, error) { if !AssertTypes(index, IntegerType) { return nil, fmt.Errorf("invalid type for string index, expected Integer got %s", index.Type()) } - i := int(index.(*Integer).Value) + i := int(index.(Integer).Value) if i < 0 || i >= len(s.Value) { - return &String{}, nil + return String{}, nil } - return &String{string(s.Value[i])}, nil + return String{string(s.Value[i])}, nil } -func (s *String) Compare(other Object) int { - if obj, ok := other.(*String); ok { +func (s String) Compare(other Object) int { + if obj, ok := other.(String); ok { switch { case s.Value < obj.Value: return -1 diff --git a/internal/plugins/hello.go b/internal/plugins/hello.go index f91f6c8..ee219af 100644 --- a/internal/plugins/hello.go +++ b/internal/plugins/hello.go @@ -4,5 +4,5 @@ import "monkey/internal/object" // Hello ... func Hello(args ...object.Object) object.Object { - return &object.String{Value: "Hello World!"} + return object.String{Value: "Hello World!"} } diff --git a/internal/vm/frame.go b/internal/vm/frame.go index 5a564a2..6ffc14d 100644 --- a/internal/vm/frame.go +++ b/internal/vm/frame.go @@ -11,23 +11,39 @@ type Frame struct { basePointer int } -func NewFrame(cl *object.Closure, basePointer int) *Frame { - return &Frame{ +func NewFrame(cl *object.Closure, basePointer int) Frame { + return Frame{ cl: cl, basePointer: basePointer, } } +func (f *Frame) Closure() *object.Closure { + return f.cl +} + +func (f *Frame) GetFree(idx uint8) object.Object { + return f.cl.Free[idx] +} + +func (f *Frame) SetFree(idx uint8, obj object.Object) { + f.cl.Free[idx] = obj +} + +func (f *Frame) SetIP(ip int) { + f.ip = ip +} + +func (f Frame) PeekNextOp() code.Opcode { + return code.Opcode(f.cl.Fn.Instructions[f.ip]) +} + func (f *Frame) ReadNextOp() code.Opcode { op := code.Opcode(f.cl.Fn.Instructions[f.ip]) f.ip++ return op } -func (f *Frame) PeekNextOp() code.Opcode { - return code.Opcode(f.cl.Fn.Instructions[f.ip]) -} - func (f *Frame) ReadUint8() uint8 { n := code.ReadUint8(f.cl.Fn.Instructions[f.ip:]) f.ip++ @@ -40,6 +56,6 @@ func (f *Frame) ReadUint16() uint16 { return n } -func (f *Frame) Instructions() code.Instructions { +func (f Frame) Instructions() code.Instructions { return f.cl.Fn.Instructions } diff --git a/internal/vm/vm.go b/internal/vm/vm.go index c1b316c..9c0a19d 100644 --- a/internal/vm/vm.go +++ b/internal/vm/vm.go @@ -20,17 +20,17 @@ const StackSize = 2048 const GlobalsSize = 65536 const MaxFrames = 1024 -var Null = &object.Null{} -var True = &object.Boolean{Value: true} -var False = &object.Boolean{Value: false} +var Null = object.Null{} +var True = object.Boolean{Value: true} +var False = object.Boolean{Value: false} func isTruthy(obj object.Object) bool { switch obj := obj.(type) { - case *object.Boolean: + case object.Boolean: return obj.Value - case *object.Null: + case object.Null: return false default: @@ -38,7 +38,7 @@ func isTruthy(obj object.Object) bool { } } -// executeModule compiles the named module and returns a *object.Module object +// executeModule compiles the named module and returns a object.Module object func executeModule(name string, state *VMState) (object.Object, error) { filename := utils.FindModule(name) if filename == "" { @@ -104,7 +104,7 @@ func (s *VMState) ExportedHash() *object.Hash { if unicode.IsUpper(rune(name[0])) { if symbol.Scope == compiler.GlobalScope { obj := s.Globals[symbol.Index] - s := &object.String{Value: name} + s := object.String{Value: name} pairs[s.HashKey()] = object.HashPair{Key: s, Value: obj} } } @@ -123,20 +123,21 @@ type VM struct { stack []object.Object sp int // Always points to the next value. Top of stack is stack[sp-1] - frames []*Frame - frame *Frame // Current frame or nil - fp int // Always points to the current frame. Current frame is frames[fp-1] + frames []Frame + fp int // Always points to the current frame. Current frame is frames[fp-1] } -func (vm *VM) pushFrame(f *Frame) { - vm.frame = f +func (vm *VM) currentFrame() *Frame { + return &vm.frames[vm.fp-1] +} + +func (vm *VM) pushFrame(f Frame) { vm.frames[vm.fp] = f vm.fp++ } -func (vm *VM) popFrame() *Frame { +func (vm *VM) popFrame() Frame { vm.fp-- - vm.frame = vm.frames[vm.fp-1] return vm.frames[vm.fp] } @@ -146,7 +147,7 @@ func New(fn string, bytecode *compiler.Bytecode) *VM { mainClosure := &object.Closure{Fn: mainFn} mainFrame := NewFrame(mainClosure, 0) - frames := make([]*Frame, MaxFrames) + frames := make([]Frame, MaxFrames) frames[0] = mainFrame state := NewVMState() @@ -159,7 +160,6 @@ func New(fn string, bytecode *compiler.Bytecode) *VM { sp: 0, frames: frames, - frame: mainFrame, fp: 1, } @@ -173,14 +173,13 @@ func NewWithState(fn string, bytecode *compiler.Bytecode, state *VMState) *VM { mainClosure := &object.Closure{Fn: mainFn} mainFrame := NewFrame(mainClosure, 0) - frames := make([]*Frame, MaxFrames) + frames := make([]Frame, MaxFrames) frames[0] = mainFrame vm := &VM{ state: state, frames: frames, - frame: mainFrame, fp: 1, stack: make([]object.Object, StackSize), @@ -210,30 +209,30 @@ func (vm *VM) pop() object.Object { } func (vm *VM) executeLoadBuiltin() error { - builtinIndex := vm.frame.ReadUint8() + builtinIndex := vm.currentFrame().ReadUint8() builtin := builtins.BuiltinsIndex[builtinIndex] return vm.push(builtin) } func (vm *VM) executeConstant() error { - constIndex := vm.frame.ReadUint16() + constIndex := vm.currentFrame().ReadUint16() return vm.push(vm.state.Constants[constIndex]) } func (vm *VM) executeAssignGlobal() error { - globalIndex := vm.frame.ReadUint16() + globalIndex := vm.currentFrame().ReadUint16() vm.state.Globals[globalIndex] = vm.pop() return vm.push(Null) } func (vm *VM) executeAssignLocal() error { - localIndex := vm.frame.ReadUint8() - vm.stack[vm.frame.basePointer+int(localIndex)] = vm.pop() + localIndex := vm.currentFrame().ReadUint8() + vm.stack[vm.currentFrame().basePointer+int(localIndex)] = vm.pop() return vm.push(Null) } func (vm *VM) executeSetGlobal() error { - globalIndex := vm.frame.ReadUint16() + globalIndex := vm.currentFrame().ReadUint16() ref := vm.pop() if immutable, ok := ref.(object.Immutable); ok { @@ -246,31 +245,31 @@ func (vm *VM) executeSetGlobal() error { } func (vm *VM) executeGetGlobal() error { - globalIndex := vm.frame.ReadUint16() + globalIndex := vm.currentFrame().ReadUint16() return vm.push(vm.state.Globals[globalIndex]) } func (vm *VM) executeSetLocal() error { - localIndex := vm.frame.ReadUint8() + localIndex := vm.currentFrame().ReadUint8() ref := vm.pop() if immutable, ok := ref.(object.Immutable); ok { - vm.stack[vm.frame.basePointer+int(localIndex)] = immutable.Clone() + vm.stack[vm.currentFrame().basePointer+int(localIndex)] = immutable.Clone() } else { - vm.stack[vm.frame.basePointer+int(localIndex)] = ref + vm.stack[vm.currentFrame().basePointer+int(localIndex)] = ref } return vm.push(Null) } func (vm *VM) executeGetLocal() error { - localIndex := vm.frame.ReadUint8() - return vm.push(vm.stack[vm.frame.basePointer+int(localIndex)]) + localIndex := vm.currentFrame().ReadUint8() + return vm.push(vm.stack[vm.currentFrame().basePointer+int(localIndex)]) } func (vm *VM) executeGetFree() error { - freeIndex := vm.frame.ReadUint8() - return vm.push(vm.frame.cl.Free[freeIndex]) + freeIndex := vm.currentFrame().ReadUint8() + return vm.push(vm.currentFrame().GetFree(freeIndex)) } func (vm *VM) executeLoadModule() error { @@ -279,7 +278,7 @@ func (vm *VM) executeLoadModule() error { } func (vm *VM) executeCurrentClosure() error { - currentClosure := vm.frame.cl + currentClosure := vm.currentFrame().cl return vm.push(currentClosure) } @@ -316,7 +315,7 @@ func (vm *VM) buildHash(startIndex, endIndex int) (object.Object, error) { } func (vm *VM) executeMakeHash() error { - startIndex := vm.sp - int(vm.frame.ReadUint16()) + startIndex := vm.sp - int(vm.currentFrame().ReadUint16()) hash, err := vm.buildHash(startIndex, vm.sp) if err != nil { return err @@ -336,7 +335,7 @@ func (vm *VM) buildArray(startIndex, endIndex int) (object.Object, error) { } func (vm *VM) executeMakeArray() error { - startIndex := vm.sp - int(vm.frame.ReadUint16()) + startIndex := vm.sp - int(vm.currentFrame().ReadUint16()) hash, err := vm.buildArray(startIndex, vm.sp) if err != nil { return err @@ -346,8 +345,8 @@ func (vm *VM) executeMakeArray() error { } func (vm *VM) executeClosure() error { - constIndex := vm.frame.ReadUint16() - numFree := vm.frame.ReadUint8() + constIndex := vm.currentFrame().ReadUint16() + numFree := vm.currentFrame().ReadUint8() return vm.pushClosure(int(constIndex), int(numFree)) } @@ -659,7 +658,7 @@ func (vm *VM) executeGetItem() error { } func (vm *VM) executeCall() error { - args := int(vm.frame.ReadUint8()) + args := int(vm.currentFrame().ReadUint8()) callee := vm.stack[vm.sp-1-args] switch callee := callee.(type) { @@ -685,16 +684,16 @@ func (vm *VM) executeReturn() error { } func (vm *VM) executeJumpIfFalse() error { - pos := int(vm.frame.ReadUint16()) + pos := int(vm.currentFrame().ReadUint16()) if !isTruthy(vm.pop()) { - vm.frame.ip = pos + vm.currentFrame().SetIP(pos) } return nil } func (vm *VM) executeJump() error { - pos := int(vm.frame.ReadUint16()) - vm.frame.ip = pos + pos := int(vm.currentFrame().ReadUint16()) + vm.currentFrame().SetIP(pos) return nil } @@ -709,14 +708,14 @@ func (vm *VM) callClosure(cl *object.Closure, numArgs int) error { } // Optimize tail calls and avoid a new frame - if cl.Fn == vm.frame.cl.Fn { - nextOP := vm.frame.PeekNextOp() + if cl.Fn == vm.currentFrame().cl.Fn { + nextOP := vm.currentFrame().PeekNextOp() if nextOP == code.OpReturn { for p := 0; p < numArgs; p++ { - vm.stack[vm.frame.basePointer+p] = vm.stack[vm.sp-numArgs+p] + vm.stack[vm.currentFrame().basePointer+p] = vm.stack[vm.sp-numArgs+p] } vm.sp -= numArgs + 1 - vm.frame.ip = 0 // reset IP to the beginning of the frame + vm.currentFrame().SetIP(0) // reset IP to the beginning of the frame return nil } } @@ -767,7 +766,7 @@ func (vm *VM) pushClosure(constIndex, numFree int) error { } func (vm *VM) loadModule(name object.Object) error { - s, ok := name.(*object.String) + s, ok := name.(object.String) if !ok { return fmt.Errorf( "TypeError: import() expected argument #1 to be `str` got `%s`", @@ -780,7 +779,7 @@ func (vm *VM) loadModule(name object.Object) error { return err } - module := &object.Module{Name: s.Value, Attrs: attrs} + module := object.Module{Name: s.Value, Attrs: attrs} return vm.push(module) } @@ -799,16 +798,16 @@ func (vm *VM) Run() (err error) { } for err == nil { - op := vm.frame.ReadNextOp() + op := vm.currentFrame().ReadNextOp() if vm.Debug { n++ log.Printf( "%-25s %-20s\n", - fmt.Sprintf("%04d %s", vm.frame.ip, op), + fmt.Sprintf("%04d %s", vm.currentFrame().ip, op), fmt.Sprintf( "[ip=%02d fp=%02d, sp=%02d]", - vm.frame.ip, vm.fp-1, vm.sp, + vm.currentFrame().ip, vm.fp-1, vm.sp, ), ) } @@ -953,7 +952,7 @@ func (vm *VM) Run() (err error) { if vm.Debug { log.Printf( "%-25s [ip=%02d fp=%02d, sp=%02d]", - "", vm.frame.ip, vm.fp-1, vm.sp, + "", vm.currentFrame().ip, vm.fp-1, vm.sp, ) } } diff --git a/internal/vm/vm_test.go b/internal/vm/vm_test.go index 535fde9..a740951 100644 --- a/internal/vm/vm_test.go +++ b/internal/vm/vm_test.go @@ -42,7 +42,7 @@ func runVmTests(t *testing.T, tests []vmTestCase) { // switch constant := constant.(type) { // case *object.CompiledFunction: // fmt.Printf(" Instructions:\n%s", constant.Instructions) - // case *object.Integer: + // case object.Integer: // fmt.Printf(" Value: %d\n", constant.Value) // } // @@ -129,13 +129,13 @@ func testExpectedObject(t *testing.T, expected interface{}, actual object.Object } } - case *object.Null: + case object.Null: if actual != Null { t.Errorf("object is not Null: %T (%+v)", actual, actual) } - case *object.Error: - errObj, ok := actual.(*object.Error) + case object.Error: + errObj, ok := actual.(object.Error) if !ok { t.Errorf("object is not Error: %T (%+v)", actual, actual) return @@ -153,7 +153,7 @@ func parse(input string) *ast.Program { } func testIntegerObject(expected int64, actual object.Object) error { - result, ok := actual.(*object.Integer) + result, ok := actual.(object.Integer) if !ok { return fmt.Errorf("object is not Integer. got=%T (%+v", actual, actual) } @@ -166,7 +166,7 @@ func testIntegerObject(expected int64, actual object.Object) error { } func testBooleanObject(expected bool, actual object.Object) error { - result, ok := actual.(*object.Boolean) + result, ok := actual.(object.Boolean) if !ok { return fmt.Errorf("object is not Boolean. got=%T (%+v", actual, actual) } @@ -179,7 +179,7 @@ func testBooleanObject(expected bool, actual object.Object) error { } func testStringObject(expected string, actual object.Object) error { - result, ok := actual.(*object.String) + result, ok := actual.(object.String) if !ok { return fmt.Errorf("object is not String. got=%T (%+v", actual, actual) } @@ -379,15 +379,15 @@ func TestHashLiterals(t *testing.T) { { "{1: 2, 2: 3}", map[object.HashKey]int64{ - (&object.Integer{Value: 1}).HashKey(): 2, - (&object.Integer{Value: 2}).HashKey(): 3, + (object.Integer{Value: 1}).HashKey(): 2, + (object.Integer{Value: 2}).HashKey(): 3, }, }, { "{1 + 1: 2 * 2, 3 + 3: 4 * 4}", map[object.HashKey]int64{ - (&object.Integer{Value: 2}).HashKey(): 4, - (&object.Integer{Value: 6}).HashKey(): 16, + (object.Integer{Value: 2}).HashKey(): 4, + (object.Integer{Value: 6}).HashKey(): 16, }, }, } @@ -400,14 +400,14 @@ func TestHashMerging(t *testing.T) { { `{} + {"a": 1}`, map[object.HashKey]int64{ - (&object.String{Value: "a"}).HashKey(): 1, + (object.String{Value: "a"}).HashKey(): 1, }, }, { `{"a": 1} + {"b": 2}`, map[object.HashKey]int64{ - (&object.String{Value: "a"}).HashKey(): 1, - (&object.String{Value: "b"}).HashKey(): 2, + (object.String{Value: "a"}).HashKey(): 1, + (object.String{Value: "b"}).HashKey(): 2, }, }, }