home *** CD-ROM | disk | FTP | other *** search
- ; misc.l - Copyright (c) 1986 by David Morein.
- ;
- ; this file contains miscellaneous routines which
- ; don't belong anywhere else.
- ;
- ; note - this is an initialization file, see the manual for more info.
- ;
- ; global functions:
- ;
- (global 'add1)
- (global 'add-to-list)
- (global 'assoc)
- (global 'compiled-function-p)
- (global 'csubrp)
- (global 'cnsubrp)
- (global 'defmacro)
- (global 'defun)
- (global 'do)
- (global 'do*)
- (global 'firstn)
- (global 'function)
- (global 'gensym)
- (global 'implode)
- (global 'intern)
- ;(global 'if)
- (global 'lconc)
- (global 'loop)
- (global 'make-tconc)
- (global 'max)
- (global 'min)
- (global 'nsubrp)
- (global 'nth)
- (global 'nthcdr)
- (global 'nthelem)
- (global 'prog)
- (global 'prog*)
- (global 'remove-first)
- (global 'sprint)
- (global 'subrp)
- (global 'subst)
- (global 'sub1)
- (global 'tconc)
- (global 'type)
- (global 'unless)
- (global 'when)
- ;
- ; defun - Common LISP style defun
- ;
- ; this macro expands to:
- ; (progn
- ; (putd
- ; '<name>
- ; '(lambda <lambda-list> (block <name> <form>)))
- ; '<name>)
- ;
- (def defun (macro (name lambda-list &rest form)
- (list 'progn
- (list 'putd
- (list 'quote name)
- (list 'quote
- (list 'lambda lambda-list
- (list 'block name form))))
- (list 'quote name))))
- ;
- ; defmacro - Common LISP style defmacro
- ;
- (def defmacro (macro (name lambda-list &rest form)
- (list 'progn
- (list 'putd
- (list 'quote name)
- (list 'quote
- (list 'macro lambda-list form)))
- (list 'quote name))))
- ;
- ;
- ; add-to-list - adds expression e to list l if it is not already present.
- ; this function returns the altered list as its value.
- ;
- (defun add-to-list (e l)
- (cond ((member e l) l)
- (t (cons e l))))
- ;
- ;
- ; add1 - returns n + 1
- ;
- (defun add1 (x) (+ x 1))
- ;
- ;
- ; assoc - associates e with l in an association list
- ;
- (defun assoc (e l)
- (cond
- ((null l) nil)
- ((equal e (caar l)) (car l))
- (t (assoc e (cdr l)))))
- ;
- ;
- ; compiled-function-p - Common Lisp compatible.
- ;
- (defun compiled-function-p (x)
- (or (csubrp x) (cnsubrp x) (subrp x) (nsubrp x)))
- ;
- ;
- ; csubrp - return T iff x is bound as a csubr
- ;
- (defun csubrp (x)
- (eq (type x) 'csubr))
- ;
- ;
- ; cnsubrp - return T iff x is bound as a cnsubr
- ;
- (defun cnsubrp (x)
- (eq (type x) 'cnsubr))
- ;
- ;
- ; do - structured iterative construct.
- ;
- (defmacro do (initlist term_case &rest body)
- (list 'block 'nil
- (list 'let initlist
- (list 'loop1
- (filter-nulls (mapcar 'extract-update-form initlist))
- (list 'cond (list (car term_case) (list 'return (cadr term_case))))
- (cons 'tagbody body)))))
- ;
- ;
- ; extract-update-form: extracts any update forms from
- ; an initialization list.
- ;
- (def extract-update-form (nlambda (initform)
- (progn
- (setq init_var (car initform))
- (setq init_val (cadr initform))
- (setq init_step (caddr initform))
- (cond (init_step (list 'setq init_var initstep))
- (t nil)))))
- ;
- ; filter-nulls: filters out nulls from a list
- ;
- (defun filter-nulls (l)
- (cond ((null l) l)
- ((null (car l)) (filter-nulls (cdr l)))
- (t (cons (car l) (filter-nulls (cdr l))))))
- ;
- ; do* - structured iterative construct with parallel binding.
- ;
- (defmacro do* (initlist term_case &rest body)
- (list 'block 'nil
- (list 'let* initlist
- (list 'loop1
- (list 'cond (list (car term_case) (list 'return (cadr term_case))))
- (cons 'tagbody body)))))
- ;
- ;
- ; firstn - returns a list of the first n elements of l.
- ; (i.e., (firstn 2 '(a b c d e)) ==> (a b))
- ;
- (defun firstn (n l)
- (reverse (nthcdr (- (length l) (min (length l) n)) (reverse l))))
- ;
- ;
- ; function - as far as the interpreter is concerned,
- ; this is the same as QUOTE. Lexical closures
- ; will be introduced in a later release.
- ;
- (def function (nlambda (x) x))
- ;
- ; gensym - creates an new, uninterned symbol.
- ; see the Common Lisp manual or the UNXLISP manual
- ; for all of the arcana associated with this function.
- ;
- (defun gensym (&optional x)
- (make-symbol (genstring x)))
- ;
- ;
- ; the following code will be un-commented when
- ; the compiler is ready:
- ;
- ; if - Common compatible IF macro:
- ;
- ;(defmacro if (test result-if-true &optional result-if-false)
- ; `(cond (,test ,result-if-true) (t ,result-if-false)))
- ;
- ;
- ; implode - implodes a list of symbols into a new
- ; symbol with a print-name which is the concatenation
- ; of all of the constituent names.
- ;
- (defun implode (x)
- (intern (implode-to-string x)))
- ;
- ;
- ; intern - interns a symbol in a specified directory
- ;
- (defun intern (id &optional directory)
- (cond
- ((null directory) (internc id))
- (t (progn
- (pd directory)
- (internc id)
- (popd)))))
- ;
- ; loop - loops until an explicit return
- ;
- (defmacro loop (&rest body)
- (list 'block 'nil (list 'loop1 body)))
- ;
- ; max - returns the maximum of its arguments
- ;
- (defun max (x y)
- (cond ((> x y) x)
- (t y)))
- ;
- ; min - returns the minimum of its arguments
- ;
- (defun min (x y)
- (cond
- ((< x y) x)
- (t y)))
- ;
- ;
- ; nth - similar to Franz nth; returns the nth
- ; element of a list, with the first element of
- ; the list having an index of 0.
- ;
- (defun nth (n e)
- (car (nthcdr n e)))
- ;
- ;
- ; nthcdr - similar to Franz nthcdr; cdrs down a list
- ; n times. (i.e., (nthcdr 2 '(a b c d e)) ==> (c d e)).
- ;
- (defun nthcdr (n e)
- (do ((i 0)) ;initialize i to 0.
- ((eql i n) e) ;termination test.
- (setq i (+ i 1)) ;increment i.
- (setq e (cdr e)))) ;body of do
- ;
- ;
- ; nthelem - similar to Franz nthelem; returns the nth
- ; element of a list, with the first element of
- ; the list having an index of 1.
- ;
- (defun nthelem (n e)
- (car (nthcdr (- n 1) e)))
- ;
- ;
- ; nsubrp - return T iff x is bound as an nsubr
- ;
- (defun nsubrp (x)
- (eq (type x) 'nsubr))
- ;
- ;
- ; prog - generalized iterative construct.
- ;
- (defmacro prog (vbl_list &rest body)
- (list 'block 'nil
- (list 'let vbl_list
- (cons 'tagbody body))))
- ;
- ; prog* - generalized iterative construct with parallel binding.
- ;
- (defmacro prog* (vbl_list &rest body)
- (list 'block 'nil
- (list 'let* vbl_list
- (cons 'tagbody body))))
- ;
- ; sprint - "safe" print utility, prints s-expression x
- ; down to level LEV. Expressions more than LEV levels
- ; down are printed as &.
- ;
- (defun sprint (x lev)
- (cond ((atom x) x)
- ((eql 0 lev) '&)
- ((and (atom (cdr x)) (cdr x)) x)
- (t (cons
- (sprint (car x) (sub1 lev))
- (sprint (cdr x) lev)))))
- ;
- ;
- ; subst - substitutes a for b in c
- ; there are no restrictions on a, b, and c.
- ;
- ;
- (defun subst (a b c)
- (cond
- ((equal b c) a)
- ((atom c) c)
- (t (cons (subst a b (car c)) (subst a b (cdr c))))))
- ;
- ;
- ; subrp - return T iff x is bound as a subr
- ;
- (defun subrp (x)
- (eq (type x) 'subr))
- ;
- ;
- ; sub1 - returns n - 1
- ;
- (defun sub1 (x)
- (- x 1))
- ;
- ;
- ; make-tconc - creates a new tconc structure
- ;
- (def make-tconc (lambda ()
- (cons 'nil 'nil)))
- ;
- ;
- ; lconc - adds an element, Y to the end of a tconc cell, X.
- ;
- (def lconc (lambda (x y)
- (let ((listy (list y)))
- ;
- ; if x was empty, then y is now the
- ; first and last element.
- ;
- (cond
- ((null (cdr x))
- (rplaca x listy)
- (rplacd x listy))
- (t
- (rplacd (last (car x)) listy)
- (rplacd x listy)))
- x)))
- ;
- ; tconc - adds an element, y, to a tconc structure, x.
- ; a tconc structure is a type of s-expression
- ; with pointers to both the head and tail
- ; of a list.
- ;
- (def tconc (lambda (x y)
- (let ((listy (list y)))
- (rplacd listy (car x))
- (rplaca x listy)
- (if (null (cdr x))
- (rplacd x listy))
- x)))
- ;
- ;
- ; remove-first - removes the first element from a tconc cell:
- ;
- (def remove-first (lambda (x)
- (cond
- ((null (car x)) 'nil) ;return NIL if empty tconc cell.
- ((null (cdar x))
- (let ((element (caar x)))
- (rplaca x 'nil)
- (rplacd x 'nil)
- element))
- (t
- (let ((element (caar x)))
- (rplaca x (cdar x))
- element)))))
-
- ; type - returns the type of a symbol which is bound as a function.
- ;
- (def type (lambda (x)
- (cond
- ((not (symbolp x))
- (err "***> TYPE: arg not a symbol"))
- ((not (fboundp x))
- (err "***> TYPE: arg not bound as a function"))
- (t
- (car (symbol-function x))))))
- ;
- ; unless - Common LISP compatible UNLESS
- ;
- (defmacro unless (test &rest forms)
- `(cond
- ((null ,test) (progn ,@forms))
- (t nil)))
- ;
- ; when - Common LISP compatible WHEN
- ;
- (defmacro when (test &rest forms)
- `(cond
- ((null ,test) nil)
- (t (progn ,@forms))))
- ;
- ;
- ; end of misc.l
- ;