diff --git a/README.md b/README.md index e585ce1..734a60d 100644 --- a/README.md +++ b/README.md @@ -272,12 +272,12 @@ It is also possible to define a function without the use of `let`, via the `func function hello() { puts "Hello, world\n" ; }; hello(); // Outputs: Hello, world" to the console. -You may specify a default value for arguments which are not specified, -for example: +You may specify a default value for arguments which are not provided, for example: let foo = fn( name = "World!") { puts( "Hello, " + name + "\n" ); }; + foo(); foo( "Steve" ); @@ -401,5 +401,64 @@ capture groups in the match. This is demonstrated in the [examples/regexp.mon](examples/regexp.mon) example. +# 3. Object Methods + +There is now support for "object-methods". Object methods are methods +which are defined against a _type_. For example all of our primitive +types allow a `methods()` method, which returns the methods which are +available against them. + +Similarly each of them implement a `type()` function which returns the +type involved: + + let i = 1; + puts( i.type() ); + + let s = "Steve"; + puts( s.type() ); + +Or even: + + puts( "Steve".type() ); + +Seeing methods available works as you would expect: + + a = [ "Array", "Is", "Here" ]; + + let i = 0; + for ( i < len(a.methods() ) ) { + puts( "Method " + a.methods()[i] + "\n" ); + i++; + } + +This shows: + + Method find + Method len + Method methods + Method string + +The `string` object has the most methods at the time of writing, but +no doubt things will change over time. + + +## 3.1 Object Method Limitations + +Object-methods are currently implemented in Go, and the user cannot +add new ones. This is something I'm pondering how to change. + +It might be possible to allow new methods to be implemented in the +future via a specialised method: + + class string { + + function foo() { + puts( "Called with a string : " + this + "\n" ); + } + }; + +If something like that were implemented then `"input".foo()` would work. + + Steve -- diff --git a/object/object_array.go b/object/object_array.go index fd37b28..8a3f919 100644 --- a/object/object_array.go +++ b/object/object_array.go @@ -75,5 +75,8 @@ func (ao *Array) InvokeMethod(method string, args ...Object) Object { if method == "string" { return &String{Value: ao.Inspect()} } + if method == "type" { + return &String{Value: "array"} + } return nil } diff --git a/object/object_bool.go b/object/object_bool.go index d2a3cd9..d00f698 100644 --- a/object/object_bool.go +++ b/object/object_bool.go @@ -46,7 +46,7 @@ func (b *Boolean) HashKey() HashKey { // (Built-in methods only.) func (b *Boolean) InvokeMethod(method string, args ...Object) Object { if method == "methods" { - names := []string{"methods", "string"} + names := []string{"methods", "string", "type"} result := make([]Object, len(names), len(names)) for i, txt := range names { @@ -57,5 +57,8 @@ func (b *Boolean) InvokeMethod(method string, args ...Object) Object { if method == "string" { return &String{Value: b.Inspect()} } + if method == "type" { + return &String{Value: "bool"} + } return nil } diff --git a/object/object_float.go b/object/object_float.go index f78e5cd..ea16415 100644 --- a/object/object_float.go +++ b/object/object_float.go @@ -45,7 +45,7 @@ func (f *Float) HashKey() HashKey { // (Built-in methods only.) func (f *Float) InvokeMethod(method string, args ...Object) Object { if method == "methods" { - names := []string{"methods", "string"} + names := []string{"methods", "string", "type"} result := make([]Object, len(names), len(names)) for i, txt := range names { @@ -56,5 +56,8 @@ func (f *Float) InvokeMethod(method string, args ...Object) Object { if method == "string" { return &String{Value: f.Inspect()} } + if method == "type" { + return &String{Value: "float"} + } return nil } diff --git a/object/object_function.go b/object/object_function.go index cc02606..6235645 100644 --- a/object/object_function.go +++ b/object/object_function.go @@ -50,5 +50,17 @@ func (f *Function) Inspect() string { // InvokeMethod invokes a method against the object. // (Built-in methods only.) func (f *Function) InvokeMethod(method string, args ...Object) Object { + if method == "methods" { + names := []string{"methods", "type"} + + result := make([]Object, len(names), len(names)) + for i, txt := range names { + result[i] = &String{Value: txt} + } + return &Array{Elements: result} + } + if method == "type" { + return &String{Value: "function"} + } return nil } diff --git a/object/object_hash.go b/object/object_hash.go index 006a015..1980af3 100644 --- a/object/object_hash.go +++ b/object/object_hash.go @@ -66,7 +66,7 @@ func (h *Hash) Inspect() string { // (Built-in methods only.) func (h *Hash) InvokeMethod(method string, args ...Object) Object { if method == "methods" { - names := []string{"keys", "methods", "string"} + names := []string{"keys", "methods", "string", "type"} result := make([]Object, len(names), len(names)) for i, txt := range names { @@ -90,5 +90,8 @@ func (h *Hash) InvokeMethod(method string, args ...Object) Object { if method == "string" { return &String{Value: h.Inspect()} } + if method == "type" { + return &String{Value: "hash"} + } return nil } diff --git a/object/object_int.go b/object/object_int.go index ca706ec..f290966 100644 --- a/object/object_int.go +++ b/object/object_int.go @@ -41,7 +41,7 @@ func (i *Integer) HashKey() HashKey { func (i *Integer) InvokeMethod(method string, args ...Object) Object { if method == "methods" { - names := []string{"methods", "string"} + names := []string{"methods", "string", "type"} result := make([]Object, len(names), len(names)) for i, txt := range names { @@ -52,5 +52,8 @@ func (i *Integer) InvokeMethod(method string, args ...Object) Object { if method == "string" { return &String{Value: i.Inspect()} } + if method == "type" { + return &String{Value: "integer"} + } return nil }