You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
beautiful-racket/beautiful-racket-lib/br/datum.rkt

45 lines
1.8 KiB
Racket

#lang racket/base
(require (for-syntax racket/base br/syntax) br/define)
(provide (except-out (all-defined-out) string->datum))
(define (blank? str)
(or (zero? (string-length str))
(andmap char-blank? (string->list str))))
;; read "foo bar" the same way as "(foo bar)"
;; otherwise "bar" is dropped, which is too astonishing
(define (string->datum str)
(if (blank? str)
(void)
(let ([result (read (open-input-string (format "(~a)" str)))])
(if (= (length result) 1)
(car result)
result))))
(define (datum? x)
(or (list? x) (symbol? x)))
(define (format-datum datum-template . args)
(string->datum (apply format (format "~a" datum-template) (map (λ(arg) (if (syntax? arg)
(syntax->datum arg)
arg)) args))))
;; todo: rephrase errors from `format` or `map` in terms of `format-datums`
(define (format-datums datum-template . argss)
(apply map (λ args (apply format-datum datum-template args)) argss))
(module+ test
(require rackunit syntax/datum)
(check-equal? (string->datum "foo") 'foo)
(check-equal? (string->datum "(foo bar)") '(foo bar))
(check-equal? (string->datum "foo bar") '(foo bar))
(check-equal? (string->datum "42") 42)
(check-equal? (format-datum '(~a-bar-~a) "foo" "zam") '(foo-bar-zam))
(check-equal? (format-datum '(~a-bar-~a) #'foo #'zam) '(foo-bar-zam))
(check-equal? (format-datum (datum (~a-bar-~a)) "foo" "zam") '(foo-bar-zam))
(check-equal? (format-datum '~a "foo") 'foo)
(check-equal? (format-datum '~a "foo") 'foo)
(check-equal? (format-datum '~a "") (void))
(check-equal? (format-datum '~a " ") (void))
(check-equal? (format-datums '(put ~a) '("foo" "zam")) '((put foo) (put zam))))