From 955540d6a0452c14d476bc166970024555c13b79 Mon Sep 17 00:00:00 2001 From: Stefan Israelsson Tampe Date: Fri, 22 Sep 2017 21:40:04 +0200 Subject: strings now sully supported --- modules/language/python/string.scm | 202 ++++++++++++++++++++++++++++++++++--- 1 file changed, 186 insertions(+), 16 deletions(-) (limited to 'modules/language/python/string.scm') diff --git a/modules/language/python/string.scm b/modules/language/python/string.scm index 96b97f3..d15ca23 100644 --- a/modules/language/python/string.scm +++ b/modules/language/python/string.scm @@ -9,7 +9,11 @@ py-isalnum py-isalpha py-isdigit py-islower py-isspace py-isupper py-istitle py-join py-ljust py-rljust py-lower py-upper py-lstrip py-rstrip - py-partition py-replace py-strip py-title)) + py-partition py-replace py-strip py-title + py-rpartitio py-rindex py-split py-rsplit py-splitlines + py-startswith py-swapcase py-translate py-zfill)) + +(define None 'None) (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y))) @@ -18,8 +22,20 @@ (define-method (f (o ) . u) code ...) (define-method (f (o

) . l) (apply (ref o 'n) l)))) -(define-py (py-capitalize capitalize o) - (string-capitalize o)) +(define-py (py-capitalize capitalize s) + (let* ((n (len s)) + (w (make-string n))) + (let lp ((i 0) (first? #t)) + (if (< i n) + (let ((ch (string-ref s i))) + (if (and first? (char-alphabetic? ch)) + (begin + (string-set! w i (char-upcase ch)) + (lp (+ i 1) #f)) + (begin + (string-set! w i ch) + (lp (+ i 1) first?)))) + w)))) (define-py (py-center center o w . l) (let* ((ws (if (pair? l) @@ -55,6 +71,18 @@ (lambda (start end) (string-suffix? suff o 0 ns start end))))) +(define-py (py-startswith endswith o (suff ) . l) + (let* ((n (string-length o)) + (ns (string-length suff)) + (f (lambda (x) (< x 0) (+ n x) x))) + (call-with-values (lambda () + (match l + (() (values 0 n )) + ((x) (values (f x) n )) + ((x y) (values (f x) (f y))))) + (lambda (start end) + (string-prefix? suff o 0 ns start end))))) + (define-py (py-expandtabs expandtabs s . l) (let* ((tabsize (match l (() 8) ((x) x))) (u (string->list (make-string tabsize #\space))) @@ -113,7 +141,7 @@ (((#:i x) . l) (lp l (cons "~a" r) (cons (list-ref args (string->number x)) u) i)) (((#:s x) . l) - (lp l (cons "~a" r) (cons (hash-ref kwargs x 'None) u) i)) + (lp l (cons "~a" r) (cons (hash-ref kwargs x None) u) i)) (((#:e) . l) (lp l (cons "~a" r) (cons (list-ref args i) u) (+ i 1))) (() @@ -255,6 +283,31 @@ (list (pylist-slice s 0 i) sep (pylist-slice s (+ i m) n)) (lp (+ i 1))) (list s "" ""))))) + +(define-py (py-rpartition rpartition ss (ssep )) + (let* ((s (string-reverse ss)) + (sep (string-reverse ssep)) + (n (len s)) + (m (len sep))) + (define (test i) + (let lp ((i i) (j 0)) + (if (< i n) + (if (< j m) + (if (eq? (string-ref s i) (string-ref sep j)) + (lp (+ i 1) (+ j 1)) + #f) + #t) + #f))) + (let lp ((i 0)) + (if (< i n) + (if (test i) + (list (string-reverse + (pylist-slice s (+ i m) n)) + ssep + (string-reverse + (pylist-slice s 0 i))) + (lp (+ i 1))) + (list "" "" s))))) (define-py (py-replace replace s old new . l) (let ((n (match l (() #f) ((n . _) n)))) @@ -270,19 +323,136 @@ (define-py (py-strip strip s . l) (apply py-rstrip (apply py-lstrip s l) l)) -(define-py (py-title title s) (string-titlecase s)) +(define-py (py-title title s) + (string-titlecase s)) + +(define-py (py-rindex rindex s . l) + (let ((n (len s))) + (- n (apply pylist-index (string-reverse s) l) 1))) + + -#| -py-rindex -py-rpartition +(define-py (py-split split s . l) + (define ws (f+ (f-reg "[ \t\n]"))) + (define r + (f-or! (f-seq f-eof (f-out '())) + (f-cons (f-seq (mk-token (f* (f-reg! "."))) f-eof) (f-out '())))) + (define (u ws) (mk-token (f+ (f-not! ws)))) + (define (tok ws i) + (if (= i 0) + (f-list (mk-token (f* (f-reg! ".")))) + (let ((e (mk-token (f* (f-not! ws))))) + (f-seq (f? ws) + (f-cons e + (let lp ((i i)) + (if (> (- i 1) 0) + (f-or! (f-seq (f? ws) f-eof (f-out '())) + (f-cons (f-seq ws e) (Ds (lp (- i 1))))) + r))))))) + + (define N 1000000000000) + (let ((e (call-with-values + (lambda () + (match l + (() (values ws N)) + ((sep) (values (f-tag sep) N)) + ((sep n) (values (f-tag sep) n)))) + tok))) + (parse s e))) -py-rsplit -py-split -py-splitlines +(define-py (py-rsplit rsplit s . l) + (reverse + (map string-reverse + (apply py-split + (string-reverse s) + (match l + (() '()) + ((sep . l) (cons (string-reverse sep) l))))))) -py-startswith -py-swapcase -py-translate -py-zfill -|# +(define-py (py-splitlines splitlines s . l) + (let ((n (len s)) + (keep? (match l + ((#:keepends v) + v) + ((v) + v) + (_ #f)))) + (let lp ((i 0) (r '()) (old 0)) + (if (< i n) + (let ((ch (string-ref s i))) + (if (eq? ch #\newline) + (if keep? + (lp (+ i 1) + (cons + (pylist-slice s old (+ i 1) 1) + r) + (+ i 1)) + (lp (+ i 1) + (cons + (pylist-slice s old i 1) + r) + (+ i 1))) + (lp (+ i 1) r old))) + (reverse r))))) + +(define-py (py-swapcase swapcase s) + (list->string + (string-fold + (lambda (ch s) + (cons + (cond + ((char-upper-case? ch) + (char-downcase ch)) + ((char-lower-case? ch) + (char-upcase ch)) + (else ch)) + s)) + '() + s))) + +(define-py (py-translate translate s table . l) + (let* ((n (len s)) + (w (make-string n)) + (t (if (eq? table None) #f table)) + (d (match l (() #f) ((x) x)))) + + (define (tr ch) + (if d + (if (string-contains d (list->string (list ch))) + #f + (if t + (let ((i (char->integer ch))) + (if (< i n) + (string-ref t i) + ch)) + ch)))) + + (let lp ((i 0) (k 0)) + (if (< i n) + (let ((ch (tr (string-ref s i)))) + (if ch + (begin + (string-set! w k ch) + (lp (+ i 1) (+ k 1))) + (lp (+ i 1) k))) + (if (= k n) + w + (pylist-slice w 0 k 1)))))) + +(define-py (py-zfill zfill s width) + (let* ((n (len s)) + (w (pk (pylist-slice s 0 n 1)))) + (let lp ((i 0)) + (if (< i n) + (let ((ch (string-ref s i))) + (if (char-numeric? ch) + (let lp ((j (max 0 (- i width)))) + (pk i j) + (if (< j i) + (begin + (string-set! w j #\0) + (lp (+ j 1))) + w)) + (lp (+ i 1)))) + s)))) -- cgit v1.2.3