; Brian Alliet ; Programming Language Theory ; 4005-710-01 (define (lexical-address expr) (call-with-current-continuation (lambda (return) (lexical-address-helper (lambda () (return #f)) 0 '() expr)))) (define (lexical-address-helper fail depth env expr) (match expr ((list 'lambda args body) (list 'lambda args (lexical-address-helper fail (+ depth 1) (append (zip (lambda (a p) (cons a (cons depth p))) args (from-to 0 (- (length args) 1))) env) body))) ((xs @ (cons _ _)) (map (curry lexical-address-helper fail depth env) xs)) (sym (if (symbol? sym) (match (lookup sym env) ((cons a p) (list ': a p)) ('#f (list sym 'free))) (fail))))) (define (un-lexical-address expr) (call-with-current-continuation (lambda (return) (un-lexical-address-helper (lambda () (return #f)) '() expr)))) (define (un-lexical-address-helper fail env expr) (match expr ((list 'lambda args body) (list 'lambda args (un-lexical-address-helper fail (append env (list args)) body))) ((list ': d p) (if (>= d (length env)) (fail) (let ((names (list-ref env d))) (if (>= p (length names)) (fail) (list-ref names p))))) ((list sym 'free) sym) ((xs @ (cons _ _)) (map (curry un-lexical-address-helper fail env ) xs)) (_ (fail))))