|
|
1.1 ! root 1: (setq rcs-common0- ! 2: "$Header: common0.l,v 1.4 83/12/15 11:09:34 jkf Exp $") ! 3: ! 4: ;; ! 5: ;; common0.l -[Mon Nov 21 14:06:20 1983 by jkf]- ! 6: ;; ! 7: ;; Functions which are required to execute the low level lisp macros ! 8: ;; and functions. ! 9: ;; ! 10: ;; This is the first file of functions read in when building a lisp. ! 11: ;; If this lisp is to run interpretedly, then we must not use anything ! 12: ;; which hasn't be defined in the C lisp kernel, except ';' which is ! 13: ;; defined as the comment character before reading this file. ! 14: ;; We cannot use defmacro, the backquote or the # macro. ! 15: ;; ! 16: ;; This file should be as short as possible since it must be written in ! 17: ;; a rather primitive way. ! 18: ;; ! 19: ! 20: ;--- declare : ignore whatever is given, this info is for the compiler ! 21: ; ! 22: (def declare (nlambda (x) nil)) ! 23: ! 24: (declare (macros t)) ! 25: ! 26: ;--- memq - arg : (probably a symbol) ! 27: ; - lis : list ! 28: ; returns part of lis beginning with arg if arg is in lis ! 29: ; ! 30: (def memq ! 31: (lambda ($a$ $l$) ! 32: (do ((ll $l$ (cdr ll))) ! 33: ((null ll) nil) ! 34: (cond ((eq $a$ (car ll)) (return ll)))))) ! 35: ! 36: ;--- def :: define a function ! 37: ; This superceeds franz's definition. ! 38: ; It does more error checking and it does lambda conversion ! 39: ; ! 40: (def def ! 41: (nlambda (l) ! 42: ((lambda (name argl) ! 43: (cond ((and (symbolp (setq name (car l))) ! 44: (dtpr (cadr l)) ! 45: (null (cddr l)) ! 46: (memq (caadr l) '(lambda nlambda lexpr macro glambda))) ! 47: ; make sure lambda list is nil or a dtpr ! 48: (setq l (cadr l)) ; l points to (lambda (argl) ...) ! 49: (cond ((null (setq argl (cadr l)))) ; nil check ! 50: ((dtpr (cadr l)) ; dtpr ! 51: (cond ((and (eq (car l) 'lambda) ! 52: (or (memq '&aux argl) ! 53: (memq '&optional argl) ! 54: (memq '&rest argl) ! 55: (memq '&body argl))) ! 56: ; must lambda convert ! 57: (setq l (lambdacvt (cdr l)))))) ! 58: (t (error "def: bad lambda list of form in " l))) ! 59: (putd name l) ! 60: name) ! 61: (t (error "def: bad form " l)))) ! 62: nil nil))) ! 63: ! 64: ! 65: ;--- defun ! 66: ; maclisp style function defintion ! 67: ; ! 68: (def defun ! 69: (macro (l) ! 70: (prog (name type arglist body specind specnam) ! 71: (setq name (cadr l) l (cddr l)) ! 72: (cond ((dtpr name) ! 73: (cond ((memq (cadr name) '(macro expr fexpr lexpr)) ! 74: (setq l (cons (cadr name) l) ! 75: name (car name))) ! 76: (t (setq specnam (car name) ! 77: specind (cadr name) ! 78: name (concat (gensym) "::" specnam)))))) ! 79: (cond ((null (car l)) (setq type 'lambda)) ! 80: ((eq 'fexpr (car l)) (setq type 'nlambda l (cdr l))) ! 81: ((eq 'expr (car l)) (setq type 'lambda l (cdr l))) ! 82: ((eq 'macro (car l)) (setq type 'macro l (cdr l))) ! 83: ((atom (car l)) ! 84: (setq type 'lexpr ! 85: l (nconc (list (list (car l))) ! 86: (cdr l)))) ! 87: (t (setq type 'lambda))) ! 88: (setq body (list 'def name (cons type l))) ! 89: (cond (specnam ! 90: (return (list 'progn ''compile ! 91: body ! 92: (list 'putprop ! 93: (list 'quote specnam) ! 94: (list 'getd ! 95: (list 'quote name)) ! 96: (list 'quote specind))))) ! 97: (t (return body)))))) ! 98: ! 99: ! 100: ;--- error : print error message and cause an error ! 101: ; call is usually (error "string" value) ! 102: ; ! 103: (def error ! 104: ;; form: (error arg1 ...) ! 105: ;; concat all args together, with spaces between them ! 106: ;; and cause an error to be signaled ! 107: (lexpr (n) ! 108: (do ((i n (1- i)) ! 109: (mesg "")) ! 110: ((eq i 0) (err-with-message mesg)) ! 111: (setq mesg (concat ! 112: (cond ((atom (arg i)) (arg i)) ! 113: ((lessp (maknum (arg i)) (maknum nil)) ! 114: ; this tests for the <UNBOUND> value ! 115: '<UNBOUND>) ! 116: (t (implode (exploden (arg i))))) ! 117: " " mesg))))) ! 118: ! 119: (def err ! 120: ;; (err value [junk]) ! 121: ;; This is here for maclisp compatibility. junk should be nil, ! 122: ;; but we don't verify. ! 123: ;; The value is both to be printed and to be returned from the ! 124: ;; errset. 'err-with-message' should be used for new code ! 125: (lexpr (n) ! 126: (cond ((eq n 0) ! 127: (err-with-message "call to err")) ! 128: ((or (eq n 1) (eq n 2)) ! 129: (err-with-message (arg 1) (arg 1))) ! 130: (t (error "wrong number of args to err:" n))))) ! 131: ! 132: ! 133: ;--- append : append two or more lists ! 134: ; the result will be a copy of all but the last list ! 135: ; ! 136: (declare (localf append2args)) ! 137: ! 138: (def append ! 139: (lexpr (nargs) ! 140: (cond ((eq nargs 2) (append2args (arg 1) (arg 2))) ! 141: ((zerop nargs) nil) ! 142: (t (do ((i (1- nargs) (1- i)) ! 143: (res (arg nargs))) ! 144: ((zerop i) res) ! 145: (setq res (append2args (arg i) res))))))) ! 146: ! 147: ;--- append2args : append just two args ! 148: ; a version of append which only works on 2 arguments ! 149: ; ! 150: (def append2args ! 151: (lambda (x y) ! 152: (prog (l l*) ! 153: (cond ((null x) (return y)) ! 154: ((atom x) (error "Non-list to append:" x))) ! 155: (setq l* (setq l (cons (car x) nil))) ! 156: loop (cond ((atom x) (error "Non-list to append:" x)) ! 157: ((setq x (cdr x)) ! 158: (setq l* (cdr (rplacd l* (cons (car x) nil)))) ! 159: (go loop))) ! 160: (rplacd l* y) ! 161: (return l)))) ! 162: ! 163: ;--- append1 : add object to end of list ! 164: ; adds element y to then end of a copy of list x ! 165: ; ! 166: (def append1 (lambda (x y) (append x (list y)))) ! 167: ! 168: ;--- assoc - x : lispval ! 169: ; - l : list ! 170: ; l is a list of lists. The list is examined and the first ! 171: ; sublist whose car equals x is returned. ! 172: ; ! 173: (def assoc ! 174: (lambda (val alist) ! 175: (do ((al alist (cdr al))) ! 176: ((null al) nil) ! 177: (cond ((null (car al))) ! 178: ((not (dtpr (car al))) ! 179: (error "bad arg to assoc" al)) ! 180: ((equal val (caar al)) (return (car al))))))) ! 181: ! 182: ;--- rassq : like assq but look at the cdr instead of the car ! 183: ; ! 184: (def rassq ! 185: (lambda (form list) ! 186: (cond ((null list) nil) ! 187: ((not (dtpr list)) ! 188: (error "rassq: illegal second argument: " list)) ! 189: (t (do ((ll list (cdr ll))) ! 190: ((null ll) nil) ! 191: (cond ((eq form (cdar ll)) (return (car ll))))))))) ! 192: ;--- concatl - l : list of atoms ! 193: ; returns the list of atoms concatentated ! 194: ; ! 195: (def concatl ! 196: (lambda (x) (apply 'concat x))) ! 197: ! 198: ;--- length - l : list ! 199: ; returns the number of elements in the list. ! 200: ; ! 201: (def length ! 202: (lambda ($l$) ! 203: (cond ((and $l$ (not (dtpr $l$))) ! 204: (error "length: non list argument: " $l$)) ! 205: (t (cond ((null $l$) 0) ! 206: (t (do ((ll (cdr $l$) (cdr ll)) ! 207: (i 1 (1+ i))) ! 208: ((null ll) i)))))))) ! 209: ! 210: ;--- memq - arg : (probably a symbol) ! 211: ; - lis : list ! 212: ; returns part of lis beginning with arg if arg is in lis ! 213: ; ! 214: (def memq ! 215: (lambda ($a$ $l$) ! 216: (do ((ll $l$ (cdr ll))) ! 217: ((null ll) nil) ! 218: (cond ((eq $a$ (car ll)) (return ll)))))) ! 219: ! 220: ;--- nconc - x1 x2 ...: lists ! 221: ; The cdr of the last cons cell of xi is set to xi+1. This is the ! 222: ; structure modification version of append ! 223: ; ! 224: ! 225: (def nconc ! 226: (lexpr (nargs) ! 227: (cond ((eq nargs '2) ! 228: (cond ((null (arg 1)) (arg 2)) ! 229: (t (do ((tmp (arg 1) (cdr tmp))) ! 230: ((null (cdr tmp)) ! 231: (rplacd tmp (arg 2)) ! 232: (arg 1)))))) ! 233: ((zerop nargs) nil) ! 234: (t (do ((i 1 nxt) ! 235: (nxt 2 (1+ nxt)) ! 236: (res (cons nil (arg 1)))) ! 237: ((eq i nargs) (cdr res)) ! 238: (cond ((arg i) (rplacd (last (arg i)) (arg nxt))) ! 239: (t (rplacd (last res) (arg nxt))))))))) ! 240: ! 241: ! 242: ! 243: (declare (localf nreverse1)) ; quick fcn shared by nreverse and nreconc ! 244: ! 245: ;--- nreconc :: nreverse and nconc ! 246: ; (nreconc list elemt) is equiv to (nconc (nreverse list) element) ! 247: ; ! 248: (defun nreconc (list element) ! 249: (cond ((null list) element) ! 250: (t (nreverse1 list element)))) ! 251: ! 252: ;--- nreverse - l : list ! 253: ; reverse the list in place ! 254: ; ! 255: ! 256: (defun nreverse (x) ! 257: (cond ((null x) x) ! 258: (t (nreverse1 x nil)))) ! 259: ! 260: ! 261: ;--- nreverse1 ! 262: ; common local function to nreconc and nreverse. [This can just be ! 263: ; nreconc when I get local global functions allow in the compiler -jkf] ! 264: ; ! 265: (defun nreverse1 (x ele) ! 266: (prog (nxt) ! 267: loop ! 268: (setq nxt (cdr x)) ! 269: (rplacd x ele) ! 270: (setq ele x) ! 271: (cond (nxt (setq x nxt) (go loop))) ! 272: (return x))) ! 273: ! 274: ;--- liszt-declare :: this is defined in the compiler ! 275: ; we give it a null definition in the interpreter ! 276: ; ! 277: (def liszt-declare (nlambda (x) nil))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.