Skip to content

Commit

Permalink
std/misc/string: str
Browse files Browse the repository at this point in the history
  • Loading branch information
Paradiesstaub committed Jun 8, 2020
1 parent e55a9c9 commit 6611134
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 3 deletions.
57 changes: 57 additions & 0 deletions doc/reference/misc.md
Original file line number Diff line number Diff line change
Expand Up @@ -5589,6 +5589,63 @@ characters (`[a-zA-Z0-9_]`). Throws an error if `len` is not a fixnum.
```
:::

### str
``` scheme
(str . xs) -> string
xs := values to be converted and concatenated into a string
```
`str` converts all of its arguments into a single string.
When called without an argument an empty string is returned.

::: tip Examples:
``` scheme
> (str)
""
> (str 2.0)
"2.0"
> (str "hello" ", world")
"hello, world"
> (import :std/format :std/misc/repr)
> (defstruct point (x y))
> (def p (make-point 10 20))
> (defmethod {:pr point}
(lambda (self port options)
(fprintf port "(point ~a ~a)"
(point-x self) (point-y self))))
> (str p 'abc [1 2] 3.4E+2)
"(point 10 20)abc[1 2]340.0"
```
:::

### str-format
``` scheme
(str-format v) -> string
v := any value
```
`str-format` takes any value and returns a formatting string, which can be
used by the `:std/format` family of procedures. Considers the `:pr`
[method](https://cons.io/reference/misc.html#representable) from `:std/misc/repr`.

::: tip Examples:
``` scheme
> (import :std/format)
> (str-format "hello")
"~a" ; default format
> (str-format 1.2E+2)
"~f" ; inexact number
> (str-format (vector 1 2 3))
"~r" ; object which implements the :pr method of :std/misc/repr
```
:::

### line ending variables
``` scheme
(define +cr+ "\r")
Expand Down
23 changes: 21 additions & 2 deletions src/std/misc/string-test.ss
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
(import
:std/misc/string :std/srfi/13
:std/test :gerbil/gambit/exceptions
:std/pregexp)
:std/pregexp :std/misc/repr :std/sugar :std/format)

(def (error-with-message? message)
(lambda (e)
(and (error-exception? e) (equal? (error-exception-message e) message))))

(defstruct point (x y))
(defmethod {:pr point}
(lambda (self port options)
(fprintf port "(point ~a ~a)" (point-x self) (point-y self))))

(def string-test
(test-suite "test :std/misc/string"
(test-case "string-split-suffix"
Expand Down Expand Up @@ -65,4 +70,18 @@
(check-eq? (and (pregexp-match "^\\w+$" (random-string 100)) #t) #t)
(check-equal? (random-string 0) "")
(check-equal? (random-string -1) "")
(check-equal? (string-length (random-string 5)) 5))))
(check-equal? (string-length (random-string 5)) 5))
(test-case "test str"
(check (str) => "")
(check (str "hi") => "hi")
(check (str "hello" ", world.") => "hello, world.")
(check (str 0.1 "!") => "0.1!")
(check (str 2.0) => "2.0")
(check (str 1.2E+2) => "120.0")
(check (str 'abc) => "abc")
(check (str '(1 2)) => "[1 2]")
(check (str (hash (a 10))) => "(hash (a 10))")
(check (str #(1 2)) => "(vector 1 2)")
(check (str (values 1 2)) => "(values 1 2)")
(check (str (make-point 1 2)) => "(point 1 2)"))
))
39 changes: 38 additions & 1 deletion src/std/misc/string.ss
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
string-subst
string-whitespace?
random-string
str str-format
+cr+ +lf+ +crlf+)

(import
(only-in :gerbil/gambit/ports write-substring write-string)
(only-in :gerbil/gambit/random random-integer)
:std/srfi/13)
:std/srfi/13
:std/format
)

;; If the string starts with given prefix, return the end of the string after the prefix.
;; Otherwise, return the entire string. NB: Only remove the prefix once.
Expand Down Expand Up @@ -215,3 +218,37 @@
(string-set! str i (random-word-char)))
str)
""))

;; str converts all of its arguments into a single string.
;; When called without an argument an empty string is returned.
;;
;; Examples:
;; (str 2.0) => "2.0"
;; (str "hello" ", world") => "hello, world"
(def* str
((v) (if (string? v) v
(format (str-format v) v)))
(xs (call-with-output-string
(lambda (port)
(let loop ((rest xs))
(match rest
([v . rest]
(if (string? v)
(write-string v port)
(fprintf port (str-format v) v))
(loop rest))
(else (void))))))))

;; str-format takes any value and returns a formatting string, which can be
;; used by the :std/format family of procedures. Considers the :pr method
;; from :std/misc/repr.
;;
;; Examples:
;; (str-format 5.0) => "~f"
;; (str-format [1 2]) => "~r"
(def (str-format v)
(def (obj-pr? v) (method-ref v ':pr))
(cond
((? (and number? inexact?) v) "~f")
((? (or list? hash-table? vector? ##values? obj-pr?) v) "~r")
(else "~a")))

0 comments on commit 6611134

Please sign in to comment.