;; common0.l -[Thu Apr 1 10:23:14 1982 by jkf]-
;; Functions which are required to execute the low level lisp macros
;; This is the first file of functions read in when building a lisp.
;; If this lisp is to run interpretedly, then we must not use anything
;; which hasn't be defined in the C lisp kernel, except ';' which is
;; defined as the comment character before reading this file.
;; We cannot use defmacro, the backquote or the # macro.
;; This file should be as short as possible since it must be written in
;; a rather primitive way.
(setq SCCS-common0 "@(#)common0.l 1.3 4/1/82")
;--- declare : ignore whatever is given, this info is for the compiler
(def declare (nlambda (x) nil))
;--- defun - standard maclisp function definition form.
(prog (name type arglist body specind specnam)
(setq name (cadr l) l (cddr l))
(cond ((memq (cadr name) '(macro expr fexpr lexpr))
(setq l (cons (cadr name) l)
(t (setq specnam (car name)
name (concat (gensym) "::" specnam))))))
(cond ((null (car l)) (setq type 'lambda))
((eq 'fexpr (car l)) (setq type 'nlambda l (cdr l)))
((eq 'expr (car l)) (setq type 'lambda l (cdr l)))
((eq 'macro (car l)) (setq type 'macro l (cdr l)))
l (nconc (list (list (car l)))
(cond ((and (eq 'lambda type) (or (memq '&aux (car l))
(memq '&optional (car l))
(setq body (list 'def name (cons type l)))
(return (list 'progn ''compile
(list 'quote specind)))))
;--- error : print error message and cause an error
; call is usually (error "string" value)
;--- append : append two or more lists
; the result will be a copy of all but the last list
(declare (localf append2args))
(cond ((eq nargs 2) (append2args (arg 1) (arg 2)))
(t (do ((i (1- nargs) (1- i))
(setq res (append2args (arg i) res)))))))
;--- append2args : append just two args
; a version of append which only works on 2 arguments
(cond ((null x) (return y))
((atom x) (error "Non-list to append:" x)))
(setq l* (setq l (cons (car x) nil)))
loop (cond ((atom x) (error "Non-list to append:" x))
(setq l* (cdr (rplacd l* (cons (car x) nil))))
;--- append1 : add object to end of list
; adds element y to then end of a copy of list x
(def append1 (lambda (x y) (append x (list y))))
; l is a list of lists. The list is examined and the first
; sublist whose car equals x is returned.
(do ((al alist (cdr al)))
(error "bad arg to assoc" al))
((equal val (caar al)) (return (car al)))))))
;--- rassq : like assq but look at the cdr instead of the car
(error "rassq: illegal second argument: " list))
(t (do ((ll list (cdr ll)))
(cond ((eq form (cdar ll)) (return (car ll)))))))))
;--- concatl - l : list of atoms
; returns the list of atoms concatentated
(lambda (x) (apply 'concat x)))
;--- memq - arg : (probably a symbol)
; returns part of lis beginning with arg if arg is in lis
(cond ((eq $a$ (car ll)) (return ll))))))
;--- nconc - x1 x2 ...: lists
; The cdr of the last cons cell of xi is set to xi+1. This is the
; structure modification version of append
(cond ((null (arg 1)) (arg 2))
(t (do ((tmp (arg 1) (cdr tmp)))
(res (cons nil (arg 1))))
(cond ((arg i) (rplacd (last (arg i)) (arg nxt)))
(t (rplacd (last res) (arg nxt)))))))))
(declare (localf nreverse1)) ; quick fcn shared by nreverse and nreconc
;--- nreconc :: nreverse and nconc
; (nreconc list elemt) is equiv to (nconc (nreverse list) element)
(defun nreconc (list element)
(cond ((null list) element)
(t (nreverse1 list element))))
; reverse the list in place
; common local function to nreconc and nreverse. [This can just be
; nreconc when I get local global functions allow in the compiler -jkf]
(cond (nxt (setq x nxt) (go loop)))