(module mutated-vars mzscheme
(require-for-template mzscheme)
(require (lib "boundmap.ss" "syntax")
(lib "kerncase.ss" "syntax")
(lib "trace.ss"))
(define table (make-module-identifier-mapping))
(define (find-mutated-vars form)
(define (fmv/list lstx)
(for-each find-mutated-vars (syntax->list lstx)))
(kernel-syntax-case* form #f (define-type-alias-internal define-typed-struct-internal require/typed-internal)
[(set! v e)
(begin
(module-identifier-mapping-put! table #'v #t))]
[(define-values (var ...) expr)
(find-mutated-vars #'expr)]
[(#%app . rest) (fmv/list #'rest)]
[(begin . rest) (fmv/list #'rest)]
[(begin0 . rest) (fmv/list #'rest)]
[(lambda _ . rest) (fmv/list #'rest)]
[(case-lambda (_ . rest) ...) (for-each fmv/list (syntax->list #'(rest ...)))]
[(if e1 e2) (begin (find-mutated-vars #'e1) (find-mutated-vars #'e2))]
[(if e1 e2 e3) (begin (find-mutated-vars #'e1) (find-mutated-vars #'e1) (find-mutated-vars #'e3))]
[(with-continuation-mark e1 e2 e3) (begin (find-mutated-vars #'e1)
(find-mutated-vars #'e1)
(find-mutated-vars #'e3))]
[(let-values ([_ e] ...) . b) (begin (fmv/list #'(e ...))
(fmv/list #'b))]
[(letrec-values ([_ e] ...) . b) (begin (fmv/list #'(e ...))
(fmv/list #'b))]
[_ (void)]))
(define (is-var-mutated? id) (module-identifier-mapping-get table id (lambda _ #f)))
(provide find-mutated-vars is-var-mutated?)
)