#lang s-exp "../lang.ss"
(require "anormal-frag-helpers.ss")
(require "../rbtree.ss")
(require "../../collects/moby/runtime/stx.ss")
(define def-prepend "d~a_~a")
(define arg-prepend "a_~a")
(define struct-prepend "s~a_~a")
(define (symbol< x y)
(string<? (symbol->string x)
(symbol->string y)))
(define (get-id-tree expr base-tree)
(if (not (cons? expr))
base-tree
(cond
[(equal? (first expr) 'define-struct)
(let* ([orig-procs (get-struct-procs expr)]
[new-name (string->symbol (format struct-prepend
(gensym)
(second expr)))]
[new-procs (get-struct-procs (list 'define-struct
new-name
(third expr)))])
(foldl (lambda (old-proc new-proc a-tree)
(rbtree-insert symbol< a-tree old-proc new-proc))
(rbtree-insert symbol< base-tree (second expr) new-name)
orig-procs
new-procs))]
[(equal? (first expr) 'define)
(let ([name (if (cons? (second expr))
(first (second expr))
(second expr))])
(rbtree-insert symbol< base-tree name
(string->symbol (format def-prepend (gensym) name))))]
[else base-tree])))
(define (replace-ids expr replacements)
(cond
[(symbol? (stx-e expr)) (if (false? (rbtree-lookup symbol<
replacements
(stx-e expr)))
expr
(datum->stx false
(second (rbtree-lookup symbol<
replacements
(stx-e expr)))
(stx-loc expr)))]
[(stx:list? expr)
(let* ([expr-list (stx-e expr)]
[first-elt (stx-e (first expr-list))])
(cond
[(or (equal? first-elt 'define)
(equal? first-elt 'lambda))
(let* ([new-args (if (equal? first-elt 'lambda)
(stx->datum (second expr-list))
(if (stx:list? (second expr-list))
(rest (stx->datum (second expr-list)))
empty))]
[new-replacements (foldl (lambda (symb a-tree)
(rbtree-insert symbol<
a-tree
symb
(string->symbol
(format arg-prepend
symb))))
replacements
new-args)])
(datum->stx false
(list (first expr-list)
(replace-ids (second expr-list) new-replacements)
(replace-ids (third expr-list) new-replacements))
(stx-loc expr)))]
[(equal? first-elt 'local)
(let ([new-replacements (foldl get-id-tree
replacements
(stx->datum (second expr-list)))])
(datum->stx false
(list (first expr-list)
(replace-ids (second expr-list) new-replacements)
(replace-ids (third expr-list) new-replacements))
(stx-loc expr)))]
[(equal? first-elt 'define-struct)
(datum->stx false
(list (first expr-list)
(replace-ids (second expr-list) replacements)
(third expr-list))
(stx-loc expr))]
[(or (equal? first-elt 'quote)
(equal? first-elt 'require))
expr]
[else (datum->stx false
(map (lambda (an-expr)
(replace-ids an-expr replacements))
expr-list)
(stx-loc expr))]))]
[else expr]))
(define (munge-identifiers expr)
(begin
(reset-gensym)
(replace-ids expr (foldl get-id-tree empty-rbtree (stx->datum expr)))))
(provide/contract [munge-identifiers (stx:list? . -> . stx:list?)])