CS217 Day 4 Monday, April 3, 2000

Scoping and Binding of Variables
We can use depth-pos to write lex-add which returns the lexical address of a Scheme datum relative to given nested declarations. E.g.,
;; (lex-add exp vlsts) => lexical address of exp relative to vlsts.
;; [exp] ::= [symbol] | (lambda [varlist] [exp]) | ({[exp]}+)

(define lex-add
  (lambda (exp vlsts)
    (cond ((symbol? exp)
	   (cons exp (depth-pos exp vlsts 0)))
	  ((eqv? (car exp) 'lambda)
	   (let ((formals (cadr exp))
		 (body (caddr exp)))
	     (list
	       'lambda
	       formals
	       (lex-add body (cons formals vlsts)))))
	  (else
	    (map (lambda (e)
		   (lex-add e vlsts))
	      exp)))))

;; Examples of lex-add

(lex-add '(x y z) '((x) (x y)))

(lex-add '((lambda (x y)
	     ((lambda (y z)
		(x y z w))
	      (x y z w)))
	   (x y z w))
  '())
  • Scheme code: cs217d4.scm
  • Formal Syntax for Scheme expressions (From R5RS, 7.1.3)
    [expression] ::= [variable] | [literal] | [procedure call]
                    | [lambda expression] | [conditional] | [assignment]
                    | [derived expression] | [macro use] | [macro block]
    
    [literal] ::= [quotation] | [self-evaluating]
    
    [self-evaluating] ::= [boolean] | [number] | [character] | [string]
    
    [quotation] ::= '[datum] | (quote [datum])
    
    [procedure call] ::= ([operator] [operand]*)
    
    [operator] ::= [expression]
    
    [operand] ::= [expression]
    
    [lambda expression] ::= (lambda [formals] [body])
    
    [formals] ::= ([variable]*) | [variable] | ([variable]+ . [variable])
    
    [body] ::= [definition]* [sequence]
    
    [sequence] ::= [command]* [expression]
    
    [command] ::= [expression]
    
    [conditional] ::= (if [test] [consequent] [alternate])
    
    [test] ::= [expression]
    
    [consequent] ::= [expression]
    
    [alternate] ::= [expression] | [empty]
    
    [assignment] ::= (set! [variable] [expression])
    
    [derived expression] ::=
           (cond [cond clause]+)
         | (cond [cond clause]* (else [sequence]))
         | (case [expression]
             [case clause]+)
         | (case [expression]
             [case clause]*
             (else [sequence]))
         | (and [test]*)
         | (or [test]*)
         | (let ([binding spec]*) [body])
         | (let [variable] ([binding spec]*) [body])
         | (let* ([binding spec]*) [body])
         | (letrec ([binding spec]*) [body])
         | (begin [sequence])
         | (do ([iteration spec]*)
               ([test] [do result])
             [command]*)
         | (delay [expression])
         | [quasiquotation]
    
    [cond clause] ::= ([test] [sequence])
                     | ([test])
                     | ([test] =] [recipient])
    
    [recipient] ::= [expression]
    
    [case clause] ::= (([datum]*) [sequence])
    
    [binding spec] ::= ([variable] [expression])
    
    [iteration spec] ::= ([variable] [init] [step]) | ([variable] [init])
    
    [init] ::= [expression]
    
    [step] ::= [expression]
    
    [do result] ::= [sequence] | [empty]
    
    [macro use] ::= ([keyword] [datum]*)
    
    [keyword] ::= [identifier]
    
    [macro block] ::= (let-syntax ([syntax spec]*) [body])
                     | (letrec-syntax ([syntax spec]*) [body])
    
    [syntax spec] ::= ([keyword] [transformer spec])