|
|
1.1 ! root 1: (setq rcs-common0- ! 2: "$Header: common0.l,v 1.3 83/09/07 08:12:49 jkf Exp $") ! 3: ! 4: ;; ! 5: ;; common0.l -[Sun Sep 4 13:44:22 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))) ! 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: (t (implode (exploden (arg i))))) ! 114: " " mesg))))) ! 115: ! 116: (def err ! 117: ;; (err value [junk]) ! 118: ;; This is here for maclisp compatibility. junk should be nil, ! 119: ;; but we don't verify. ! 120: ;; The value is both to be printed and to be returned from the ! 121: ;; errset. 'err-with-message' should be used for new code ! 122: (lexpr (n) ! 123: (cond ((eq n 0) ! 124: (err-with-message "call to err")) ! 125: ((or (eq n 1) (eq n 2)) ! 126: (err-with-message (arg 1) (arg 1))) ! 127: (t (error "wrong number of args to err:" n))))) ! 128: ! 129: ! 130: ;--- append : append two or more lists ! 131: ; the result will be a copy of all but the last list ! 132: ; ! 133: (declare (localf append2args)) ! 134: ! 135: (def append ! 136: (lexpr (nargs) ! 137: (cond ((eq nargs 2) (append2args (arg 1) (arg 2))) ! 138: ((zerop nargs) nil) ! 139: (t (do ((i (1- nargs) (1- i)) ! 140: (res (arg nargs))) ! 141: ((zerop i) res) ! 142: (setq res (append2args (arg i) res))))))) ! 143: ! 144: ;--- append2args : append just two args ! 145: ; a version of append which only works on 2 arguments ! 146: ; ! 147: (def append2args ! 148: (lambda (x y) ! 149: (prog (l l*) ! 150: (cond ((null x) (return y)) ! 151: ((atom x) (error "Non-list to append:" x))) ! 152: (setq l* (setq l (cons (car x) nil))) ! 153: loop (cond ((atom x) (error "Non-list to append:" x)) ! 154: ((setq x (cdr x)) ! 155: (setq l* (cdr (rplacd l* (cons (car x) nil)))) ! 156: (go loop))) ! 157: (rplacd l* y) ! 158: (return l)))) ! 159: ! 160: ;--- append1 : add object to end of list ! 161: ; adds element y to then end of a copy of list x ! 162: ; ! 163: (def append1 (lambda (x y) (append x (list y)))) ! 164: ! 165: ;--- assoc - x : lispval ! 166: ; - l : list ! 167: ; l is a list of lists. The list is examined and the first ! 168: ; sublist whose car equals x is returned. ! 169: ; ! 170: (def assoc ! 171: (lambda (val alist) ! 172: (do ((al alist (cdr al))) ! 173: ((null al) nil) ! 174: (cond ((null (car al))) ! 175: ((not (dtpr (car al))) ! 176: (error "bad arg to assoc" al)) ! 177: ((equal val (caar al)) (return (car al))))))) ! 178: ! 179: ;--- rassq : like assq but look at the cdr instead of the car ! 180: ; ! 181: (def rassq ! 182: (lambda (form list) ! 183: (cond ((null list) nil) ! 184: ((not (dtpr list)) ! 185: (error "rassq: illegal second argument: " list)) ! 186: (t (do ((ll list (cdr ll))) ! 187: ((null ll) nil) ! 188: (cond ((eq form (cdar ll)) (return (car ll))))))))) ! 189: ;--- concatl - l : list of atoms ! 190: ; returns the list of atoms concatentated ! 191: ; ! 192: (def concatl ! 193: (lambda (x) (apply 'concat x))) ! 194: ! 195: ;--- length - l : list ! 196: ; returns the number of elements in the list. ! 197: ; ! 198: (def length ! 199: (lambda ($l$) ! 200: (cond ((and $l$ (not (dtpr $l$))) ! 201: (error "length: non list argument: " $l$)) ! 202: (t (cond ((null $l$) 0) ! 203: (t (do ((ll (cdr $l$) (cdr ll)) ! 204: (i 1 (1+ i))) ! 205: ((null ll) i)))))))) ! 206: ! 207: ;--- memq - arg : (probably a symbol) ! 208: ; - lis : list ! 209: ; returns part of lis beginning with arg if arg is in lis ! 210: ; ! 211: (def memq ! 212: (lambda ($a$ $l$) ! 213: (do ((ll $l$ (cdr ll))) ! 214: ((null ll) nil) ! 215: (cond ((eq $a$ (car ll)) (return ll)))))) ! 216: ! 217: ;--- nconc - x1 x2 ...: lists ! 218: ; The cdr of the last cons cell of xi is set to xi+1. This is the ! 219: ; structure modification version of append ! 220: ; ! 221: ! 222: (def nconc ! 223: (lexpr (nargs) ! 224: (cond ((eq nargs '2) ! 225: (cond ((null (arg 1)) (arg 2)) ! 226: (t (do ((tmp (arg 1) (cdr tmp))) ! 227: ((null (cdr tmp)) ! 228: (rplacd tmp (arg 2)) ! 229: (arg 1)))))) ! 230: ((zerop nargs) nil) ! 231: (t (do ((i 1 nxt) ! 232: (nxt 2 (1+ nxt)) ! 233: (res (cons nil (arg 1)))) ! 234: ((eq i nargs) (cdr res)) ! 235: (cond ((arg i) (rplacd (last (arg i)) (arg nxt))) ! 236: (t (rplacd (last res) (arg nxt))))))))) ! 237: ! 238: ! 239: ! 240: (declare (localf nreverse1)) ; quick fcn shared by nreverse and nreconc ! 241: ! 242: ;--- nreconc :: nreverse and nconc ! 243: ; (nreconc list elemt) is equiv to (nconc (nreverse list) element) ! 244: ; ! 245: (defun nreconc (list element) ! 246: (cond ((null list) element) ! 247: (t (nreverse1 list element)))) ! 248: ! 249: ;--- nreverse - l : list ! 250: ; reverse the list in place ! 251: ; ! 252: ! 253: (defun nreverse (x) ! 254: (cond ((null x) x) ! 255: (t (nreverse1 x nil)))) ! 256: ! 257: ! 258: ;--- nreverse1 ! 259: ; common local function to nreconc and nreverse. [This can just be ! 260: ; nreconc when I get local global functions allow in the compiler -jkf] ! 261: ; ! 262: (defun nreverse1 (x ele) ! 263: (prog (nxt) ! 264: loop ! 265: (setq nxt (cdr x)) ! 266: (rplacd x ele) ! 267: (setq ele x) ! 268: (cond (nxt (setq x nxt) (go loop))) ! 269: (return x))) ! 270: ! 271: ;--- liszt-declare :: this is defined in the compiler ! 272: ; we give it a null definition in the interpreter ! 273: ; ! 274: (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.