From f4fc95cb7f7ed5c607173d330fc4121282f2da52 Mon Sep 17 00:00:00 2001 From: odino Date: Fri, 16 Aug 2019 17:02:12 +0400 Subject: [PATCH] str.replace supports a short form that doesn't require the n argument, closes #262 ``` "aaaa".replace("a", "x") # "xxxx" ``` --- docs/types/string.md | 8 +++++--- evaluator/evaluator_test.go | 2 ++ evaluator/functions.go | 18 ++++++++++++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/docs/types/string.md b/docs/types/string.md index 3819802c..91de024a 100644 --- a/docs/types/string.md +++ b/docs/types/string.md @@ -337,19 +337,21 @@ Creates a new string, repeating the original one `i` times: "string".repeat(2) # "stringstring" ``` -### replace(x, y, n) +### replace(x, y [, n]) Replaces occurrences of `x` with `y`, `n` times. -If `n` is negative it will replace all occurrencies: +If `n` is omitted, or negative, it will replace all occurrencies: ``` bash "string".replace("i", "o", -1) # "strong" +"aaaa".replace("a", "x") # "xxxx" +"aaaa".replace("a", "x", 2) # "xxaa" ``` You can also replace an array of characters: ``` bash -"string".replace(["i", "g"], "o", -1) # "strono" +"string".replace(["i", "g"], "o") # "strono" ``` ### title() diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go index a1d28328..12df7ef7 100644 --- a/evaluator/evaluator_test.go +++ b/evaluator/evaluator_test.go @@ -895,7 +895,9 @@ c")`, []string{"a", "b", "c"}}, {`[1,2,3].slice(-1, 3)`, []int{3}}, {`[1,2,3].slice(-1, 1)`, []int{3}}, {`"a".replace("a", "b", -1)`, "b"}, + {`"a".replace("a", "b")`, "b"}, {`"ac".replace(["a", "c"], "b", -1)`, "bb"}, + {`"ac".replace(["a", "c"], "b")`, "bb"}, {`"a".str()`, "a"}, {`1.str()`, "1"}, {`[1].str()`, "[1]"}, diff --git a/evaluator/functions.go b/evaluator/functions.go index c336ba1b..f42e9052 100644 --- a/evaluator/functions.go +++ b/evaluator/functions.go @@ -1165,17 +1165,31 @@ func repeatFn(tok token.Token, args ...object.Object) object.Object { return &object.String{Token: tok, Value: strings.Repeat(args[0].(*object.String).Value, int(args[1].(*object.Number).Value))} } +// replace("abd", "d", "c") --> short form // replace("abd", "d", "c", -1) // replace("abc", ["a", "b"], "c", -1) func replaceFn(tok token.Token, args ...object.Object) object.Object { - err := validateArgs(tok, "replace", args, 4, [][]string{{object.STRING_OBJ}, {object.STRING_OBJ, object.ARRAY_OBJ}, {object.STRING_OBJ}, {object.NUMBER_OBJ}}) + var err object.Object + + // Support short form + if len(args) == 3 { + err = validateArgs(tok, "replace", args, 3, [][]string{{object.STRING_OBJ}, {object.STRING_OBJ, object.ARRAY_OBJ}, {object.STRING_OBJ}}) + } else { + err = validateArgs(tok, "replace", args, 4, [][]string{{object.STRING_OBJ}, {object.STRING_OBJ, object.ARRAY_OBJ}, {object.STRING_OBJ}, {object.NUMBER_OBJ}}) + } + if err != nil { return err } original := args[0].(*object.String).Value replacement := args[2].(*object.String).Value - n := int(args[3].(*object.Number).Value) + + n := -1 + + if len(args) == 4 { + n = int(args[3].(*object.Number).Value) + } if characters, ok := args[1].(*object.Array); ok { for _, c := range characters.Elements {