2021-04-21 15:12:05 +02:00
|
|
|
(load "util.scm")
|
2021-04-21 16:02:02 +02:00
|
|
|
(load "misc/sicp-compiler-lexical-addressing.scm")
|
2021-04-21 15:12:05 +02:00
|
|
|
|
2021-04-21 16:02:02 +02:00
|
|
|
(display "\nex-5.39 - lexical-addressing\n")
|
|
|
|
|
|
|
|
; Exercise 5.39. Write a procedure lexical-address-lookup that implements the
|
|
|
|
; new lookup operation. It should take two arguments -- a lexical address and a
|
|
|
|
; run-time environment -- and return the value of the variable stored at the
|
|
|
|
; specified lexical address. Lexical-address-lookup should signal an error if
|
|
|
|
; the value of the variable is the symbol *unassigned*.46 Also write a
|
|
|
|
; procedure lexical-address-set! that implements the operation that changes the
|
|
|
|
; value of the variable at a specified lexical address.
|
|
|
|
|
|
|
|
(define (make-address frame-number index-number)
|
|
|
|
(list 'address frame-number index-number))
|
|
|
|
(define (frame-number address) (cadr address))
|
|
|
|
(define (index-number address) (caddr address))
|
|
|
|
|
|
|
|
(define test-env '((1 2 3) (4 5 6) (7 8 9)))
|
|
|
|
|
|
|
|
(define (lexical-address-lookup adr env)
|
|
|
|
(define (iter-env frame-number env)
|
|
|
|
(cond
|
|
|
|
((null? env)
|
|
|
|
(error "frame does not exist - LEXICAL-ADDRESS-LOOKUP" adr env))
|
|
|
|
((= frame-number 0) (car env))
|
|
|
|
(else (iter-env (- frame-number 1) (cdr env)))))
|
|
|
|
(define (iter-frame index-number frame)
|
|
|
|
(cond
|
|
|
|
((null? frame)
|
|
|
|
(error "index does not exist - LEXICAL-ADDRESS-LOOKUP" adr env))
|
|
|
|
((and (= index-number 0) (eq? (car frame) '*unassigned*))
|
|
|
|
(error "var not assigned - LEXICAL-ADDRESS-LOOKUP" adr env))
|
|
|
|
((= index-number 0) (car frame))
|
|
|
|
(else (iter-frame (- index-number 1) (cdr frame)))))
|
|
|
|
(let ((frame (iter-env (frame-number adr) env)))
|
|
|
|
(iter-frame (index-number adr) frame)))
|
|
|
|
|
|
|
|
(assert (lexical-address-lookup (make-address 0 0) test-env) 1)
|
|
|
|
(assert (lexical-address-lookup (make-address 0 1) test-env) 2)
|
|
|
|
(assert (lexical-address-lookup (make-address 0 2) test-env) 3)
|
|
|
|
(assert (lexical-address-lookup (make-address 1 0) test-env) 4)
|
|
|
|
(assert (lexical-address-lookup (make-address 2 2) test-env) 9)
|
|
|
|
|
|
|
|
; (define (env-loop env)
|
|
|
|
; (define (scan vars vals)
|
|
|
|
; (cond ((null? vars)
|
|
|
|
; (env-loop (enclosing-environment env)))
|
|
|
|
; ((eq? var (car vars))
|
|
|
|
; (car vals))
|
|
|
|
; (else (scan (cdr vars) (cdr vals)))))
|
|
|
|
; (if (eq? env the-empty-environment)
|
|
|
|
; 'unbound-variable-error
|
|
|
|
; (let ((frame (first-frame env)))
|
|
|
|
; (scan (frame-variables frame)
|
|
|
|
; (frame-values frame)))))
|
|
|
|
; (env-loop env))
|
|
|
|
|
|
|
|
;(define (unbound-variable? var)
|
|
|
|
; (eq? var 'unbound-variable-error))
|
|
|
|
|
|
|
|
(define (lexical-address-set! adr val env) '())
|
|
|
|
|
|
|
|
; (define (env-loop env)
|
|
|
|
; (define (scan vars vals)
|
|
|
|
; (cond ((null? vars)
|
|
|
|
; (env-loop (enclosing-environment env)))
|
|
|
|
; ((eq? var (car vars))
|
|
|
|
; (set-car! vals val))
|
|
|
|
; (else (scan (cdr vars) (cdr vals)))))
|
|
|
|
; (if (eq? env the-empty-environment)
|
|
|
|
; (error "Unbound variable -- SET!" var)
|
|
|
|
; (let ((frame (first-frame env)))
|
|
|
|
; (scan (frame-variables frame)
|
|
|
|
; (frame-values frame)))))
|
|
|
|
; (env-loop env))
|
2021-04-21 15:12:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
(display "\nex-5.40\n")
|
|
|
|
|
2021-04-21 16:02:02 +02:00
|
|
|
;(compile-to-file
|
|
|
|
; '(let ((x 3) (y 4))
|
|
|
|
; (lambda (a b c d e)
|
|
|
|
; (let ((y (* a b x))
|
|
|
|
; (z (+ c d x)))
|
|
|
|
; (* x y z))))
|
|
|
|
; 'val 'next "f-lexaddr.scm")
|
2021-04-21 15:12:05 +02:00
|
|
|
|
|
|
|
; (display "\nex-5.41\n")
|
|
|
|
; (display "\nex-5.42\n")
|
|
|
|
|