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/private/generate-literals.rkt

55 lines
2.2 KiB
Racket

#lang racket/base
8 years ago
(require "syntax-flatten.rkt")
(provide all-...-follow-wildcards generate-literals)
(define (literal-identifier? pat-datum)
(and (symbol? pat-datum)
(not (memq pat-datum '(... _))) ; isn't a reserved identifier
(let ([pat-str (symbol->string pat-datum)])
(or (not (regexp-match #rx"[A-Z]" pat-str)) ; either doesn't contain at least one uppercase letter ...
(not (equal? (string-upcase pat-str) pat-str)))))) ;... or doesn't contain all uppercase letters
(define (wildcard-identifier? pat-datum)
(and (symbol? pat-datum)
(not (literal-identifier? pat-datum))
(not (memq pat-datum '(... _)))))
8 years ago
;; generate literals for any symbols that are not ... or _ and not IN_CAPS
(define (generate-literals pats)
(for*/list ([pat-arg (in-list (syntax-flatten pats))]
[pat-datum (in-value (syntax->datum pat-arg))]
#:when (literal-identifier? pat-datum))
8 years ago
pat-arg))
(define (all-...-follow-wildcards pats)
(define prev-datum (box #f))
(and
(for*/and ([pat-arg (in-list (syntax-flatten pats))]
[pat-datum (in-value (syntax->datum pat-arg))])
;; OK if there's no previous datum,
(and
(when (eq? pat-datum '...)
(wildcard-identifier? (unbox prev-datum)))
(set-box! prev-datum pat-datum)))
#true))
8 years ago
(module+ test
(require rackunit)
(check-equal? (map syntax->datum (generate-literals #'(foo 42 BAR _ (... ...) bar <=> 3Bar 3bar))) '(foo bar <=> 3Bar 3bar))
(test-case "wildcard-identifier?"
(check-true (wildcard-identifier? 'FOO))
(check-true (wildcard-identifier? 'TOPPING))
(check-false (wildcard-identifier? 'piZZa))
(check-false (wildcard-identifier? 'please)))
(test-case "all-...-follow-wildcards"
(check-true (all-...-follow-wildcards #'()))
(check-true (all-...-follow-wildcards (datum->syntax #f '(a b))))
(check-true (all-...-follow-wildcards (datum->syntax #f '(a b C ...))))
(check-false (all-...-follow-wildcards (datum->syntax #f '(...))))
(check-false (all-...-follow-wildcards (datum->syntax #f '(a ...))))
(check-false (all-...-follow-wildcards (datum->syntax #f '(A ... b ...))))))