diff --git a/core/procs.go b/core/procs.go index 3a7c7e24d..11367526f 100644 --- a/core/procs.go +++ b/core/procs.go @@ -94,6 +94,10 @@ func ExtractString(args []Object, index int) string { return EnsureString(args, index).S } +func ExtractStringable(args []Object, index int) string { + return EnsureStringable(args, index).S +} + func ExtractStrings(args []Object, index int) []string { strs := make([]string, 0) for i := index; i < len(args); i++ { diff --git a/core/stringable.go b/core/stringable.go new file mode 100644 index 000000000..a709ff936 --- /dev/null +++ b/core/stringable.go @@ -0,0 +1,30 @@ +package core + +import ( + "fmt" +) + +func AssertStringable(obj Object, msg string) String { + switch c := obj.(type) { + case String: + return c + case Char: + return String{S: string(c.Ch)} + default: + if msg == "" { + msg = fmt.Sprintf("Expected %s, got %s", "Stringable", obj.GetType().ToString(false)) + } + panic(RT.NewError(msg)) + } +} + +func EnsureStringable(args []Object, index int) String { + switch c := args[index].(type) { + case String: + return c + case Char: + return String{S: string(c.Ch)} + default: + panic(RT.NewArgTypeError(index, c, "Stringable")) + } +} diff --git a/std/string.joke b/std/string.joke index a5e63d80c..40b76a7c5 100644 --- a/std/string.joke +++ b/std/string.joke @@ -7,25 +7,25 @@ "True if s ends with substr." {:added "1.0" :go "strings.HasSuffix(s, substr)"} - [^String s ^String substr]) + [^String s ^Stringable substr]) (defn ^Boolean starts-with? "True if s starts with substr." {:added "1.0" :go "strings.HasPrefix(s, substr)"} - [^String s ^String substr]) + [^String s ^Stringable substr]) (defn ^String pad-right "Returns s padded with pad at the end to length n." {:added "1.0" :go "padRight(s, pad, n)"} - [^String s ^String pad ^Int n]) + [^String s ^Stringable pad ^Int n]) (defn ^String pad-left "Returns s padded with pad at the beginning to length n." {:added "1.0" :go "padLeft(s, pad, n)"} - [^String s ^String pad ^Int n]) + [^String s ^Stringable pad ^Int n]) (defn split "Splits string on a regular expression. Returns vector of the splits." @@ -47,7 +47,7 @@ :go {1 "join(\"\", coll)" 2 "join(separator, coll)"}} ([^Seqable coll]) - ([^String separator ^Seqable coll])) + ([^Stringable separator ^Seqable coll])) (defn ^String replace "Replaces all instances of match (String or Regex) with string repl in string s. @@ -58,7 +58,7 @@ " {:added "1.0" :go "replace(s, match, repl)"} - [^String s ^Object match ^String repl]) + [^String s ^Object match ^Stringable repl]) (defn ^String replace-first "Replaces the first instance of match (String or Regex) with string repl in string s. @@ -69,7 +69,7 @@ " {:added "1.0" :go "replaceFirst(s, match, repl)"} - [^String s ^Object match ^String repl]) + [^String s ^Object match ^Stringable repl]) (defn ^String trim "Removes whitespace from both ends of string." @@ -106,7 +106,7 @@ characters to lower-case." {:added "1.0" :go "capitalize(s)"} - [^String s]) + [^Stringable s]) (defn ^String escape "Return a new string, using cmap to escape each character ch @@ -122,7 +122,7 @@ "True if s includes substr." {:added "1.0" :go "strings.Contains(s, substr)"} - [^String s ^String substr]) + [^String s ^Stringable substr]) (defn index-of "Return index of value (string or char) in s, optionally searching @@ -146,13 +146,13 @@ "Converts string to all lower-case." {:added "1.0" :go "strings.ToLower(s)"} - [^String s]) + [^Stringable s]) (defn ^String upper-case "Converts string to all upper-case." {:added "1.0" :go "strings.ToUpper(s)"} - [^String s]) + [^Stringable s]) (defn ^String reverse "Returns s with its characters reversed." diff --git a/std/string/a_string.go b/std/string/a_string.go index 1390ac026..8d327cbb4 100644 --- a/std/string/a_string.go +++ b/std/string/a_string.go @@ -28,7 +28,7 @@ var capitalize_ Proc = func(_args []Object) Object { _c := len(_args) switch { case _c == 1: - s := ExtractString(_args, 0) + s := ExtractStringable(_args, 0) _res := capitalize(s) return MakeString(_res) @@ -43,7 +43,7 @@ var isends_with_ Proc = func(_args []Object) Object { switch { case _c == 2: s := ExtractString(_args, 0) - substr := ExtractString(_args, 1) + substr := ExtractStringable(_args, 1) _res := strings.HasSuffix(s, substr) return MakeBoolean(_res) @@ -73,7 +73,7 @@ var isincludes_ Proc = func(_args []Object) Object { switch { case _c == 2: s := ExtractString(_args, 0) - substr := ExtractString(_args, 1) + substr := ExtractStringable(_args, 1) _res := strings.Contains(s, substr) return MakeBoolean(_res) @@ -114,7 +114,7 @@ var join_ Proc = func(_args []Object) Object { return MakeString(_res) case _c == 2: - separator := ExtractString(_args, 0) + separator := ExtractStringable(_args, 0) coll := ExtractSeqable(_args, 1) _res := join(separator, coll) return MakeString(_res) @@ -151,7 +151,7 @@ var lower_case_ Proc = func(_args []Object) Object { _c := len(_args) switch { case _c == 1: - s := ExtractString(_args, 0) + s := ExtractStringable(_args, 0) _res := strings.ToLower(s) return MakeString(_res) @@ -166,7 +166,7 @@ var pad_left_ Proc = func(_args []Object) Object { switch { case _c == 3: s := ExtractString(_args, 0) - pad := ExtractString(_args, 1) + pad := ExtractStringable(_args, 1) n := ExtractInt(_args, 2) _res := padLeft(s, pad, n) return MakeString(_res) @@ -182,7 +182,7 @@ var pad_right_ Proc = func(_args []Object) Object { switch { case _c == 3: s := ExtractString(_args, 0) - pad := ExtractString(_args, 1) + pad := ExtractStringable(_args, 1) n := ExtractInt(_args, 2) _res := padRight(s, pad, n) return MakeString(_res) @@ -199,7 +199,7 @@ var replace_ Proc = func(_args []Object) Object { case _c == 3: s := ExtractString(_args, 0) match := ExtractObject(_args, 1) - repl := ExtractString(_args, 2) + repl := ExtractStringable(_args, 2) _res := replace(s, match, repl) return MakeString(_res) @@ -215,7 +215,7 @@ var replace_first_ Proc = func(_args []Object) Object { case _c == 3: s := ExtractString(_args, 0) match := ExtractObject(_args, 1) - repl := ExtractString(_args, 2) + repl := ExtractStringable(_args, 2) _res := replaceFirst(s, match, repl) return MakeString(_res) @@ -280,7 +280,7 @@ var isstarts_with_ Proc = func(_args []Object) Object { switch { case _c == 2: s := ExtractString(_args, 0) - substr := ExtractString(_args, 1) + substr := ExtractStringable(_args, 1) _res := strings.HasPrefix(s, substr) return MakeBoolean(_res) @@ -350,7 +350,7 @@ var upper_case_ Proc = func(_args []Object) Object { _c := len(_args) switch { case _c == 1: - s := ExtractString(_args, 0) + s := ExtractStringable(_args, 0) _res := strings.ToUpper(s) return MakeString(_res)