Synopsis: Compute the Dylan superclass linearization Author: Kim Barrett , Bob Cassels , Paul Haahr , David A. Moon , Keith Playford , P. Tucker Withington Module: dylan-user define constant compute-dylan-linearization = method (c :: ) => (cpl :: ) local method merge-lists (reversed-partial-result :: , remaining-inputs :: ) if (every?(empty?, remaining-inputs)) reverse!(reversed-partial-result) else // start of selection rule local method candidate (c :: ) // returns c if it can go in the result now, otherwise false local method head? (l :: ) c == head(l) end method head?, method tail? (l :: ) member?(c, tail(l)) end method tail?; any?(head?, remaining-inputs) & ~any?(tail?, remaining-inputs) & c end method candidate, method candidate-direct-superclass (c :: ) any?(candidate, direct-superclasses(c)) end method candidate-direct-superclass; let next = any?(candidate-direct-superclass, reversed-partial-result); // end of selection rule if (next) local method remove-next (l :: ) if (head(l) == next) tail(l) else l end end method remove-next; merge-lists(pair(next, reversed-partial-result), map(remove-next, remaining-inputs)) else error("Inconsistent precedence graph"); end if end if end method merge-lists; let c-direct-superclasses = direct-superclasses(c); local method cpl-list (c) as(, dylan-linearization(c)) // all-superclasses end method cpl-list; merge-lists(list(c), concatenate(map(cpl-list, c-direct-superclasses), list(as(, c-direct-superclasses)))); end method; // compute-dylan-linearization