EoPL reading (40) 1.3.1 Free and Bound Variables
Exercise.1-32
なんとなく Ex.1-31 の逆で良いカンジをイメージしてるんですがどうなる事やら。
とりあえず lambda 式が変換できるように、という事で例示されているナニを試験に盛り込んでおく。
(use gauche.test) (add-load-path ".") (load "un-lexical-address") (test-start "un-lexical-address") (test-section "un-lexical-address") (test* "(un-lexical-address '(lambda (a) (lambda (b c) ((: 1 0) (: 0 0) (: 0 1))))) should return (lambda (a) (lambda (b c) (a b c)))" '(lambda (a) (lambda (b c) (a b c))) (un-lexical-address '(lambda (a) (lambda (b c) ((: 1 0) (: 0 0) (: 0 1)))))) (test-end)
微妙にハードル高そげ。ガワだけ作った。
(define (un-lexical-address exp) (define (un-lexical-address-inner rslt dict l) (cond ((null? l) rslt) ((symbol? l) ) ((eqv? (car l) 'lambda) ) (else )) ) (un-lexical-address-inner '() '() exp) )
どうしたものやら。
って、基本 symbol は表れない、を前提にしても良いのかな。てーコトはリストの car が : だったら symbol 扱いすりゃ良いのか。
と言いつつ適当にビートたけしが出てくる番組を見つつ (見てないけど)、Ex.1-31 を見ながら手続きをでっちあげたら上記の試験にパス。
(define (un-lexical-address exp) (define (un-lexical-address-inner rslt dict l) (cond ((null? l) rslt) ((eqv? (car l) 'lambda) (un-lexical-address-inner (append rslt `(lambda ,(cadr l))) (cons (cadr l) dict) (cddr l)) ) (else (if (eqv? (car l) ':) (let f ((d 0) (dict dict)) (cond ((null? dict) #f) ((eq? (cadr l) d) (let f-inner ((p 0) (dict (car dict))) (if (eq? (caddr l) p) (car dict) (f-inner (+ p 1) (cdr dict))))) (else (f (+ d 1) (cdr dict))))) (let g ((rslt rslt) (l l)) (if (null? l) rslt (g (append rslt (list (un-lexical-address-inner '() dict (car l)))) (cdr l)))) ) )) ) (un-lexical-address-inner '() '() exp) )
これは違う意味で微妙。試験は足りてないので別途。