This commit is contained in:
Justin Ethier 2016-07-12 03:28:38 -04:00
parent 0e82152a7c
commit 8e983a9bfa

View file

@ -13,49 +13,56 @@
;((d) (b)) ; circular dep!
((e))
))
;; TODO: see http://www.electricmonk.nl/log/2008/08/07/dependency-resolving-algorithm/
;; A dependency is a list (lib . deps)
;; lib is the name, and deps are the edges.
;; Goal is to resolve a list of dependencies into the appropriate order
;; Goal is to resolve a list of dependencies into the appropriate order such
;; that no node is encountered before its dependencies.
;; We also need to raise an error if a circular dependency is found
;;
;; A dependency list consists of: (name . edges)
;; Where edges are all of the dependencies of name.
;;
;; nodes is a list of many dependency lists.
;;
;; Based on code from:
;; http://www.electricmonk.nl/log/2008/08/07/dependency-resolving-algorithm/
(define (resolve-dependencies nodes)
(define (append-cell! cell value) (set-cdr! cell (cons value (cdr cell))))
(define (make-cell) (cons #f '()))
(define get-cell cdr)
(define (node->edges name) (assoc name nodes))
;; TODO: consider loading all (lib . deps) into a table so we can easily get edges for a lib
;; Create a new node that depends on all the others
(define (master-dependency)
(cons '(#f) (map car nodes)))
(define (node->edges name)
(assoc name test2))
(define (dep-resolve node resolved seen)
; DEBUG: (write node) (newline)
(append-cell! seen node)
(for-each
(lambda (edge)
(cond
((not (assoc edge (get-cell resolved)))
(if (assoc edge (get-cell seen))
(error "Circular dependency detected" node edge))
(dep-resolve (node->edges edge) resolved seen))))
(cdr (node->edges (car node))))
(append-cell! resolved node)
resolved)
(define result (cons #f '()))
(define seen (cons #f '()))
(set! nodes (cons (master-dependency) nodes))
(let* ((resolved (dep-resolve (node->edges '(#f)) (make-cell) (make-cell)))
(deps (reverse (cdr (get-cell resolved))))) ;; cdr to get rid of master list
(map car deps)))
(define (append-cell! cell value)
(set-cdr! cell (cons value (cdr cell))))
(define get-cell cdr)
(define (get-all-names)
(cons '(all) (map car test2)))
(define (dep-resolve node resolved seen)
;(write (car node))
(write node)
(newline)
(append-cell! seen node)
(for-each
(lambda (edge)
(cond
((not (assoc edge (get-cell resolved)))
(if (assoc edge (get-cell seen))
(error "Circular dependency detected" node edge))
(dep-resolve (node->edges edge) resolved seen))))
(cdr (node->edges (car node))))
(append-cell! resolved node)
)
(set! test2 (cons (get-all-names) test2))
;(write (get-all-names))
;(newline)
(dep-resolve (node->edges '(all)) result seen)
;(dep-resolve (node->edges '(a)) result seen)
(write (resolve-dependencies test2))
(newline)
(write (reverse (get-cell result)))
(write (resolve-dependencies *test*))
; (set! test2 (cons (get-all-names) test2))
;;(write (get-all-names))
;;(newline)
;(dep-resolve (node->edges '(all)) result seen)
;;(dep-resolve (node->edges '(a)) result seen)
;(newline)
;(write (reverse (get-cell result)))