;;; -*- Mode:LISP; Package:USER; Base:10 -*- ;;; $Header: /ct/ctlisp/dlist.l,v 1.3 85/06/21 12:26:57 bill Exp $ ;;; $Log: /ct/ctlisp/dlist.l,v $ ;;;Revision 1.3 85/06/21 12:26:57 bill ;;;Changed the record_type definitions to def_record_type. ;;; ;;;Revision 1.2 83/10/12 08:26:13 bill ;;;System works with all files compiled. ;;; ;;;Revision 1.1 83/10/08 00:17:14 bill ;;;Initial revision ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ;;; dlist ;;; ;;; ;;; ;;; William Brew 8-11-83 ;;; ;;; ;;; ;;; Lisp code for double linked lists. ;;; ;;; ;;; ;;; This file is part of a proprietary software project. Source ;;; ;;; code and documentation describing implementation details are ;;; ;;; available on a confidential, non-disclosure basis only. These ;;; ;;; materials, including this file in particular, are trade secrets ;;; ;;; of Computer * Thought Corporation. ;;; ;;; ;;; ;;; (c) Copyright 1982 and 1983, Computer * Thought Corporation. ;;; ;;; All Rights Reserved. ;;; ;;; ;;; ;;; Reference materials: ;;; ;;; Foderaro and Sklower, The FRANZ LISP Manual, September 1981. ;;; ;;; Weinreb and Moon, LISP MACHINE MANUAL, Symbolics, July 1981. ;;; ;;; Charniak et al., 1980. Artificial Intelligence Programming. ;;; ;;; Miller, 1982. The C*T Ada Tutor: Guide to the Implementation. ;;; ;;; ;;; ;;; The following code assumes familiarity with these materials. ;;; ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Ensure presence of needed files. (comment Assumes ct_load and some suitable file_map are present) (eval-when (compile load eval) (ct_load 'aip)) ;AIP macros pkg. (eval-when (compile load eval) (ct_load 'compat)) ;Franz/LM compat pkg. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Compiler Declarations and Global Variables -- #+franz (declare (macros t)) #+franz (setq *flavor-expand-macros* t) ; ; A cell of a dlist (dlcell) structure consists of two cons cells. The car of the ; first cons cell points to the value; its cdr points to the other cons cell. The ; second cons cell contains the predecessor and successor pointers ; for the dlist. The car is the pred pointer. The cdr is the succ pointer. ; (def_record_type dlcell nil (val pred . succ)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Macro definitions -- ; Get the value part of a dlcell (defmacro dlval (dlcel) `(dlcell%val ,dlcel)) ; Get the pred pointer of a dlcell (defmacro dlpred (dlcel) `(dlcell%pred ,dlcel)) ; Get the succ pointer of a dlcell (defmacro dlsucc (dlcel) `(dlcell%succ ,dlcel)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Flavor definitions -- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Externally Callable Functions/Methods -- ; --NB may want to some checking for well formed dlcells on input arguments. ; ; Test whether a thing looks like a dlcell. ; ; --NB may want to put the tag field in the record. (defun dlcellp (thing) (listp thing) ) ; ; Get the first dlcell in a dlist structure ; (defun dlfirst (dlist) (loop for dlcel = dlist then (dlpred dlcel) unless (dlpred dlcel) return dlcel ) ) ; ; Get the last dlcell in a dlist structure ; (defun dllast (dlist) (loop for dlcel = dlist then (dlsucc dlcel) unless (dlsucc dlcel) return dlcel ) ) ; ; Insert a new dlcell with the given value at the beginning of the dlist. Makes ; a new dlcell and rplac's it into the dlist. Returns the new first dlcell. ; (defun dlinfirst (dlist value) (let ((first (dlfirst dlist))) (cond (first (%= (dlpred first) (setq first (dlcell value nil first))) first ) (t (dlcell value nil nil)) ) ) ) ; ; Insert a new dlcell with the given value at the end of the dlist. Makes ; a new dlcell and rplac's it into the dlist. Returns the new last dlcell. ; (defun dlinlast (dlist value) (let ((last (dllast dlist))) (cond (last (%= (dlsucc last) (setq last (dlcell value last nil))) last ) (t (dlcell value nil nil)) ) ) ) ; ; Insert a new dlcell with the given value before the given dlcell. Makes ; a new dlcell and rplac's it into the dlist. Returns the new dlcell. ; (defun dlinbefore (dlcel value) (let ((prev (dlpred dlcel)) new) (cond (prev (setq new (dlcell value prev dlcel)) (%= (dlpred dlcel) new) (%= (dlsucc prev) new) new ) (t (dlinfirst dlcel value)) ) ) ) ; ; Insert a new dlcell with the given value after the given cell. Makes ; a new dlcell and rplac's it into the dlist. Returns the new dlcell. ; (defun dlinafter (dlcel value) (let ((next (dlsucc dlcel)) new) (cond (next (setq new (dlcell value dlcel next)) (%= (dlpred next) new) (%= (dlsucc dlcel) new) new ) (t (dlinlast dlcel value)) ) ) ) ; ; Append two dlists together. Take two dlcells and make the first the predicessor ; of the second and the second the successor of the first. Returns the first ; dlcell. ; (defun dlappend (dlfirst dlsecond) (%= (dlsucc dlfirst) dlsecond) (%= (dlpred dlsecond) dlfirst) dlfirst ) ; ; Remove a dlcell from its dlist. Rplac's the dlcell out of the dlist. ; Clears the removed dlcell's pointers and returns a copy of the original. ; (defun dlrem (dlcel) (let* ((prev (dlpred dlcel)) (next (dlsucc dlcel)) (oldcell (dlcell (dlval dlcel) prev next)) ) (cond (prev (%= (dlsucc prev) next))) (cond (next (%= (dlpred next) prev))) (%= (dlpred dlcel) nil) (%= (dlsucc dlcel) nil) oldcell ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Internal Use Only Functions/Methods -- ;;; eof ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;