home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / t3_1 / sources.lha / sources / comp / front_end / nodestuff.t < prev    next >
Encoding:
Text File  |  1988-02-05  |  21.9 KB  |  617 lines

  1. (herald (front_end nodestuff)
  2.   (env t (orbit_top defs)))
  3.  
  4. ;;; Copyright (c) 1985 Yale University
  5. ;;;     Authors: N Adams, R Kelsey, D Kranz, J Philbin, J Rees.
  6. ;;; This material was developed by the T Project at the Yale University Computer 
  7. ;;; Science Department.  Permission to copy this software, to redistribute it, 
  8. ;;; and to use it for any purpose is granted, subject to the following restric-
  9. ;;; tions and understandings.
  10. ;;; 1. Any copy made of this software must include this copyright notice in full.
  11. ;;; 2. Users of this software agree to make their best efforts (a) to return
  12. ;;;    to the T Project at Yale any improvements or extensions that they make,
  13. ;;;    so that these may be included in future releases; and (b) to inform
  14. ;;;    the T Project of noteworthy uses of this software.
  15. ;;; 3. All materials developed as a consequence of the use of this software
  16. ;;;    shall duly acknowledge such use, in accordance with the usual standards
  17. ;;;    of acknowledging credit in academic research.
  18. ;;; 4. Yale has made no warrantee or representation that the operation of
  19. ;;;    this software will be error-free, and Yale is under no obligation to
  20. ;;;    provide any services, by way of maintenance, update, or otherwise.
  21. ;;; 5. In conjunction with products arising from the use of this material,
  22. ;;;    there shall be no use of the name of the Yale University nor of any
  23. ;;;    adaptation thereof in any advertising, promotional, or sales literature
  24. ;;;    without prior written consent from Yale in each case.
  25. ;;;
  26.  
  27. ;;;============================================================================
  28. ;;; MISCELLANEOUS NODE-TREE AND DEFINITION UTILITES
  29. ;;;============================================================================
  30.  
  31. ;;; Useful utility, not used by any code
  32.  
  33. (define (node-base node)
  34.   (do ((p node (node-parent p)))
  35.       ((not (node? (node-parent p)))
  36.        p)))
  37.  
  38. ;;; Get the type, if any, associated with NODE.
  39.  
  40. (define (any-known-type node)
  41.   (cond ((not (reference-node? node))
  42.          (get-node-definition-type node))
  43.         (else
  44.          (let* ((var (reference-variable node))
  45.                 (binder (variable-binder var)))
  46.            (cond ((get-variable-definition var)
  47.                   => (lambda (def)
  48.                        (get-definition-type def node)))
  49.                  ((not binder)
  50.                   nil)
  51.                  ((eq? var (lambda-rest-var binder))
  52.                   'literal)
  53.                  ((eq? call-proc (node-role binder))
  54.                   (any-known-type ((call-arg (fx+ -1 (variable-number var)))
  55.                                    (node-parent binder))))
  56.                  (else nil))))))
  57.  
  58. (define (get-definition-type def node)
  59.   (cond ((definition->primop def)
  60.          => (lambda (p)
  61.               (fix-primop-type (primop.type p node))))
  62.         ((definition-type def)
  63.          => identity)
  64.         (else
  65.          nil)))
  66.  
  67. ;;; Get the 'real' value of NODE, i.e. the definition value if NODE is a
  68. ;;; variable reference.
  69.  
  70. (define (known-value node)
  71.   (cond ((and (reference-node? node)
  72.               (get-variable-definition (reference-variable node)))
  73.          => definition-value)
  74.         (else node)))
  75.  
  76. ;;; The same as KNOWN-VALUE except that it only returns primops.
  77.  
  78. (define (known-primop node)
  79.   (cond ((primop-node? node)
  80.          (primop-value node))
  81.         ((and (reference-node? node)
  82.               (get-variable-definition (reference-variable node)))
  83.          => definition->primop)
  84.         (else nil)))
  85.  
  86. ;;; The same as KNOWN-VALUE except that it checks for objects and returns the
  87. ;;; whole definition instead of just the value.
  88.  
  89. (define (known-object-definition node)
  90.   (cond ((and (reference-node? node)
  91.               (get-variable-definition (reference-variable node)))
  92.          => (lambda (def)
  93.               (if (definition->object def) def nil)))
  94.         (else nil)))
  95.  
  96. ;;; Are all references to VAR in call position?
  97.  
  98. (define (all-refs-are-calls? var)               
  99.   (every? (lambda (ref)
  100.             (eq? (node-role ref) call-proc))
  101.           (variable-refs var)))
  102.  
  103. ;;; Returns T if REF is being referred to as an L-value.
  104.  
  105. (define (nonvalue-reference? ref)
  106.   (and (eq? (node-role ref) (call-arg 2))
  107.        (primop-node? (call-proc (node-parent ref)))
  108.        (primop.uses-L-value? (primop-value (call-proc (node-parent ref))))))
  109.  
  110. ;;; Walk (or map) a tree modifying procedure down a variable's references.
  111.  
  112. (define (walk-refs-safely proc var)
  113.   (let ((refs (free-copy-list (variable-refs var))))
  114.     (walk proc refs)
  115.     (return-list-to-freelist refs)
  116.     (return)))
  117.  
  118. (define (map-refs-safely proc var)
  119.   (let* ((refs (free-copy-list (variable-refs var)))
  120.          (res (map proc refs)))
  121.     (return-list-to-freelist refs)
  122.     res))
  123.  
  124. ;;; The value a thunk will return when it is called.
  125.  
  126. (define (thunk-value l-node)
  127.   (let ((refs (variable-refs (lambda-cont-var l-node))))
  128.     (cond ((or (fxn= 1 (length refs))
  129.                (neq? call-proc (node-role (car refs))))
  130.            nil)
  131.           ((fxn= 1 (length (call-args (node-parent (car refs)))))
  132.            (bug "thunk returns multiple values"))
  133.           (else   
  134.            ((call-arg 1) (node-parent (car refs)))))))
  135.  
  136. ;;; Does THUNK just return a lambda or object node?
  137.  
  138. (define (simple-thunk? thunk)
  139.   (let ((node (thunk-value thunk)))
  140.     (and (node? node)
  141.          (eq? (node-parent (node-parent node)) thunk)
  142.          (or (lambda-node? node)
  143.              (object-node? node)))))
  144.  
  145. ;;; Replaces the call node CALL with VALUE.
  146. ;;; (<proc> <exit> . <args>) => (<exit> <value>)
  147.  
  148. (define (replace-call-with-value call value)
  149.   (cond ((fxn= 1 (call-exits call))
  150.          (bug "can only substitute for call with one exit ~S" call))
  151.         (else
  152.          (let ((cont (detach ((call-arg 1) call))))
  153.            (walk (lambda (node)
  154.                    (if (node? node)
  155.                        (erase-all (detach node))))
  156.                  (cdr (call-args call)))
  157.            (set (call-exits call) 0)
  158.            (replace (call-proc call) cont)
  159.            (relate-new-call-args call (if value `(,value) '()))))))
  160.  
  161. ;;;=============================================================================
  162. ;;;                             Child Variables
  163. ;;;=============================================================================
  164.  
  165. ;;; These are used as aliases for global variables.  They typically have
  166. ;;; slightly different declaration information than their parents.
  167.  
  168. (lset *child-vars* '())
  169.  
  170. (define (remove-child-vars)
  171.   (walk (lambda (v)
  172.           (cond ((get-child-variable v 'parent)
  173.                  => (lambda (p)
  174.                       (walk-refs-safely (lambda (n)
  175.                                           (set (reference-variable n) p))
  176.                                         v)
  177.                       (modify (variable-refs p)
  178.                               (lambda (l) (append! (variable-refs v) l)))))
  179.                 (else
  180.                  (bug "child-variable ~S has no parent"))))
  181.         *child-vars*)
  182.   (set *child-vars* '()))
  183.  
  184. (define (get-child-variable var type)
  185.   (iterate loop ((l (variable-flags var)))
  186.     (cond ((null? l)
  187.            nil)
  188.           ((and (pair? (car l))
  189.                 (eq? (caar l) type))
  190.            (cdar l))
  191.           (else
  192.            (loop (cdr l))))))
  193.  
  194. (define (add-child-variable parent child type)
  195.   (push *child-vars* child)
  196.   (push (variable-flags parent) (cons type child))
  197.   (push (variable-flags child) (cons 'parent parent))
  198.   (push (variable-flags child) (cons 'type type)))
  199.  
  200. ;;;============================================================================
  201. ;;; SUBSTITUTING VALUES FOR VARIABLES
  202. ;;;============================================================================
  203.  
  204. ;;; Substitute VAL for VAR.  If DETACH? is true then VAL should be detached
  205. ;;; and so can be used instead of a copy for the first substitution.
  206.  
  207. (define (substitute var val detach?)
  208.   (let ((refs (variable-refs var)))
  209. ;    (orbit-debug "substituting: ~A := ~A~%" var (pp-cps-2 val))
  210.     (set (variable-refs var) '())
  211.     (if (and (reference-node? val)               ;Keep LET variable names
  212.              (eq? 'v (variable-name (reference-variable val))))
  213.         (set (variable-name (reference-variable val))
  214.              (variable-name var)))
  215.     (cond (refs
  216.            (walk (lambda (ref)
  217.                    (replace ref (copy-node-tree val)))
  218.                  (if detach? (cdr refs) refs))
  219.            (if detach? (replace (car refs) (detach val)))
  220.            (return-list-to-freelist refs))
  221.           (detach?
  222.            (erase-all (detach val))))))
  223.  
  224. ;;; Replace every reference of OLD-VAR in NODE with a reference to NEW-VAR.
  225. ;;; Return T if any change is made.
  226.  
  227. (define (substitute-in-node-tree node old-var new-var)
  228.   (let ((count (length (variable-refs new-var))))
  229.     (substitute-vars-in-node-tree node (list old-var) (list new-var))
  230.     (fxn= count (length (variable-refs new-var)))))
  231.  
  232. ;;; Walk the tree NODE replacing references to variables in OLD-VARS with
  233. ;;; the corresponding variables in NEW-VARS.  Uses VARIABLE-FLAG to mark
  234. ;;; the variables being replaced.
  235.  
  236. (define (substitute-vars-in-node-tree node old-vars new-vars)
  237.   (walk (lambda (old new)
  238.           (if (used? old)
  239.               (set (variable-flag old) new)))
  240.         old-vars new-vars)
  241.   (iterate tree-walk ((node node))
  242.     (cond ((lambda-node? node)
  243.            (walk tree-walk (call-proc+args (lambda-body node))))
  244.           ((call-node? node)
  245.            (walk tree-walk (call-proc+args node)))
  246.           ((object-node? node)
  247.            (walk tree-walk (object-operations node))
  248.            (walk tree-walk (object-methods node))
  249.            (tree-walk (object-proc node)))
  250.           ((and (reference-node? node)
  251.                 (variable-flag (reference-variable node)))
  252.            => (lambda (new)
  253.                 (replace node (create-reference-node new))))))
  254.   (walk (lambda (old) 
  255.           (if (used? old)
  256.               (set (variable-flag old) nil)))
  257.         old-vars))
  258.  
  259. ;;;============================================================================
  260. ;;; COPYING NODE TREES
  261. ;;;============================================================================
  262.  
  263. ;;; Copy the node-tree NODE.  This dispatches on the type of NODE.
  264.  
  265. (define (copy-node-tree node)
  266.   (let ((new (xselect (node-variant node)
  267.                ((leaf-node?)
  268.                 (copy-leaf node))
  269.                ((lambda-node?)
  270.                 (copy-lambda node))
  271.                ((call-node?)
  272.                 (copy-call node))
  273.                ((object-node? node)
  274.                 (copy-object node)))))
  275.      new))
  276.  
  277. ;;; Copying leaves.  Variables which have been copied have the copy in the
  278. ;;; NODE-FLAG field.
  279.  
  280. (define (copy-leaf node)
  281.   (xcase (leaf-variant node)
  282.     ((literal)
  283.      (create-literal-node (literal-value node)))
  284.     ((primop)
  285.      (create-primop-node (primop-value node)))
  286.     ((reference)
  287.      (let ((var (reference-variable node)))
  288.        (cond ((and (variable-binder var)
  289.                    (variable-flag var))
  290.               => create-reference-node)
  291.              (else
  292.               (create-reference-node var)))))))
  293.  
  294. ;;; Copy a lambda node and its variables.  The variables' copies are put in
  295. ;;; their VARIABLE-FLAG while the lambda's body is being copied.
  296.  
  297. (define (copy-lambda node)
  298.   (let* ((vars (free-map (lambda (var)
  299.                            (if var
  300.                                (set (variable-flag var)
  301.                                     (create-variable (variable-name var)))
  302.                                nil))
  303.                          (lambda-rest+variables node)))
  304.          (new-node (create-lambda-node (variable-name (lambda-self-var node))
  305.                                        vars)))
  306.     (relate lambda-body new-node (copy-node-tree (lambda-body node)))
  307.     (walk (lambda (var)
  308.             (if var (set (variable-flag var) nil)))
  309.           (lambda-rest+variables node))
  310.     new-node))
  311.  
  312. (define (copy-call node)
  313.   (let ((new-node (create-call-node (length (call-proc+args node))
  314.                                     (call-exits node))))
  315.     (relate call-proc new-node (copy-node-tree (call-proc node)))
  316.     (relate-call-args new-node (free-map copy-node-tree (call-args node)))
  317.     new-node))
  318.  
  319. (define (copy-object node)
  320.   (let ((new-node (create-object-node (object-operation? node)
  321.                                       (length (object-operations node)))))
  322.     (relate object-proc new-node (copy-node-tree (object-proc node)))
  323.     (relate-object-ops new-node
  324.                       (free-map copy-node-tree (object-operations node)))
  325.     (relate-object-methods new-node
  326.                            (free-map copy-node-tree (object-methods node)))
  327.     new-node))
  328.  
  329. ;;;============================================================================
  330. ;;; STORING NODE TREES IN VECTORS
  331. ;;;============================================================================
  332.  
  333. ;;;    Convert a node into a vector
  334. ;;;
  335. ;;;  primop        => <primop>
  336. ;;;  literal       => QUOTE <literal>
  337. ;;;  reference     => <index of the variable's name in vector> if lexical
  338. ;;;                   LOCALE <variable-name> if not lexical
  339. ;;;                   KNOWN <variable> if this variable was
  340. ;;;                       originally LOCALE but has been statically bound
  341. ;;;  lambda        => LAMBDA #vars <variable names...> <call>
  342. ;;;  call          => <exits> <number of args> <args>
  343. ;;;  object        => (OBJECT <proc> <ops> <methods>) if at top level
  344. ;;;                => INTERNAL-OBJECT <proc> <ops> <methods> if not                                                     
  345.  
  346.  
  347. ;;; This returns a vector if NODE has no free references to lexically bound
  348. ;;; variables, otherwise it returns NIL.  If NODE is an object node the vector
  349. ;;; is actually a list of vectors.  This is done so that the procedure and
  350. ;;; methods may be reconstructed seperately.
  351.  
  352. (define (node->vector node)
  353.   (cond ((object-node? node)
  354.          (list 'object
  355.                (object-operation? node)
  356.                (node->vector (object-proc node))
  357.                (map node->vector (object-operations node))
  358.                (map node->vector (object-methods node))))
  359.         (else
  360.          (let* ((exp-vec (make-infinite-vector 100 false))
  361.                 (vec (cons exp-vec 0))
  362.                 (value (if (real-node->vector node vec)
  363.                            (copy-node-vector exp-vec (cdr vec))
  364.                            nil)))
  365.            (recycle exp-vec)
  366.            value))))
  367.  
  368. ;;; Copies the expanding vector into a normal vector of the appropriate size.
  369.  
  370. (define (copy-node-vector exp-vec size)
  371.   (let ((new (make-vector size)))
  372.     (do ((i 0 (fx+ i 1)))
  373.         ((fx>= i size))
  374.       (set (vref new i) (exp-vec i)))
  375.     new))
  376.  
  377. ;;; Add another element to the vector (which is really a (<vector> . <index>)
  378. ;;; pair) keeping track of the current index.
  379.  
  380. (define-integrable (add-datum vec value)
  381.   (set ((car vec) (cdr vec)) value)
  382.   (set (cdr vec) (fx+ (cdr vec) 1)))
  383.  
  384. ;;; The main dispatch
  385.  
  386. (define (real-node->vector node vec)
  387.   (cond ((primop-node? node)
  388.          (add-datum vec (primop-value node)))
  389.         ((literal-node? node)
  390.          (add-datum vec 'quote)
  391.          (add-datum vec (literal-value node)))
  392.         ((reference-node? node)
  393.          (variable->vector (reference-variable node) vec))
  394.         ((lambda-node? node)
  395.          (lambda->vector node vec))
  396.         ((object-node? node)
  397.          (object->vector node vec))
  398.         (else
  399.          (bug "node->vector got funny node ~S" node))))
  400.  
  401. ;;; VARIABLE-FLAGs are used to mark variables with their position in the
  402. ;;; vector.
  403.  
  404. (define (lambda->vector node vec)
  405.   (add-datum vec 'lambda)
  406.   (add-datum vec (variable-name (lambda-self-var node)))
  407.   (add-datum vec (length (lambda-rest+variables node)))
  408.   (walk (lambda (var)
  409.           (cond (var
  410.                  (set (variable-flag var) (cdr vec))
  411.                  (add-datum vec (variable-name var)))
  412.                 (else
  413.                  (add-datum vec nil))))
  414.         (lambda-rest+variables node))
  415.   (let ((ok? (call-node->vector (lambda-body node) vec)))
  416.     (walk (lambda (var)
  417.             (if var
  418.                 (set (variable-flag var) nil)))
  419.           (lambda-rest+variables node))
  420.     ok?))
  421.  
  422. ;;; Return NIL if the variable is lexically bound and its binder has not
  423. ;;; been written into the vector.
  424.  
  425. (define (variable->vector var vec)
  426.   (cond ((and (variable-binder var)
  427.               (fixnum? (variable-flag var)))
  428.          (add-datum vec (variable-flag var))
  429.          t)
  430.         ((variable-binder var)
  431.          nil)
  432.         (else
  433.          (add-datum vec 'locale)
  434.          (add-datum vec (variable-name var))
  435.          t)))
  436.  
  437. (define (call-node->vector node vec)
  438.   (add-datum vec (call-exits node))
  439.   (add-datum vec (length (call-proc+args node)))
  440.   (node-list->vector (call-proc+args node) vec))
  441.  
  442. (define (object->vector node vec)
  443.   (add-datum vec 'internal-object)
  444.   (add-datum vec (object-operation? node))
  445.   (add-datum vec (length (object-operations node)))
  446.   (and (real-node->vector (object-proc node) vec)
  447.        (node-list->vector (object-operations node) vec)
  448.        (node-list->vector (object-methods node) vec)))
  449.  
  450. ;;; Write the nodes in list NODES into VEC.
  451.  
  452. (define (node-list->vector nodes vec)
  453.   (iterate loop ((children nodes))
  454.     (cond ((null? children)
  455.            t)
  456.           ((real-node->vector (car children) vec)
  457.            (loop (cdr children)))
  458.           (else
  459.            nil))))
  460.  
  461. ;;;============================================================================
  462. ;;; TURNING VECTORS BACK INTO NODES
  463. ;;;============================================================================
  464.  
  465. ;;; Reconstructing nodes requires an environment in addition to the vector.
  466. ;;; Free variables are looked up in the environment.  The vectors and
  467. ;;; environments are usually in definitions.
  468.  
  469. ;;; Get the value of DEF if it is a variable.
  470.  
  471. (define (definition->variable def)
  472.   (vector->variable (definition-value def) (definition-env def)))
  473.  
  474. ;;; Get the value of VECTOR if it is a variable.
  475.  
  476. (define (vector->variable vector env)
  477.   (cond ((not (vector? vector))
  478.          nil)
  479.         (else
  480.          (case (vref vector 0)
  481.            ((locale)
  482.             (obtain-locale-bound-variable (vref vector 1) env))
  483.            ((early-bound)
  484.             (vref vector 1))
  485.            (else nil)))))
  486.  
  487. ;;; The same thing for primops and objects.
  488.  
  489. (define (definition->primop def)
  490.   (let ((vector (definition-value def)))
  491.     (if (and (vector? vector)
  492.              (primop? (vref vector 0)))
  493.         (vref vector 0)
  494.         nil)))
  495.  
  496. (define (definition->object def)
  497.   (let ((vector (definition-value def)))
  498.     (if (and (pair? vector)
  499.              (eq? (car vector) 'object))
  500.         vector
  501.         nil)))
  502.  
  503. ;;; Definitions and vectors are made back into nodes.
  504.  
  505. (define (definition->node def)
  506.   (vector->node (definition-value def) (definition-env def)))
  507.  
  508. (define (vector->node vector env)
  509.   (cond ((vector? vector)
  510.          (real-vector->node (cons vector -1) env))
  511.         ((and (pair? vector)
  512.               (eq? (car vector) 'object))
  513.          (list->object-node (cdr vector) env))
  514.         (else
  515.          (bug "VECTOR->NODE got funny value ~S~%" vector))))
  516.  
  517. ;;; Pop the next thing off of the vector (which is really a (<vector> . <index>)
  518. ;;; pair).
  519.  
  520. (define-integrable (get-datum vec)
  521.   (set (cdr vec) (fx+ (cdr vec) 1))
  522.   (vref (car vec) (cdr vec)))
  523.  
  524. ;;; Vector used to contain any lexical variables required in reconstructing
  525. ;;; a node.
  526.  
  527. (lset *vector->lexical-var*
  528.   (make-infinite-vector 0 false '*vector->lexical-var*))
  529.  
  530. ;;; Dispatch on the next thing in VEC.
  531.  
  532. (define (real-vector->node vec env)
  533.   (let ((exp (get-datum vec)))
  534.     (cond ((primop? exp)
  535.            (create-primop-node exp))
  536.           ((variable? exp)
  537.            (create-reference-node exp))
  538.           ((fixnum? exp)
  539.            (create-reference-node (*vector->lexical-var* exp)))
  540.           (else
  541.            (case exp
  542.             ((lambda)
  543.              (vector->lambda-node vec env))
  544.             ((quote)
  545.              (create-literal-node (get-datum vec)))
  546.             ((locale)
  547.              (let ((name (get-datum vec)))
  548.                (create-reference-node (obtain-locale-bound-variable name env))))
  549.             ((known)
  550.              (let ((var (get-datum vec)))
  551.                (create-reference-node var)))
  552.             ((internal-object)
  553.              (vector->object-node vec env))
  554.             ((object)
  555.              (bug '"vector->node got an OBJECT in ~S" vec))
  556.             (else
  557.              (bug '"vector->node got an unknown form ~S" exp)))))))
  558.  
  559. (define (vector->lambda-node vec env)
  560.   (let* ((self-name (get-datum vec))
  561.          (count (get-datum vec)))   
  562.     (do ((i 0 (fx+ i 1))
  563.          (v '() (cons-from-freelist (vector->bound-variable vec) v)))
  564.         ((fx>= i count)
  565.          (let ((node (create-lambda-node self-name (reverse! v))))
  566.            (relate lambda-body node (vector->call-node vec env))
  567.            node)))))        
  568.  
  569. ;;; Replace a variable name with a new variable.
  570.  
  571. (define (vector->bound-variable vec)
  572.   (let ((name (get-datum vec)))
  573.     (cond (name
  574.            (let ((var (create-variable name)))
  575.              (set (*vector->lexical-var* (cdr vec)) var)
  576.              var))
  577.           (else nil))))
  578.  
  579. (define (vector->call-node vec env)
  580.   (let* ((exits (get-datum vec))
  581.          (count (get-datum vec))
  582.          (node (create-call-node count exits)))
  583.     (vector->node-list vec node call-arg count env)))
  584.  
  585. (define (vector->node-list vec node relation count env)
  586.   (do ((i 0 (fx+ i 1)))
  587.       ((fx>= i count)
  588.        node)
  589.     (relate (relation i) node (real-vector->node vec env))))
  590.  
  591. ;;; There are two ways of encoding objects depending on the context.
  592.  
  593. (define (vector->object-node vec env)
  594.   (let* ((op? (get-datum vec))
  595.          (count (get-datum vec))
  596.          (node (create-object-node op? count)))
  597.     (relate object-proc node (real-vector->node vec env))
  598.     (vector->node-list vec node object-op count env)
  599.     (vector->node-list vec node object-method count env)
  600.     node))
  601.  
  602. (define (list->object-node list env)
  603.   (destructure (((#f op? proc ops methods) list))
  604.     (let ((node (create-object-node op? (length ops))))
  605.       (relate object-proc node (vector->node proc env))
  606.       (relate-object-ops node (free-map (lambda (v)
  607.                                           (vector->node v env))
  608.                                         ops))
  609.       (relate-object-methods node (free-map (lambda (v)
  610.                                               (vector->node v env))
  611.                                             methods))
  612.       node)))
  613.  
  614.  
  615.  
  616.  
  617.