anchor.diff:     #:ast
      #:constant-ast #:value
      #:typed-location-ast
  -   #:function-call-ast #:binding #:arguments
  +   #:function-call-ast #:binding #:arguments #:function-location
      #:block-ast #:binding #:body
      #:catch-ast
      #:eval-when-ast
      #:function-ast
  -   #:go-ast
  +   #:go-ast #:tag-ast
      #:if-ast #:test #:then #:else
      #:load-time-value-ast
  -   #:progn-ast #:forms
  -   #:return-from-ast #:form
  +   #:progn-ast #:form-asts
  +   #:return-from-ast #:form #:form-ast
      #:setq-ast
      #:tagbody-ast #:items
      #:the-ast
      #:throw-ast
      #:unwind-protect-ast
  +   #:convert #:convert-compound
  +   #:draw-ast #:id
      ))
   
   (in-package #:sicl-compiler-phase-1)
  
positive.code:   (let ((forms (convert-sequence (cddr form) environment)))
      (make-instance 'catch-ast
        :tag (convert (cadr form) environment)
        :body (make-instance 'progn-ast :forms forms))))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;
  
negative.code: 
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;
  ;;; Convert an ordinary lambda list to compiled form.
  
  ;;; An &optional entry is one of:
  ;;;
  ;;;  * (lexical-location init-form-ast)
  ;;;  * (lexical-location init-form-ast lexical-location)
  ;;;
  ;;; Here, init-form-ast is an AST resulting from the conversion of an
  ;;; initialization form.  In the second variant, the last lexical
  ;;; location is assigned a Boolean value according to whether an
  ;;; optional argument was given.
  ;;;
  ;;; A &key entry is one of:
  ;;;
  ;;;  * ((keyword lexical-location) init-form-ast)
  ;;;  * ((keyword lexical-location) init-form-ast lexical-location)
  ;;;
  ;;; As with the &optional entry, init-form-ast is an AST resulting
  ;;; from the conversion of an initialization form.  In the second
  ;;; variant, the last lexical location is assigned a Boolean value
  ;;; according to whether an optional argument was given.
  ;;; 
  ;;; An &aux entry is of the form:
  ;;;
  ;;;  * (lexical-location init-form-ast)
  
  ;;; FIXME: handle special variables in lambda list. 
  
  (defclass lambda-list ()
    (;; A possibly empty list of lexical locations.
     (%required :initarg :required :reader required)
     ;; A possibly empty list of optional entries. 
     (%optional :initarg :optional :reader optional)
     ;; Either NIL or a single lexical location. 
     (%rest-body :initarg :rest-body :reader rest-body)
     ;; Either:
     ;;  * :none, meaning &key was not given at all,
     ;;  * a possibly empty list of &key entries.
     (%keys :initarg :keys :reader keys)
     ;; Either:
     ;;  * nil, meaning &allow-other-keys was not given at all,
     ;;  * t, meaning &allow-other-keys was given.
     (%allow-other-keys :initarg :allow-other-keys :reader allow-other-keys)
     ;; A possibly empty list of &aux entries.
     (%aux :initarg :aux :reader aux)))
  
  ;;; The main tricky part about converting a lambda list is that any
  ;;; init-form in &optional, &key, or &aux entries may refer to
  ;;; variables in parameter specifiers to the left of the one it
  ;;; appears in.
  ;;;
  ;;; A question (that the HyperSpec does not seem to be addressing as
  ;;; far as I can tell) is whether the lambda list may contain multiple
  ;;; entries of the same symbol.  It kind of makes sense that this
  ;;; would be possible, given what was said in the paragraph above, so
  ;;; a lambda list might be for instance: (x &key (x x)) which would
  ;;; mean that the variable x takes on the value of the :x keyword
  ;;; argument if given, and of the required arguement if no keyword
  ;;; argument was given.  It is probably easier to allow this than to
  ;;; check for it.
  
  ;;; FIXME: for now, we handle only required parameters.
  (defun convert-lambda-list (ordinary-lambda-list env)
    (let* ((required-vars (sicl-code-utilities:required ordinary-lambda-list))
  	 (required-entries
  	   (loop for var in required-vars
  		 collect (sicl-env:make-lexical-variable-entry var)))
  	 (new-env (sicl-env:augment-environment env required-entries)))
      (values
       (make-instance 'lambda-list
  		    :required (mapcar #'sicl-env:location required-entries))
       new-env)))
  
  (defclass code-ast (ast)
    ((%lambda-list :initarg :lambda-list :reader lambda-list)
     (%body-ast :initarg :body-ast :reader body-ast)))
  
  (defun convert-code (lambda-list body env)
    (let* ((parsed-lambda-list
  	   (sicl-code-utilities:parse-ordinary-lambda-list lambda-list)))
      (multiple-value-bind (compiled-lambda-list new-env)
  	(convert-lambda-list parsed-lambda-list env)
        (multiple-value-bind (declarations documentation forms)
  	  (sicl-code-utilities:separate-function-body body)
  	(declare (ignore documentation))
  	(setf new-env
  	      (sicl-env:augment-environment-with-declarations
  	       new-env declarations))
  	(let ((body-asts (convert-sequence forms new-env)))
  	  (make-instance 'code-ast
  			 :lambda-list compiled-lambda-list
  			 :body-ast (make-instance 'progn-ast
  						  :form-asts body-asts)))))))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;
  ;;; Converting BLOCK.
  
  (defclass block-ast (ast)
  