|
|
1.1 ! root 1: ! 2: ; special atoms: ! 3: (declare (special debug-level-count break-level-count ! 4: errlist tpl-errlist user-top-level ! 5: top-level-eof * - ^w) ! 6: (macros t)) ! 7: ! 8: (setq top-level-eof (gensym 'Q) ! 9: tpl-errlist nil ! 10: errlist nil ! 11: user-top-level nil ) ! 12: ! 13: ;------------------------------------------------------ ! 14: ; Top level function for franz jkf, march 1980 ! 15: ; ! 16: ; The following function contains the top-level read, eval, print ! 17: ; loop. With the help of the error handling functions, ! 18: ; break-err-handler and debug-err-handler, franz-top-level provides ! 19: ; a reasonable enviroment for working with franz lisp. ! 20: ; ! 21: ! 22: (def franz-top-level ! 23: (lambda nil ! 24: (cond ((or (not (boundp 'franz-not-virgin)) ! 25: (null franz-not-virgin)) ! 26: (patom (status version)) ! 27: (setq franz-not-virgin t) ! 28: (setq ER%tpl 'break-err-handler) ! 29: (putd 'reset (getd 'franz-reset)) ! 30: (terpr) ! 31: (read-in-lisprc-file))) ! 32: ! 33: ; loop forever ! 34: (do nil (nil) ! 35: (setq retval ! 36: (*catch ! 37: '(top-level-catch break-catch) ! 38: ; begin or return to top level ! 39: (progn ! 40: (setq debug-level-count 0 break-level-count 0) ! 41: (cond (tpl-errlist (mapc 'eval tpl-errlist))) ! 42: (do ((^w nil nil)) ! 43: (nil) ! 44: (cond (user-top-level (funcall user-top-level)) ! 45: (t (patom "-> ") ! 46: (cond ((eq top-level-eof ! 47: (setq - ! 48: (car (errset (read nil ! 49: top-level-eof))))) ! 50: (cond ((not (status isatty)) ! 51: (exit))) ! 52: (cond ((null (status ignoreeof)) ! 53: (terpr) ! 54: (print 'Goodbye) ! 55: (terpr) ! 56: (exit)) ! 57: (t (terpr) ! 58: (setq - ''EOF))))) ! 59: (setq * (eval -)) ! 60: (print *) ! 61: (terpr))))))) ! 62: (terpr) ! 63: (patom "[Return to top level]") ! 64: (terpr) ! 65: (cond ((eq 'reset retval) (old-reset-function)))))) ! 66: ! 67: ! 68: ; debug-err-handler is the clb of ER%all when we are doing debugging ! 69: ; and we want to catch all errors. ! 70: ; It is just a read eval print loop with errset. ! 71: ; the only way to leave is: ! 72: ; (reset) just back to top level ! 73: ; (return x) return the value, if possible ! 74: ; ^D continue as if this handler wasn't called. ! 75: ; the form of errmsgs is: ! 76: ; (error_type unique_id continuable message_string other_args ...) ! 77: ; ! 78: (def debug-err-handler ! 79: (lexpr (n) ! 80: ((lambda (message debug-level-count retval ^w) ! 81: (cond ((greaterp n 0) ! 82: (print 'Error:) ! 83: (mapc '(lambda (a) (patom " ") (patom a) ) ! 84: (cdddr (arg 1))) ! 85: (terpr))) ! 86: (setq ER%all 'debug-err-handler) ! 87: (do nil (nil) ! 88: (cond ((setq retval ! 89: (dtpr ! 90: (errset ! 91: (do ((form)) (nil) ! 92: (patom "D<") ! 93: (patom debug-level-count) ! 94: (patom ">: ") ! 95: (cond ((eq top-level-eof ! 96: (setq form (read nil top-level-eof))) ! 97: (cond ((null (status isatty)) ! 98: (exit))) ! 99: (return nil)) ! 100: ((and (dtpr form) ! 101: (eq 'return (car form))) ! 102: (cond ((caddr errmsgs) ! 103: (return (ncons (eval (cadr form))))) ! 104: (t (patom "Can't continue from this error")))) ! 105: (t (print (eval form)) ! 106: (terpr))))))) ! 107: (return (car retval)))))) ! 108: nil ! 109: (add1 debug-level-count) ! 110: nil ! 111: nil))) ! 112: ! 113: ; this is the break handler, it should be tied to ! 114: ; ER%tpl always. ! 115: ; it is entered if there is an error which no one wants to handle. ! 116: ; We loop forever, printing out our error level until someone ! 117: ; types a ^D which goes to the next break level above us (or the ! 118: ; top-level if there are no break levels above us. ! 119: ; a (return n) will return that value to the error message ! 120: ; which called us, if that is possible (that is if the error is ! 121: ; continuable) ! 122: ; ! 123: (def break-err-handler ! 124: (lexpr (n) ! 125: ((lambda (message break-level-count retval rettype ^w) ! 126: (setq piport nil) ! 127: (cond ((greaterp n 0) ! 128: (print 'Error:) ! 129: (mapc '(lambda (a) (patom " ") (patom a) ) ! 130: (cdddr (arg 1))) ! 131: (terpr) ! 132: (cond ((caddr (arg 1)) (setq rettyp 'contuab)) ! 133: (t (setq rettyp nil)))) ! 134: (t (setq rettyp 'localcall))) ! 135: ! 136: (do nil (nil) ! 137: (cond ((dtpr ! 138: (setq retval ! 139: (*catch 'break-catch ! 140: (do ((form)) (nil) ! 141: (patom "<") ! 142: (patom break-level-count) ! 143: (patom ">: ") ! 144: (cond ((eq top-level-eof ! 145: (setq form (read nil top-level-eof))) ! 146: (cond ((null (status isatty)) ! 147: (exit))) ! 148: (eval 1) ; force interrupt check ! 149: (return (sub1 break-level-count))) ! 150: ((and (dtpr form) (eq 'return (car form))) ! 151: (cond ((or (eq rettyp 'contuab) ! 152: (eq rettyp 'localcall)) ! 153: (return (ncons (eval (cadr form))))) ! 154: (t (patom "Can't continue from this error") ! 155: (terpr)))) ! 156: ((and (dtpr form) (eq 'retbrk (car form))) ! 157: (cond ((numberp (setq form (eval (cadr form)))) ! 158: (return form)) ! 159: (t (return (sub1 break-level-count))))) ! 160: (t (print (eval form)) ! 161: (terpr))))))) ! 162: (return (cond ((eq rettype 'localcall) ! 163: (car retval)) ! 164: (t retval)))) ! 165: ((lessp retval break-level-count) ! 166: (setq tpl-errlist errlist) ! 167: (*throw 'break-catch retval)) ! 168: (t (terpr))))) ! 169: nil ! 170: (add1 break-level-count) ! 171: nil ! 172: nil ! 173: nil))) ! 174: ! 175: (def debugging ! 176: (lambda (val) ! 177: (cond (val (setq ER%all 'debug-err-handler)) ! 178: (t (setq ER%all nil))))) ! 179: ! 180: ! 181: ; the problem with this definition for break is that we are ! 182: ; forced to put an errset around the break-err-handler. This means ! 183: ; that we will never get break errors, since all errors will be ! 184: ; caught by our errset (better ours than one higher up though). ! 185: ; perhaps the solution is to automatically turn debugmode on. ! 186: ; ! 187: (defmacro break (message &optional (pred t)) ! 188: `(*break ,pred ',message)) ! 189: ! 190: (def *break ! 191: (lambda (pred message) ! 192: (let ((^w nil)) ! 193: (cond ((not (boundp 'break-level-count)) (setq break-level-count 1))) ! 194: (cond (pred (terpr) ! 195: (patom "Break ") ! 196: (patom message) ! 197: (terpr) ! 198: (do ((form)) ! 199: (nil) ! 200: (cond ((dtpr (setq form (errset (break-err-handler)))) ! 201: (return (car form)))))))))) ! 202: ! 203: ! 204: ; this reset function is designed to work with the franz-top-level. ! 205: ; When franz-top-level begins, it makes franz-reset be reset. ! 206: ; when a reset occurs now, we set the global variable tpl-errlist to ! 207: ; the current value of errlist and throw to top level. At top level, ! 208: ; then tpl-errlist will be evaluated. ! 209: ; ! 210: (def franz-reset ! 211: (lambda nil ! 212: (setq tpl-errlist errlist) ! 213: (errset (*throw 'top-level-catch 'reset) ! 214: nil) ! 215: (old-reset-function))) ! 216: ! 217: ! 218: ; this definition will have to do until we have the ability to ! 219: ; cause and error on any channel in franz ! 220: (def error ! 221: (lexpr (n) ! 222: (cond ((greaterp n 0) ! 223: (patom (arg 1)) ! 224: ! 225: (cond ((greaterp n 1) ! 226: (patom " ") ! 227: (patom (arg 2)))) ! 228: (terpr))) ! 229: (err))) ! 230: ! 231: ! 232: ; this file is read in just before dumplisping if you want .lisprc ! 233: ; from your home directory read in before the lisp begins. ! 234: (def read-in-lisprc-file ! 235: (lambda nil ! 236: ((lambda (hom prt) ! 237: (setq break-level-count 0 ; do this in case break ! 238: debug-level-count 0) ; occurs during readin ! 239: (*catch '(break-catch top-level-catch) ! 240: (cond (hom ! 241: (cond ((and ! 242: (errset ! 243: (progn ! 244: (setq prt (infile (concat hom '"/.lisprc"))) ! 245: (close prt)) ! 246: nil) ! 247: (null (errset ! 248: (load (concat hom '"/.lisprc"))))) ! 249: (patom '"Error in .lisprc file detected") ! 250: (terpr))))))) ! 251: (getenv 'HOME) nil))) ! 252: ! 253: (putd 'top-level (getd 'franz-top-level)) ! 254: ! 255: ; if this is the first time this file has been read in, then ! 256: ; make franz-reset be the reset function, but remember the original ! 257: ; reset function as old-reset-function. We need the old reset function ! 258: ; if we are going to allow the user to change top-levels, for in ! 259: ; order to do that we really have to jump all the way up to the top. ! 260: (cond ((null (getd 'old-reset-function)) ! 261: (putd 'old-reset-function (getd 'reset))))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.