-
Notifications
You must be signed in to change notification settings - Fork 0
/
ex-1-32.scm
72 lines (68 loc) · 2.03 KB
/
ex-1-32.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
;; ; TODO: FIND A WAY WITHOUT CALL/CC
;; ; un-lexical-address (expression)
;; ; return expression with lexical addresses (: d p) and (v free)
;; ; replaced by corresponding definitions. Return #f if no such expression
;; ; can be formed.
;; ;
;; ; BNF
;; ; <lex-var> ::= (: <digit> <digit>) | (<identifier> free)
;; ; <lex-expr> ::= <lex-var>
;; ; ::= (if <lex-expr> <lex-expr> <lex-expr>)
;; ; ::= (lambda ({<identifier>}*) <lex-expr>)
;; ; ::= ({<lex-expr>}+)
(define un-lexical-address
(lambda (e)
(un-lexical-address-1 e '())))
(define lexical->symbol
(lambda (e env)
(if (null? env)
#f
(let ((depth (cadr e)) (pos (caddr e)))
(cond ((< (length env) (+ depth 1)) #f)
((< (length (list-ref env depth)) pos) #f)
(else (let ((sym (list-ref (list-ref env depth) pos)))
(if (bound-nearer? sym (- depth 1) env)
#f
sym))))))))
(define bound-nearer?
(lambda (sym distance env)
(if (or (< distance 0) (null? env))
#f
(if (member sym (car env))
#t
(bound-nearer? sym (- distance 1) (cdr env))))))
(define un-lexical-address-1
(lambda (expr env)
(if (null? expr)
'()
(cond
((eqv? (car expr) 'if)
(cons 'if (un-lexical-address-1 (cdr expr) env)))
((eqv? (car expr) 'lambda)
(cons 'lambda
(cons (cadr expr) (un-lexical-address-1 (cddr expr) (cons (cadr expr) env)))))
((eqv? (car expr) ':)
(lexical->symbol expr env))
((symbol? (car expr))
(if (eqv? (cadr expr) 'free)
(car expr)
#f))
(else
(cons (un-lexical-address-1 (car expr) env)
(un-lexical-address-1 (cdr expr) env)))))))
;; (define un-lexical-address-h
;; (lambda (expr env res)
;; (if (null? expr)
;; (res)
;; (cond
;; ((eqv? (car expr) 'if)
;; (un-lexical-address-h (cdr exp) env (cons 'if res)))
;; ((eqv? (car expr) 'lambda)
;; (un-lexical-address-h
;; (cddr exp)
;; (cons (cadr expr) env)
;; (cons 'lambda (cons (cadr expr) res))))
;; ((eqv? (car expr) ':)
;; (let ((sym (lexical->symbol expr)))
;; (if (sym)
;; (un-lexical-address-h '() env