diff --git a/utils-tests.rkt b/utils-tests.rkt index abb1573..acd9677 100644 --- a/utils-tests.rkt +++ b/utils-tests.rkt @@ -29,3 +29,7 @@ (check-equal? (let ([ht #hash((a . 1) (b . 1))]) (eval-with1 ht '(+ b a 1))) 3))) + +(test-case "Analysis of quoted expressions" + (check-equal? (extract-symbols '(1 (2 3) x (y z 3))) + '(x y z))) diff --git a/utils.rkt b/utils.rkt index dda94ee..7e2c998 100644 --- a/utils.rkt +++ b/utils.rkt @@ -7,7 +7,8 @@ (require (for-syntax syntax/parse) (for-syntax racket/list)) -(provide auto-hash-ref/explicit auto-hash-ref/: eval-with eval-with1) +(provide auto-hash-ref/explicit auto-hash-ref/: eval-with eval-with1 + extract-symbols) ;;; =================== ;;; HashTable Injection @@ -109,3 +110,21 @@ (let ([vals (call-with-values (λ () (eval-with ht expr)) (λ vals vals))]) (car vals))) + + +;;; ============================== +;;; Analysis of quoted expressions +;;; ============================== + +;;; Produces a list of symbols appearing in the quoted expression +;;; passed in the first argument. +(: extract-symbols (-> Any (Listof Symbol))) +(define (extract-symbols form) + (cond + [(symbol? form) + (list (cast form Symbol))] + [(list? form) + (cast (flatten (for/list : (Listof (Listof Symbol)) + ([x (cast form (Listof Any))]) + (extract-symbols x))) (Listof Symbol))] + [else '()]))