|
|
1.1 ! root 1: ! 2: (setsyntax '\; 'splicing 'zapline) ! 3: ! 4: ;---------------- auxfns0 --------------- ! 5: ; this file contains the definitions of the most common functions. ! 6: ; It should only be loaded in Opus 30 Franz Lisp. ! 7: ; These functions should be loaded into every lisp. ! 8: ; ! 9: ;------------------------------------------------ ! 10: ; preliminaries: ! 11: ! 12: (eval-when (eval load) ! 13: (cond ((null (getd 'back=quotify)) (load 'backquote)))) ! 14: ! 15: (eval-when (compile) ! 16: (setq macros t)) ! 17: ! 18: ! 19: ;--- declare - ignore whatever is given, this is for the compiler ! 20: ; ! 21: (def declare (nlambda (x) nil)) ! 22: ! 23: ;----------------------------------------------- ! 24: ; functions contained herein: ! 25: ! 26: ; ---------------------------------- ! 27: ; macros ! 28: ! 29: ;--- catch form [tag] ! 30: ; catch is now a macro which translates to (*catch 'tag form) ! 31: ; ! 32: (def catch ! 33: (macro (l) ! 34: `(*catch ',(caddr l) ,(cadr l)))) ! 35: ;--- throw form [tag] ! 36: ; throw isnow a macro ! 37: ; ! 38: (def throw ! 39: (macro (l) ! 40: `(*throw ',(caddr l) ,(cadr l)))) ! 41: ! 42: ! 43: ; defmacro for franz, written 20sep79 by jkf ! 44: ! 45: (declare (special defmacrooptlist)) ! 46: ! 47: ;--- defmacro - name - name of macro being defined ! 48: ; - pattrn - formal arguments plus other fun stuff ! 49: ; - body - body of the macro ! 50: ; This is an intellegent macro creator. The pattern may contain ! 51: ; symbols which are formal paramters, lists which show how the ! 52: ; actual paramters will appear in the args, and these key words ! 53: ; &rest name - the rest of the args (or nil if there are no other args) ! 54: ; is bound to name ! 55: ; &optional name - bind the next arg to name if it exists, otherwise ! 56: ; bind it to nil ! 57: ; &optional (name init) - bind the next arg to name if it exists, otherwise ! 58: ; bind it to init evaluted. (the evaluation is done left ! 59: ; to right for optional forms) ! 60: ; &optional (name init given) - bind the next arg to name and given to t ! 61: ; if the arg exists, else bind name to the value of ! 62: ; init and given to nil. ! 63: ; ! 64: ; Method of operation: ! 65: ; the list returned from defmcrosrc has the form ((cxxr name) ...) ! 66: ; where cxxr is the loc of the macro arg and name is it formal name ! 67: ; defmcrooptlist has the form ((initv cxxr name) ...) ! 68: ; which is use for &optional args with an initial value. ! 69: ; here cxxr looks like cdd..dr which will test of the arg exists. ! 70: ; ! 71: ; the variable defmacro-for-compiling determines if the defmacro forms ! 72: ; will be compiled. If it is t, then we return (progn 'compile (def xx..)) ! 73: ; to insure that it is compiled ! 74: ; ! 75: (cond ((null (boundp 'defmacro-for-compiling)) ; insure it has a value ! 76: (setq defmacro-for-compiling nil))) ! 77: ! 78: (def defmacro ! 79: (macro (args) ! 80: ((lambda (tmp tmp2 defmacrooptlist body) ! 81: (setq tmp (defmcrosrch (caddr args) '(d r) nil) ! 82: body ! 83: `(def ,(cadr args) ! 84: (macro (defmacroarg) ! 85: ((lambda ,(mapcar 'cdr tmp) ! 86: ,@(mapcar ! 87: '(lambda (arg) ! 88: `(cond ((setq ,(caddr arg) ! 89: (,(cadr arg) ! 90: defmacroarg)) ! 91: ,@(cond ((setq tmp2 (cadddr arg)) ! 92: `((setq ,tmp2 t)))) ! 93: (setq ,(caddr arg) ! 94: (car ,(caddr arg)))) ! 95: (t (setq ,(caddr arg) ! 96: ,(car arg))))) ! 97: defmacrooptlist) ! 98: ,@(cdddr args)) ! 99: ,@(mapcar '(lambda (arg) ! 100: (cond ((car arg) ! 101: `(,(car arg) defmacroarg)))) ! 102: tmp))))) ! 103: (cond (defmacro-for-compiling `(progn 'compile ,body)) ! 104: (t body))) ! 105: nil nil nil nil))) ! 106: ! 107: (def defmcrosrch ! 108: (lambda (pat form sofar) ! 109: (cond ((null pat) sofar) ! 110: ((atom pat) (cons (cons (concatl `(c ,@form)) pat) ! 111: sofar)) ! 112: ((eq (car pat) '&rest) ! 113: (defmcrosrch (cadr pat) form sofar)) ! 114: ((eq (car pat) '&optional) ! 115: (defmcrooption (cdr pat) form sofar)) ! 116: (t (append (defmcrosrch (car pat) (cons 'a form) nil) ! 117: (defmcrosrch (cdr pat) (cons 'd form) sofar)))))) ! 118: ! 119: (def defmcrooption ! 120: (lambda (pat form sofar) ! 121: ((lambda (tmp tmp2) ! 122: (cond ((null pat) sofar) ! 123: ((eq (car pat) '&rest) ! 124: (defmcrosrch (cadr pat) form sofar)) ! 125: (t (cond ((atom (car pat)) ! 126: (setq tmp (car pat))) ! 127: (t (setq tmp (caar pat)) ! 128: (setq defmacrooptlist ! 129: `((,(cadar pat) ! 130: ,(concatl `(c ,@form)) ! 131: ,tmp ! 132: ,(setq tmp2 (caddar pat))) ! 133: . ,defmacrooptlist)))) ! 134: (defmcrooption ! 135: (cdr pat) ! 136: (cons 'd form) ! 137: `( (,(concatl `(ca ,@form)) . ,tmp) ! 138: ,@(cond (tmp2 `((nil . ,tmp2)))) ! 139: . ,sofar))))) ! 140: nil nil))) ! 141: ! 142: ;----------------- ! 143: ; functions which must be defined first ! 144: ! 145: (def FPEINT ! 146: (lambda (x$) (patom '"Floating Exception: ") (drain poport) (break))) ! 147: ! 148: (def INT ! 149: (lambda (dummy) (patom '"Interrupt: ") (drain poport) (break))) ! 150: ! 151: ! 152: (signal 8 'FPEINT) ! 153: (signal 2 'INT) ! 154: ! 155: ! 156: (cond ((null (boundp '$gcprint$)) ! 157: (setq $gcprint$ nil))) ; dont print gc stats by default ! 158: ! 159: (cond ((null (boundp '$gccount$)) ! 160: (setq $gccount$ 0))) ! 161: ! 162: ;--- prtpagesused - [arg] : type of page allocated last time. ! 163: ; prints a summary of pages used for certain selected types ! 164: ; of pages. If arg is given we put a star beside that type ! 165: ; of page. This is normally called after a gc. ! 166: ; ! 167: (def prtpagesused ! 168: (nlambda (arg) ! 169: (patom '"[") ! 170: (do ((curtypl '(list fixnum symbol string ) (cdr curtypl)) ! 171: (temp)) ! 172: ((null curtypl) (patom '"]") (terpr poport)) ! 173: (setq temp (car curtypl)) ! 174: (cond ((greaterp (cadr (opval temp)) 0) ! 175: (cond ((eq (car arg) temp) ! 176: (patom '*))) ! 177: (patom temp) ! 178: (patom '":") ! 179: (print (cadr (opval temp))) ! 180: (patom '"{") ! 181: (print (fix (quotient ! 182: (times 100.0 ! 183: (car (opval temp))) ! 184: (times (cadr (opval temp)) ! 185: (caddr (opval temp)))))) ! 186: (patom '"%}") ! 187: (patom '"; ")))))) ! 188: ! 189: ;--- gcafter - [s] : type of item which ran out forcing garbage collection. ! 190: ; This is called after each gc. ! 191: ; ! 192: (def gcafter ! 193: (nlambda (s) ! 194: (prog (x) ! 195: (cond ((null s) (return))) ! 196: (cond ((null (boundp '$gccount$)) (setq $gccount$ 0))) ! 197: (setq $gccount$ (add1 $gccount$)) ! 198: (setq x (opval (car s))) ! 199: (cond ((greaterp ! 200: (quotient (car x) ! 201: (times 1.0 (cadr x) (caddr x))) ! 202: .65) ! 203: (allocate (car s) 20)) ! 204: (t (allocate (car s) 10))) ! 205: (cond ($gcprint$ (apply 'prtpagesused s)))))) ! 206: ! 207: ;-------------------------------- ! 208: ; functions in alphabetical order ! 209: ! 210: ;--- append - x : list ! 211: ; - y : list ! 212: ; ! 213: (def append2args ! 214: (lambda (x y) ! 215: (prog (l l*) ! 216: (cond ((null x) (return y)) ! 217: ((atom x) (err (list '"Non-list to append:" x)))) ! 218: (setq l* (setq l (cons (car x) nil))) ! 219: loop (cond ((atom x) (err (list '"Non-list to append:" x))) ! 220: ((setq x (cdr x)) ! 221: (setq l* (cdr (rplacd l* (cons (car x) nil)))) ! 222: (go loop))) ! 223: (rplacd l* y) ! 224: (return l)))) ! 225: ! 226: (def append ! 227: (lexpr (nargs) ! 228: (cond ((zerop nargs) nil) ! 229: (t (do ((i (sub1 nargs) (sub1 i)) ! 230: (res (arg nargs))) ! 231: ((zerop i) res) ! 232: (setq res (append2args (arg i) res))))))) ! 233: ! 234: ! 235: ! 236: ;--- append1 - x : list ! 237: ; - y : lispval ! 238: ; puts y at the end of list x ! 239: ; ! 240: (def append1 (lambda (x y) (append x (list y)))) ! 241: ! 242: ! 243: ;--- assoc - x : lispval ! 244: ; - l : list ! 245: ; l is a list of lists. The list is examined and the first ! 246: ; sublist whose car equals x is returned. ! 247: ; ! 248: (def assoc ! 249: (lambda (val alist) ! 250: (do ((al alist (cdr al))) ! 251: ((null al) nil) ! 252: (cond ((equal val (caar al)) (return (car al))))))) ! 253: ! 254: ; sassoc and sassq, silly relatives from lisp 1.5 of assoc ! 255: ; ! 256: ! 257: (defun sassoc(x y z) ! 258: (or (assoc x y) ! 259: (apply z nil))) ! 260: (defun sassq(x y z) ! 261: (or (assq x y) ! 262: (apply z nil))) ! 263: ! 264: ;--- bigp - x : lispval ! 265: ; returns t if x is a bignum ! 266: ; ! 267: (def bigp (lambda (arg) (equal (type arg) 'bignum))) ! 268: ! 269: ;--- comment - any ! 270: ; ignores the rest of the things in the list ! 271: (def comment ! 272: (nlambda (x) 'comment)) ! 273: ! 274: ;--- concatl - l : list of atoms ! 275: ; returns the list of atoms concatentated ! 276: ; ! 277: (def concatl ! 278: (lambda (x) (apply 'concat x))) ! 279: ! 280: ! 281: ! 282: ;--- copy - l : list (will work if atom but will have no effect) ! 283: ; makes a copy of the list. ! 284: ; ! 285: (def copy ! 286: (lambda (l) ! 287: (cond ((atom l) l) ! 288: (t (cons (copy (car l)) (copy (cdr l))))))) ! 289: ! 290: ! 291: ;--- cvttomaclisp - converts the readtable to a maclisp character syntax ! 292: ; ! 293: (def cvttomaclisp ! 294: (lambda nil ! 295: (setsyntax '\| 138.) ; double quoting char ! 296: (setsyntax '\/ 143.) ; escape ! 297: (setsyntax '\\ 2) ; normal char ! 298: (setsyntax '\" 2) ; normal char ! 299: (setsyntax '\[ 2) ; normal char ! 300: (setsyntax '\] 2) ; normal char ! 301: (sstatus uctolc t))) ! 302: ! 303: ! 304: ;--- defun - standard maclisp function definition form. ! 305: ; ! 306: (def defun ! 307: (macro (l) ! 308: (prog (name type arglist body) ! 309: (setq name (cadr l) l (cddr l)) ! 310: (cond ((null (car l)) (setq type 'lambda)) ! 311: ((eq 'fexpr (car l)) (setq type 'nlambda l (cdr l))) ! 312: ((eq 'expr (car l)) (setq type 'lambda l (cdr l))) ! 313: ((eq 'macro (car l)) (setq type 'macro l (cdr l))) ! 314: ((atom (car l)) (setq type 'lexpr ! 315: l `((,(car l)) ,@(cdr l)))) ! 316: (t (setq type 'lambda))) ! 317: (return `(def ,name ! 318: (,type ,@l)))))) ! 319: ! 320: ! 321: ;--- defprop - like putprop except args are not evaled ! 322: ; ! 323: (def defprop ! 324: (nlambda (argl) ! 325: (putprop (car argl) (cadr argl) (caddr argl) ))) ! 326: ! 327: ;--- delete - val - s-expression ! 328: ; - list - list to delete fromm ! 329: ; -[n] optional count , if not specified, it is infinity ! 330: ; delete removes every thing in the top level of list which equals val ! 331: ; the list structure is modified ! 332: ; ! 333: (def delete ! 334: (lexpr (nargs) ! 335: ((lambda (val list n) ! 336: (cond ((or (atom list) (zerop n)) list) ! 337: ((equal val (car list)) ! 338: (delete val (cdr list) (sub1 n))) ! 339: (t (rplacd list (delete val (cdr list) n))))) ! 340: (arg 1) ! 341: (arg 2) ! 342: (cond ((equal nargs 3) (arg 3)) ! 343: (t 99999999))))) ! 344: ! 345: ! 346: ;--- delq - val - s-expression ! 347: ; - list - list to delete fromm ! 348: ; -[n] optional count , if not specified, it is infinity ! 349: ; delq removes every thing in the top level of list which eq's val ! 350: ; the list structure is modified ! 351: ; ! 352: (def delq ! 353: (lexpr (nargs) ! 354: ((lambda (val list n) ! 355: (cond ((or (atom list) (zerop n)) list) ! 356: ((eq val (car list)) ! 357: (delq val (cdr list) (sub1 n))) ! 358: (t (rplacd list (delq val (cdr list) n))))) ! 359: (arg 1) ! 360: (arg 2) ! 361: (cond ((equal nargs 3) (arg 3)) ! 362: (t -1))))) ! 363: ! 364: ;--- evenp : num - return ! 365: ; ! 366: (def evenp ! 367: (lambda (n) ! 368: (cond ((not (zerop (boole 4 1 n))) t)))) ! 369: ! 370: ;--- ex [name] : unevaluated name of file to edit. ! 371: ; the ex editor is forked to edit the given file, if no ! 372: ; name is given the previous name is used ! 373: ; ! 374: (def ex ! 375: (nlambda (x) ! 376: (prog (handy handyport bigname) ! 377: (cond ((null x) (setq x (list edit_file))) ! 378: (t (setq edit_file (car x)))) ! 379: (setq bigname (concat (car x) '".l")) ! 380: (cond ((setq handyport (car (errset (infile bigname) nil))) ! 381: (close handyport) ! 382: (setq handy bigname)) ! 383: (t (setq handy (car x)))) ! 384: (setq handy (concat '"ex " handy)) ! 385: (setq handy (list 'process handy)) ! 386: (eval handy)))) ! 387: ! 388: ;--- exec - arg1 [arg2 [arg3 ...] ] unevaluated atoms ! 389: ; A string of all the args concatenated together seperated by ! 390: ; blanks is forked as a process. ! 391: ; ! 392: (def exec ! 393: (nlambda ($list) ! 394: (prog ($handy) ! 395: (setq $handy (quote "")) ! 396: loop (cond ((null $list) ! 397: (return (eval (list (quote process) $handy)))) ! 398: (t (setq $handy ! 399: (concat (concat $handy (car $list)) ! 400: (quote " "))) ! 401: (setq $list (cdr $list)) ! 402: (go loop)))))) ! 403: ! 404: ! 405: ;--- exl - [name] : unevaluated name of file to edit and load. ! 406: ; If name is not given the last file edited will be used. ! 407: ; After the file is edited it will be `load'ed into lisp. ! 408: ; ! 409: (def exl (nlambda (fil) (cond (fil (setq edit_file (car fil)))) ! 410: (eval (list 'ex edit_file)) ! 411: (load edit_file))) ! 412: ! 413: ;----- explode functions ------- ! 414: ; These functions, explode , explodec and exploden, implement the ! 415: ; maclisp explode functions completely. ! 416: ; They have a similar structure and are written with efficiency, not ! 417: ; beauty in mind (and as a result they are quite ugly) ! 418: ; The basic idea in all of them is to keep a pointer to the last ! 419: ; thing added to the list, and rplacd the last cons cell of it each time. ! 420: ; ! 421: ;--- explode - arg : lispval ! 422: ; explode returns a list of characters which print would use to ! 423: ; print out arg. Slashification is included. ! 424: ; ! 425: (def explode ! 426: (lambda (arg) ! 427: (cond ((atom arg) (aexplode arg)) ! 428: (t (do ((ll (cdr arg) (cdr ll)) ! 429: (sofar (setq arg (cons '"(" (explode (car arg))))) ! 430: (xx)) ! 431: ((cond ((null ll) (rplacd (last sofar) (ncons '")" )) ! 432: t) ! 433: ((atom ll) (rplacd (last sofar) ! 434: `(" " "." " " ,@(explode ll) ! 435: ,@(ncons '")"))) ! 436: t)) ! 437: arg) ! 438: (setq xx (last sofar) ! 439: sofar (cons '" " (explode (car ll)))) ! 440: (rplacd xx sofar)))))) ! 441: ! 442: ;--- explodec - arg : lispval ! 443: ; returns the list of character which would be use to print arg assuming that ! 444: ; patom were used to print all atoms. ! 445: ; that is, no slashification would be used. ! 446: ; ! 447: (def explodec ! 448: (lambda (arg) ! 449: (cond ((atom arg) (aexplodec arg)) ! 450: (t (do ((ll (cdr arg) (cdr ll)) ! 451: (sofar (setq arg (cons '"(" (explodec (car arg))))) ! 452: (xx)) ! 453: ((cond ((null ll) (rplacd (last sofar) (ncons '")" )) ! 454: t) ! 455: ((atom ll) (rplacd (last sofar) ! 456: `(" " "." " " ,@(explodec ll) ! 457: ,@(ncons '")"))) ! 458: t)) ! 459: arg) ! 460: (setq xx (last sofar) ! 461: sofar (cons '" " (explodec (car ll)))) ! 462: (rplacd xx sofar)))))) ! 463: ! 464: ;--- exploden - arg : lispval ! 465: ; returns a list just like explodec, except we return fixnums instead ! 466: ; of characters. ! 467: ; ! 468: (def exploden ! 469: (lambda (arg) ! 470: (cond ((atom arg) (aexploden arg)) ! 471: (t (do ((ll (cdr arg) (cdr ll)) ! 472: (sofar (setq arg (cons 40. (exploden (car arg))))) ! 473: (xx)) ! 474: ((cond ((null ll) (rplacd (last sofar) (ncons 41.)) ! 475: t) ! 476: ((atom ll) (rplacd (last sofar) ! 477: `(32. 46. 32. ,@(exploden ll) ! 478: ,@(ncons 41.))) ! 479: t)) ! 480: arg) ! 481: (setq xx (last sofar) ! 482: sofar (cons 32. (exploden (car ll)))) ! 483: (rplacd xx sofar)))))) ! 484: ! 485: ;-- expt - x ! 486: ; - y ! 487: ; ! 488: ; y ! 489: ; returns x ! 490: ; ! 491: (defun expt(x y) ! 492: (cond ((or (floatp y) (lessp y 0)) ! 493: (exp(times y (log x)))) ; bomb out for (-3)^4 or (-3)^4.0 or 0^y. ! 494: (t ; y is integer, y>= 0 ! 495: (prog (res) ! 496: (setq res 1) ! 497: loop ! 498: (cond ((equal y 0) (return res)) ! 499: ((oddp y)(setq res (times res x) y (sub1 y))) ! 500: (t (setq x (times x x) y (quotient y 2)))) ! 501: (go loop))))) ! 502: ! 503: ! 504: ;--- expt ! 505: ; old ! 506: '(defun expt(x y) ! 507: (prog (res) ! 508: (setq res 1) ! 509: loop (cond ((equal y 0) (return res)) ! 510: (t (setq res (times x res) ! 511: y (sub1 y)))) ! 512: (go loop))) ! 513: ! 514: ;--- fixp - l : lispval ! 515: ; returns t if l is a fixnum or bignum ! 516: ; ! 517: (defun fixp (x) (or (equal (type x) 'fixnum) ! 518: (equal (type x) 'bignum))) ! 519: ! 520: ! 521: ;--- floatp - l : lispval ! 522: ; returns t if l is a flonum ! 523: ; ! 524: (defun floatp (x) (equal 'flonum (type x))) ! 525: ! 526: ! 527: ;--- getchar,getcharn - x : atom ! 528: ; - n : fixnum ! 529: ; returns the n'th character of x's pname (the first corresponds to n=1) ! 530: ; if n is out of bounds, nil is return ! 531: (def getchar ! 532: (lambda (x n) ! 533: (cond ((lessp n 1) nil) ! 534: (t (do ((i n (sub1 i)) ! 535: (lis (aexplodec x) (cdr lis))) ! 536: ((cond ((null lis) (return nil)) ! 537: ((equal i 1) (return (car lis)))))))))) ! 538: ! 539: (def getcharn ! 540: (lambda (x n) ! 541: (cond ((lessp n 1) nil) ! 542: (t (do ((i n (sub1 i)) ! 543: (lis (aexploden x) (cdr lis))) ! 544: ((cond ((null lis) (return nil)) ! 545: ((equal i 1) (return (car lis)))))))))) ! 546: ! 547: ! 548: (def getl ! 549: (lambda (atm lis) ! 550: (do ((ll (cond ((atom atm) (plist atm)) ! 551: (t (cdr atm))) ! 552: (cddr ll))) ! 553: ((null ll) nil) ! 554: (cond ((member (car ll) lis) (return ll)))))) ! 555: ! 556: ;--- last - l : list ! 557: ; returns the last cons cell of the list, NOT the last element ! 558: ; ! 559: (def last ! 560: (lambda (a) ! 561: (do ((ll a (cdr ll))) ! 562: ((null (cdr ll)) ll)))) ! 563: ! 564: ;--- include - read in the file name given ! 565: ; ! 566: (def include (nlambda (l) (load (car l)))) ! 567: ! 568: ;--- length - l : list ! 569: ; returns the number of elements in the list. ! 570: ; ! 571: (def length ! 572: (lambda ($l$) ! 573: (cond ((atom $l$) 0)) ! 574: (do ((ll $l$ (cdr ll)) ! 575: (i 0 (add1 i))) ! 576: ((null ll) i)))) ! 577: ! 578: ! 579: ;--- let - vb - binding forms ! 580: ; - bd - body ! 581: ; this macro allow one to express lambda binding for certain ! 582: ; variables and keep the information together. ! 583: ; the binding forms have this form ! 584: ; (vrbl (vrbl2 val2) ) ! 585: ; here vrbl will be bound to nil, and vrbl2 will be bound to the ! 586: ; result of evaluating val2 ! 587: ; the general form using let is ! 588: ; (let (vrbl1 (vrbl2 val2)) ! 589: ; .. body .. ! 590: ; ) ! 591: ; ! 592: (def let ! 593: (macro (l) ! 594: `((lambda ,(mapcar '(lambda (x) (cond ((atom x) x) ! 595: (t (car x)))) ! 596: (cadr l)) ! 597: ,@(cddr l)) ! 598: ,@(mapcar '(lambda (x) (cond ((atom x) nil) ! 599: (t (cadr x)))) ! 600: (cadr l))))) ! 601: ! 602: ! 603: ;--- listify : n - integer ! 604: ; returns a list of the first n args to the enclosing lexpr if ! 605: ; n is positive, else returns the last -n args to the lexpr if n is ! 606: ; negative. ! 607: ; ! 608: (def listify ! 609: (macro (lis) ! 610: `(let ((n ,(cadr lis))) ! 611: (cond ((minusp n) ! 612: (do ((i (arg nil) (1- i)) ! 613: (result nil (cons (arg i) result))) ! 614: ((< i (+ (arg nil) n 1)) result) )) ! 615: (t (do ((i n (1- i)) ! 616: (result nil (cons (arg i) result))) ! 617: ((< i 1) result) )))))) ! 618: ! 619: ;--- macroexpand - form ! 620: ; expands out all macros it can ! 621: ; ! 622: (def macroexpand ! 623: (lambda (form) ! 624: (prog nil ! 625: top (cond ((atom form) (return form)) ! 626: ((atom (car form)) ! 627: (return ! 628: (let ((nam (car form)) def disc) ! 629: (setq def (getd nam)) ! 630: (setq disc (cond ((bcdp def) (getdisc def)) ! 631: (t (car def)))) ! 632: (cond ((memq disc '(lambda lexpr nil)) ! 633: (cons nam (mapcar 'macroexpand (cdr form)))) ! 634: ((eq disc 'nlambda) form) ! 635: ((eq disc 'macro) ! 636: (setq form ! 637: (apply (cond ((bcdp def) ! 638: (mfunction (getentry def) ! 639: 'nlambda)) ! 640: (t (cons 'nlambda ! 641: (cdr def)))) ! 642: form)) ! 643: (go top)))))) ! 644: (t (return (cons (macroexpand (car form)) ! 645: (mapcar 'macroexpand (cdr form))))))))) ! 646: ! 647: ! 648: ;--- max - arg1 arg2 ... : sequence of numbe ! 649: ; returns the maximum ! 650: ; ! 651: (def max ! 652: (lexpr (nargs) ! 653: (do ((i nargs (sub1 i)) ! 654: (max (arg 1))) ! 655: ((lessp i 2) max) ! 656: (cond ((greaterp (arg i) max) (setq max (arg i))))))) ! 657: ! 658: ! 659: ! 660: ! 661: ;--- member - VAL : lispval ! 662: ; - LIS : list ! 663: ; returns that portion of LIS beginning with the first occurance ! 664: ; of VAL if VAL is found at the top level of list LIS. ! 665: ; uses equal for comparisons. ! 666: ; ! 667: (def member ! 668: (lambda ($a$ $l$) ! 669: (do ((ll $l$ (cdr ll))) ! 670: ((null ll) nil) ! 671: (cond ((equal $a$ (car ll)) (return ll)))))) ! 672: ! 673: ;--- memq - arg : (probably a symbol) ! 674: ; - lis : list ! 675: ; returns part of lis beginning with arg if arg is in lis ! 676: ; ! 677: (def memq ! 678: (lambda ($a$ $l$) ! 679: (do ((ll $l$ (cdr ll))) ! 680: ((null ll) nil) ! 681: (cond ((eq $a$ (car ll)) (return ll)))))) ! 682: ! 683: ;--- min - arg1 ... numbers ! 684: ; ! 685: ; returns minimum of n numbers. ! 686: ; ! 687: ! 688: (def min ! 689: (lexpr (nargs) ! 690: (do ((i nargs (sub1 i)) ! 691: (min (arg 1))) ! 692: ((lessp i 2) min) ! 693: (cond ((lessp (arg i) min) (setq min (arg i))))))) ! 694: ! 695: ;--- nconc - x1 x2 ...: lists ! 696: ; The cdr of the last cons cell of xi is set to xi+1. This is the ! 697: ; structure modification version of append ! 698: ; ! 699: (def nconc ! 700: (lexpr (nargs) ! 701: (cond ((zerop nargs) nil) ! 702: (t (do ((i 1 nxt) ! 703: (nxt 2 (add1 nxt)) ! 704: (res (cons nil (arg 1)))) ! 705: ((equal i nargs) (cdr res)) ! 706: (cond ((arg i) (rplacd (last (arg i)) (arg nxt))) ! 707: (t (rplacd (last res) (arg nxt))))))))) ! 708: ! 709: ! 710: ;--- nreverse - l : list ! 711: ; reverse the list in place ! 712: ; ! 713: (defun nreverse (x) ! 714: (cond ((null x) nil) ! 715: (t (n$reverse1 x nil)))) ! 716: ! 717: (defun n$reverse1 (x y) ! 718: (cond ((null (cdr x)) (rplacd x y)) ! 719: (t (n$reverse1 (cdr x) (rplacd x y))))) ! 720: ! 721: (def oddp ! 722: (lambda (n) ! 723: (cond ((not (zerop (boole 1 1 n))) t)))) ! 724: ! 725: ;--- plusp : x - number ! 726: ; returns t iff x is greater than zero ! 727: ! 728: (def plusp ! 729: (lambda (x) ! 730: (greaterp x 0))) ! 731: ! 732: ;--- reverse : l - list ! 733: ; returns the list reversed using cons to create new list cells. ! 734: ; ! 735: (def reverse ! 736: (lambda (x) ! 737: (cond ((null x) nil) ! 738: (t (do ((cur (cons (car x) nil) ! 739: (cons (car res) cur)) ! 740: (res (cdr x) (cdr res))) ! 741: ((null res) cur)))))) ! 742: ! 743: ;--- shell - invoke a new c shell ! 744: ; ! 745: (def shell (lambda nil (process csh))) ! 746: ! 747: ! 748: ! 749: ;--- signp - test - unevaluated atom ! 750: ; - value - evaluated value ! 751: ; test can be l, le, e, n, ge or g with the obvious meaning ! 752: ; we return t if value compares to 0 by test ! 753: (def signp ! 754: (macro (l) ! 755: `(signphelpfcn ',(cadr l) ,(caddr l)))) ! 756: ! 757: ;-- signphelpfcn ! 758: (def signphelpfcn ! 759: (lambda (tst val) ! 760: (cond ((eq 'l tst) (minusp val 0)) ! 761: ((eq 'le tst) (or (zerop val) (minusp val))) ! 762: ((eq 'e tst) (zerop val)) ! 763: ((eq 'n tst) (not (zerop val))) ! 764: ((eq 'ge tst) (not (minusp val))) ! 765: ((eq 'g tst) (greaterp val 0))))) ! 766: ! 767: ! 768: ;--- sload : fn - file name (must include the .l) ! 769: ; loads in the file printing each result as it is seen ! 770: ; ! 771: (def sload ! 772: (lambda (fn) ! 773: (prog (por) ! 774: (cond ((setq por (infile fn))) ! 775: (t (patom '"bad file name")(terpr)(return nil))) ! 776: (do ((x (read por) (read por))) ! 777: ((eq 'eof x)) ! 778: (print x) ! 779: (eval x))))) ! 780: ! 781: (defun sort(a fun) ! 782: (prog (n) ! 783: (cond ((null a) (return nil)) ;no elements ! 784: (t ! 785: (setq n (length a)) ! 786: (do i 1 (add1 i) (greaterp i n)(sorthelp a fun)) ! 787: (return a) )))) ! 788: ! 789: (defun sorthelp (a fun) ! 790: (cond ((null (cdr a)) a) ! 791: ((funcall fun (cadr a) (car a)) ! 792: (exchange2 a) ! 793: (sorthelp (cdr a) fun)) ! 794: (t (sorthelp (cdr a) fun)))) ! 795: ! 796: (defun exchange2 (a) ! 797: (prog (temp) ! 798: (setq temp (cadr a)) ! 799: (rplaca (cdr a) (car a)) ! 800: (rplaca a temp))) ! 801: ! 802: ;--- sublis: alst - assoc list ((a . val) (b . val2) ...) ! 803: ; exp - s-expression ! 804: ; for each atom in exp which corresponds to a key in alst, the associated ! 805: ; value from alst is substituted. The substitution is done by adding ! 806: ; list cells, no struture mangling is done. Only the minimum number ! 807: ; of list cells will be created. ! 808: ; ! 809: (def sublis ! 810: (lambda (alst exp) ! 811: (let (tmp) ! 812: (cond ((atom exp) ! 813: (cond ((setq tmp (assoc exp alst)) ! 814: (cdr tmp)) ! 815: (t exp))) ! 816: ((setq tmp (sublishelp alst exp)) ! 817: (car tmp)) ! 818: (t exp))))) ! 819: ! 820: ;--- sublishelp : alst - assoc list ! 821: ; exp - s-expression ! 822: ; this function helps sublis work. it is different from sublis in that ! 823: ; it return nil if no change need be made to exp, or returns a list of ! 824: ; one element which is the changed exp. ! 825: ; ! 826: (def sublishelp ! 827: (lambda (alst exp) ! 828: (let (carp cdrp) ! 829: (cond ((atom exp) ! 830: (cond ((setq carp (assoc exp alst)) ! 831: (list (cdr carp))) ! 832: (t nil))) ! 833: (t (setq carp (sublishelp alst (car exp)) ! 834: cdrp (sublishelp alst (cdr exp))) ! 835: (cond ((not (or carp cdrp)) nil) ; no change ! 836: ((and carp (not cdrp)) ; car change ! 837: (list (cons (car carp) (cdr exp)))) ! 838: ((and (not carp) cdrp) ; cdr change ! 839: (list (cons (car exp) (car cdrp)))) ! 840: (t ; both change ! 841: (list (cons (car carp) (car cdrp)))))))))) ! 842: ! 843: ! 844: ;--- subst : new - sexp ! 845: ; old - sexp ! 846: ; patrn - sexp ! 847: ; substitutes in patrn all occurances eq to old with new and returns the ! 848: ; result ! 849: ; MUST be put in the manual ! 850: (def subst ! 851: (lambda (new old patrn) ! 852: (cond ((eq old patrn) new) ! 853: ((atom patrn) patrn) ! 854: (t (cons (subst new old (car patrn)) ! 855: (subst new old (cdr patrn))))))) ! 856: ! 857: ;--- xcons : a - sexp ! 858: ; b - sexp ! 859: ; returns (b . a) that is, it is an exchanged cons ! 860: ; ! 861: (def xcons (lambda (a b) (cons b a))) ! 862: ! 863: ;--------------------------------------- ! 864: ; ARRAY functions . ! 865: ; ! 866: (def array ! 867: (macro ($lis$) ! 868: `(*array ',(cadr $lis$) ',(caddr $lis$) ,@(cdddr $lis$)))) ! 869: ! 870: ! 871: ! 872: ; array access function ! 873: ! 874: (def arracfun ! 875: (lambda (actlst ardisc) ! 876: (prog (diml ind val) ! 877: ! 878: (setq actlst (mapcar 'eval actlst) ! 879: diml (getaux ardisc)) ! 880: ! 881: (cond ((null (equal (length actlst) ! 882: (length (cdr diml)))) ! 883: (break '"Wrong number of indexes to array ref")) ! 884: ! 885: (t (setq ind (arrcomputeind (cdr actlst) ! 886: (cddr diml) ! 887: (car actlst)) ! 888: val (arrayref ardisc ind)) ! 889: (cond ((equal (car diml) t) ! 890: (setq val (eval val)))) ! 891: (return val)))))) ! 892: ! 893: ! 894: ! 895: ! 896: (def *array ! 897: (lexpr (nargs) ! 898: (prog (name type rtype dims size tname) ! 899: ! 900: (setq name (arg 1) ! 901: type (arg 2) ! 902: rtype (cond ((or (null type) ! 903: (equal type t)) ! 904: (setq type t) ; nil is equiv to t ! 905: 'value) ! 906: (t type)) ! 907: dims (do ((i 3 (add1 i)) ! 908: (res nil (cons (arg i) res))) ! 909: ((greaterp i nargs) (nreverse res))) ! 910: size (apply 'times dims)) ! 911: ! 912: (setq tname (marray (segment rtype size) ! 913: (getd 'arracfun) ! 914: (cons type dims) ! 915: size ! 916: (sizeof rtype))) ! 917: (cond (name (set name tname) ! 918: (putd name tname))) ! 919: (return tname)))) ! 920: ! 921: (def arraycall ! 922: (nlambda ($$lis$$) ! 923: ; form (arraycall type name sub1 sub2 ... subn) ! 924: ((lambda (ardisc) ! 925: (cond ((not (equal (car (getaux ardisc))) (car $$lis$$)) ! 926: (patom '" Type given arraycall:") ! 927: (patom (car $$lis$$)) ! 928: (patom '" doesnt match array type:") ! 929: (patom (car (getaux ardisc))) ! 930: (break nil))) ! 931: (apply (getaccess ardisc) ! 932: (list (cddr $$lis$$) ardisc))) ! 933: (eval (cadr $$lis$$))))) ! 934: ! 935: ! 936: ! 937: ! 938: ; function to compute the raw array index ! 939: ! 940: (def arrcomputeind ! 941: (lambda (indl diml res) ! 942: (cond ((null diml) res) ! 943: (t (arrcomputeind (cdr indl) ! 944: (cdr diml) ! 945: (plus (times res (car diml)) ! 946: (car indl))))))) ! 947: ! 948: ; store ! 949: ; we make store a macro to insure that all parts are evaluated at the ! 950: ; right time even if it is compiled. ! 951: ; (store (foo 34 i) (plus r f)) ! 952: ; gets translated to ! 953: ; (storeintern foo (plus r f) (list 34 i)) ! 954: ; and storeintern is a lambda, so when foo is evaluated it will pass the ! 955: ; array descriptor to storeintern, so storeintern can look at the ! 956: ; aux part to determine the type of array. ! 957: ; ! 958: (defmacro store ( (arrname . indexes) value) ! 959: (cond ((eq 'funcall arrname) ! 960: (setq arrname `(eval ,(car indexes)) ! 961: indexes (cdr indexes)))) ! 962: `(storeintern ,arrname ,value (list ,@indexes))) ! 963: ! 964: (def storeintern ! 965: (lambda (arrnam vl actlst) ! 966: (prog (loc) ! 967: (cond ((equal t (car (getaux arrnam))) ! 968: (setq loc (arracfcnsimp actlst arrnam)) ! 969: (set loc vl)) ! 970: ! 971: (t (replace (apply arrnam actlst) vl))) ! 972: (return vl)))) ! 973: ! 974: ! 975: (def arracfcnsimp ! 976: (lambda (indexes adisc) ! 977: (prog (dims) ! 978: (setq dims (cdr (getaux adisc))) ! 979: (cond ((null (equal (length indexes) ! 980: (length dims))) ! 981: (break '"wrong number of indexes to array")) ! 982: (t (setq dims (arrcomputeind (cdr indexes) ! 983: (cdr dims) ! 984: (car indexes))))) ! 985: (return (arrayref adisc dims))))) ! 986: ! 987: (def arraydims (lambda (arg) (cond ((atom arg) (getaux (eval arg))) ! 988: ((arrayp arg) (getaux arg)) ! 989: (t (break '"non array arg to arraydims"))))) ! 990: ! 991: ; fill array from list or array ! 992: ! 993: (def fillarray ! 994: (lambda (arr lis) ! 995: (prog (maxv typept) ! 996: (cond ((atom arr) (setq arr (eval arr)))) ! 997: ! 998: (cond ((atom lis) ! 999: (setq lis (eval lis)) ! 1000: (return (fillarrayarray arr lis))) ! 1001: ! 1002: ((arrayp lis) (return (fillarrayarray arr lis)))) ! 1003: ! 1004: (setq maxv (sub1 (getlength arr)) ! 1005: typept (cond ((equal t (car (getaux arr))) ! 1006: t) ! 1007: (t nil))) ! 1008: (do ((ls lis) ! 1009: (i 0 (add1 i))) ! 1010: ((greaterp i maxv)) ! 1011: ! 1012: (cond (typept (set (arrayref arr i) (car ls))) ! 1013: (t (replace (arrayref arr i) (car ls)))) ! 1014: ! 1015: (cond ((cdr ls) (setq ls (cdr ls)))))))) ! 1016: ! 1017: (def fillarrayarray ! 1018: (lambda (arrto arrfrom) ! 1019: (prog (maxv) ! 1020: (setq maxv (sub1 (min (getlength arrto) ! 1021: (getlength arrfrom)))) ! 1022: (do ((i 0 (add1 i))) ! 1023: ((greaterp i maxv)) ! 1024: (replace (arrayref arrto i) (arrayref arrfrom i)))))) ! 1025: ! 1026: ;---------------------- ! 1027: ; equivalences ! 1028: ! 1029: (putd 'abs (getd 'absval)) ! 1030: (putd 'add (getd 'sum)) ! 1031: (putd 'chrct (getd 'charcnt)) ! 1032: (putd 'diff (getd 'difference)) ! 1033: (putd 'numbp (getd 'numberp)) ! 1034: (putd 'princ (getd 'patom)) ! 1035: (putd 'remainder (getd 'mod)) ! 1036: (putd 'terpri (getd 'terpr)) ! 1037: (putd 'typep (getd 'type)) ! 1038: (putd 'symeval (getd 'eval)) ! 1039: (putd '< (getd 'lessp)) ! 1040: (putd '= (getd 'equal)) ! 1041: (putd '> (getd 'greaterp)) ! 1042: (putd '- (getd 'difference)) ! 1043: (putd '"=" (getd 'equal)) ! 1044: (putd '"/" (getd 'quotient)) ! 1045: (putd '"+" (getd 'add)) ! 1046: (putd '"-" (getd 'difference)) ! 1047: (putd '*dif (getd 'difference)) ! 1048: (putd '\\ (getd 'mod)) ! 1049: (putd '"1+" (getd 'add1)) ! 1050: (putd '"1-" (getd 'sub1)) ! 1051: (putd '* (getd 'times)) ! 1052: (putd '*$ (getd 'times)) ! 1053: (putd '/$ (getd 'quotient)) ! 1054: (putd '+$ (getd 'add)) ! 1055: (putd '-$ (getd 'difference))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.