From 8e983a9bfaed2d1ee56ac2a4f3330582d22c1246 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Tue, 12 Jul 2016 03:28:38 -0400 Subject: [PATCH] WIP --- deps.scm | 83 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/deps.scm b/deps.scm index 4644ab60..d91fef71 100644 --- a/deps.scm +++ b/deps.scm @@ -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)))