HINTS FOR writing the procedure lexical-address: 1. You must use the helpers in lambda-multiple+if.scm to pick apart lambda expressions, and then you must use the helpers in lexical-addr-exp.scm to put them back together. 2. Follow the grammar!! This will be automatic if you use the type checker... IMPORTANT: Because the globally bound (free) variables may have an arbitrary position number, our test cases do not automatically check the result when there is more than one free variable in the expression. Hence, it will be up to *you* to make sure that the free variables have unique position numbers. Check the output of these tests by hand to be sure. 3. Use the `trace' procedure if you are having trouble debugging your program. See $PUB/docs/debugging-scm.txt for more information about `trace'. 4. Test your procedures from the bottom up; i.e., test the procedures that are called by other procedures first. 5. The easiest approach to writing the lexical-address procedure is to write at least two helping procedures. Also, you will likely want to use free-vars-lcm+if as a helper to obtain the free variables. Then the position in the set of free variables (a list) can be used as the unique position number for the lexical address of each free variable. The interfaces for the procedures are as follows: (define lexical-address ;; TYPE: (-> (lcm+if-exp) lexical-addr-exp) (lambda (exp) (lexical-address-helper . . . ))) (define lexical-address-helper ;; TYPE: (-> (lcm+if-exp (list (list symbol)) ) lexical-addr-exp) (lambda (exp var-table) ;; The structure of this procedure should follow the grammar given ;; below for (the same as for problem 6). )) (define lexical-address-of-varref ;; TYPE: (-> (symbol (list (list symbol)) ) lexical-addr) (lambda (var var-table) . . .)) The grammar for : ::= | ( quote ) | ( lambda ( {}* ) ) | ( if ) | ( {}* ) ::= ::= The grammar for lexical address expressions: ::= | (quote ) | (if ) | (lambda ({}*) ) | ( {}*) ::= ( : ) ::= Some examples: (lexical-address-helper (parse-lcm+if-exp 'x) '((p q r x y) (w z x) (car ls)) ) ==> (x : 0 3) (lexical-address-helper (parse-lcm+if-exp 'x) '((a b) (p q r) (x y) (car ls)) ) ==> (x : 2 0) (lexical-address-helper (parse-lcm+if-exp '(car ls)) '((car ls)) ) ==> ((car : 0 0) (ls : 0 1)) (lexical-address-helper (parse-lcm+if-exp '(car ls)) '((ls car)) ) ==> ((car : 0 1) (ls : 0 0)) The next sequence of examples traces what should happen with recursive calls on lambda expressions. Notice the way the list of variable lists (the second argument) changes with each recursive call below. ; Example 1: (lexical-address-helper (parse-lcm+if-exp '(lambda (q r p) (lambda (x y) (if (p u) (h x) (t y))))) '((h t u)) ) ; second argument with free vars ; Note: the list of free variables is a member of the list of variable lists ==> (lambda (q r p) (lambda (x y) (if ((p : 1 2) (u : 2 2)) ((h : 2 0) (x : 0 0)) ((t : 2 1) (y : 0 1))))) ; Example 2: (lexical-address-helper (parse-lcm+if-exp '(lambda (x y) (if (p u) (h x) (t y))) '((q r p) (h t u)) ) ; second argument ==> (lambda (x y) (if ((p : 1 2) (u : 2 2)) ((h : 2 0) (x : 0 0)) ((t : 2 1) (y : 0 1)))) ; Example 3: (lexical-address-helper (parse-lcm+if-exp '(if (p u) (h x) (t y)) '((x y) (q r p) (h t u)) ) ; second argument ==> (if ((p : 1 2) (u : 2 2)) ((h : 2 0) (x : 0 0)) ((t : 2 1) (y : 0 1))) Related examples for lexical-address-varref: (lexical-address-varref 'p '((x y) (q r p) (h t u)) ) ==> (p : 1 2) (lexical-address-varref 'y '((x y) (q r p) (h t u)) ) ==> (y : 0 1) (lexical-address-varref 'u '((x y) (q r p) (h t u)) ) ==> (u : 2 2) (lexical-address-varref 't '((x y) (q r p) (h t u)) ) ==> (t : 2 1)