1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancments. ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 ;;; ** (c) Copyright 1981 Massachusetts Institute of Technology **
11 ;;; SYSTEM: The ``New'' Macsyma System Stuff
15 (macsyma-module system
)
17 (defmvar $showtime nil
18 "When T, the computation time is printed with each output expression.")
20 ;;; Standard Kinds of Input Prompts
23 "Prompt symbol of the demo function, playback, and the Maxima break loop.")
25 ;; A prefix and suffix that are wrapped around every prompt that Maxima
26 ;; emits. This is designed for use with text-based interfaces that drive Maxima
27 ;; through standard input and output and need to decorate prompts to make the
28 ;; output easier to parse. There are some more notes in
29 ;; doc/implementation/external-interface.txt.
30 (defvar *prompt-prefix
* "")
31 (defvar *prompt-suffix
* "")
32 (defvar *general-display-prefix
* "")
33 (defvar $alt_format_prompt nil
"If NIL, use DEFAULT-FORMAT-PROMPT to print input prompt; if a function, use it to print input prompt.")
35 (defun format-prompt (destination control-string
&rest arguments
)
36 "If $ALT_FORMAT_PROMPT is NIL, use DEFAULT-FORMAT-PROMPT to print
37 prompt; otherwise MFUNCALL $ALT_FORMAT_PROMPT to print prompt."
38 (funcall (if $alt_format_prompt
#'alt-format-prompt
#'default-format-prompt
)
39 destination control-string arguments
))
41 (defun alt-format-prompt (destination control-string arguments
)
42 "MFUNCALL $ALT_FORMAT_PROMPT with a heavy coating of error protection."
43 (handler-bind ((error (lambda(msg) (setq $alt_format_prompt nil
)
44 (format t
(intl:gettext
"Error in printing prompt; reverting to default.~%~a") msg
)
45 (throw 'macsyma-quit
'maxima-error
))))
46 (with-$error
(let ((prompt (mfuncall $alt_format_prompt destination control-string arguments
)))
47 (if (stringp prompt
) prompt
(merror "alt_format_prompt returned an object of type ~a, needed a string." (type-of prompt
)))))))
49 (defun default-format-prompt (destination control-string arguments
)
50 "Like AFORMAT, but add the prefix and suffix configured for a prompt. This
51 function deals correctly with the ~M control character, but only when
52 DESTINATION is an actual stream (rather than nil for a string)."
53 (let ((*print-circle
* nil
))
54 (if (null destination
)
55 ;; return value string is important
58 (apply #'aformat destination
63 (format destination
"~A~A~A"
71 (defvar $default_format_prompt
(symbol-function 'default-format-prompt
))
73 ;; "When time began" (or at least the start of version control history),
74 ;; the following comment was made at this point:
76 ;; instead of using this STRIPDOLLAR hackery, the
77 ;; MREAD function should call MFORMAT to print the prompt,
78 ;; and take a format string and format arguments.
79 ;; Even easier and more general is for MREAD to take
80 ;; a FUNARG as the prompt. -gjc
82 ;; I guess we're still failing miserably, but unfortunately MFORMAT/AFORMAT
83 ;; don't deal correctly with ~M plus a string output stream.
85 (declare (special *display-labels-p
*))
86 (if *display-labels-p
*
87 (format-prompt nil
"(~A~A) "
88 (print-invert-case (stripdollar $inchar
))
92 (defun break-prompt ()
93 (format-prompt nil
"~A"
94 (print-invert-case (stripdollar $prompt
))))
96 (defun toplevel-macsyma-eval (x)
97 ;; Catch rat-err's here.
99 ;; The idea is that eventually there will be quite a few "maybe catch this"
100 ;; errors, which will be raised and might well get eaten before they get as far
101 ;; as here. However, we want to display them nicely like merror rather than
102 ;; letting a lisp error percolate to the debugger and, as such, we catch them
103 ;; here and replace them with an merror call.
105 ;; Other random errors get to the lisp debugger, which is normally set to print
106 ;; them and continue, via *debugger-hook*.
107 (rat-error-to-merror (meval* x
)))
109 (defmvar $_
'$_
"last thing read in, corresponds to lisp +")
110 (defmvar $__
'$__
"thing read in which will be evaluated, corresponds to -")
112 (declare-top (special *mread-prompt
* $file_search_demo
))
114 (defvar accumulated-time
0.0)
117 (defun used-area (&optional unused
)
118 (declare (ignore unused
))
119 (ext:get-bytes-consed
))
122 (defun used-area (&optional unused
)
123 (declare (ignore unused
))
124 (sb-ext:get-bytes-consed
))
127 (defun used-area (&optional unused
)
128 (declare (ignore unused
))
129 (ccl::total-bytes-allocated
))
132 (defun used-area (&optional unused
)
133 (declare (ignore unused
))
134 (multiple-value-bind (real1 real2 run1 run2 gc1 gc2 space1 space2 gccount
)
136 (declare (ignore real1 real2 run1 run2 gc1 gc2 gccount
))
137 (dpb space1
(byte 24 24) space2
)))
141 (defun used-area (&optional unused
)
142 (declare (ignore unused
))
143 (declare (optimize (speed 3)))
144 (let ((.oldspace
(make-array 4 :element-type
145 #-
64bit
'(unsigned-byte 32)
146 #+64bit
'(unsigned-byte 64))))
147 (declare (type (simple-array #-
64bit
(unsigned-byte 32)
148 #+64bit
(unsigned-byte 64) (*))
151 (multiple-value-bind (.olduser .oldsystem .oldgcu .oldgcs
)
152 (excl::get-internal-run-times
)
153 (declare (ignore .olduser .oldsystem .oldgcs
))
154 (sys::gsgc-totalloc .oldspace t
)
155 (list (aref .oldspace
0) (aref .oldspace
2) .oldgcu
)))) ;; report just two kinds of space,
156 ;; cons-cells and other bytes,
157 ;; also report gc-user time
160 (defun used-area (&optional unused
)
161 (declare (ignore unused
))
162 (getf (system:room-values
) :total-allocated
))
164 #-
(or cmu scl sbcl clisp allegro openmcl lispworks
)
165 (defun used-area (&optional unused
)
166 (declare (ignore unused
))
169 (defun continue (&optional
(input-stream *standard-input
*)
171 (declare (special *socket-connection
*))
172 (if (eql batch-or-demo-flag
:demo
)
175 "~%At the '~A' prompt, type ';' and <enter> to get next demonstration.~&")
176 (print-invert-case (stripdollar $prompt
))))
191 (declare (ignorable area-before area-after
))
192 (catch 'return-from-debugger
193 (when (or (not (checklabel $inchar
))
194 (not (checklabel $outchar
)))
196 (setq c-tag
(makelabel $inchar
))
197 (let ((*mread-prompt
* (if batch-or-demo-flag nil
(main-prompt)))
201 (setq r
(dbm-read input-stream nil eof
))
202 ;; This is something of a hack. If we are running in a server mode
203 ;; (which we determine by checking *socket-connection*) and we get
204 ;; an eof on an input-stream that is not *standard-input*, switch
205 ;; the input stream to *standard-input*.
206 ;; There should probably be a better scheme for server mode.
210 (not (eq input-stream
*standard-input
*))
211 (boundp '*socket-connection
*))
213 (setq input-stream
*standard-input
*)
214 (if batch-or-demo-flag
217 (setq *mread-prompt
* nil
)
218 (setq r
(dbm-read input-stream nil eof
))))))
220 (cond ((and (eq r eof
) (boundp '*socket-connection
*)
221 (eq input-stream
*socket-connection
*))
222 (cond ((>= (setq eof-count
(+ 1 eof-count
)) 10)
223 (print "exiting on eof")
226 (cond ((and (consp r
) (keywordp (car r
)))
227 (break-call (car r
) (cdr r
) 'break-command
)
229 (format t
"~a" *general-display-prefix
*)
230 (if (eq r eof
) (return '$done
))
232 (unless $nolabels
(setf (symbol-value c-tag
) $__
))
233 (cond (batch-or-demo-flag
234 (let (($display2d nil
))
235 (displa `((mlabel) ,c-tag
, $__
)))))
236 (setq time-before
(get-internal-run-time)
237 etime-before
(get-internal-real-time))
238 (setq area-before
(used-area))
239 (setq $%
(toplevel-macsyma-eval $__
))
240 (setq etime-after
(get-internal-real-time)
241 time-after
(get-internal-run-time))
242 (setq area-after
(used-area))
243 (setq time-used
(quotient
244 (float (- time-after time-before
))
245 internal-time-units-per-second
)
247 (float (- etime-after etime-before
))
248 internal-time-units-per-second
))
249 (incf accumulated-time time-used
)
250 (setq d-tag
(makelabel $outchar
))
251 (unless $nolabels
(setf (symbol-value d-tag
) $%
))
253 (when $showtime
;; we don't distinguish showtime:all?? /RJF
254 (format t
(intl:gettext
"Evaluation took ~,4F seconds (~,4F elapsed)")
255 time-used etime-used
)
258 #+(or cmu scl sbcl clisp openmcl
)
259 (let ((total-bytes (- area-after area-before
)))
260 (cond ((> total-bytes
(* 1024 1024))
261 (format t
(intl:gettext
" using ~,3F MB.~%")
262 (/ total-bytes
(* 1024.0 1024.0))))
263 ((> total-bytes
1024)
264 (format t
(intl:gettext
" using ~,3F KB.~%") (/ total-bytes
1024.0)))
266 (format t
(intl:gettext
" using ~:D bytes.~%") total-bytes
))))
269 (let ((conses (- (car area-after
) (car area-before
)))
270 (other (- (cadr area-after
) (cadr area-before
)))
271 (gctime (- (caddr area-after
) (caddr area-before
))))
272 (if (= 0 gctime
) nil
(format t
(intl:gettext
" including GC time ~s s,") (* 0.001 gctime
)))
273 (format t
(intl:gettext
" using ~s cons-cells and ~s other bytes.~%") conses other
)))
275 (putprop '$%
(cons time-used
0) 'time
)
276 (putprop d-tag
(cons time-used
0) 'time
))
277 (if (eq (caar r
) 'displayinput
)
278 (displa `((mlabel) ,d-tag
,$%
)))
279 (when (eq batch-or-demo-flag
':demo
)
280 (princ (break-prompt))
284 ;;those are common lisp characters you're reading here
285 (case (read-char *terminal-io
*)
288 (princ (break-prompt))
293 " Pausing. Type a ';' and <enter> to continue demo.~%")))
294 ((#\space
#\
; #\n #\e #\x #\t))
296 (if quitting
(throw 'abort-demo nil
) (return nil
)))
297 (t (setq quitting t
))))))
298 ;; This is sort of a kludge -- eat newlines and blanks so that
300 (and batch-or-demo-flag
302 (setq char
(read-char input-stream nil nil
))
304 (throw 'macsyma-quit nil
))
305 (unless (member char
'(#\space
#\newline
#\return
#\tab
) :test
#'equal
)
306 (unread-char char input-stream
)
309 (defun $break
(&rest arg-list
)
310 (prog1 (apply #'$print arg-list
)
313 (defun mbreak-loop ()
314 (let ((*standard-input
* *debug-io
*)
315 (*standard-output
* *debug-io
*))
317 (format t
(intl:gettext
"~%Entering a Maxima break point. Type 'exit;' to resume."))
320 (setq r
(caddr (let ((*mread-prompt
* (break-prompt)))
321 (mread *standard-input
*))))
323 (($exit
) (throw 'break-exit t
))
324 (t (errset (displa (meval r
)) t
)))))))
326 (defun merrbreak (&optional arg
)
327 (format *debug-io
* "~%Merrbreak:~A" arg
)
330 (defun retrieve (msg flag
&aux
(print? nil
))
331 (declare (special msg flag print?
))
332 (or (eq flag
'noprint
) (setq print? t
))
335 (format-prompt t
""))
337 (format-prompt t
""))
339 (format-prompt t
"~A" msg
)
342 (format-prompt t
"~{~A~}" (cdr msg
))
345 (format-prompt t
"~M" msg
)
347 (let ((res (mread-noprompt *query-io
* nil
)))
348 (princ *general-display-prefix
*)
351 (defmfun $read
(&rest l
)
352 (meval (apply #'$readonly l
)))
354 (defmfun $readonly
(&rest l
)
355 (let ((*mread-prompt
*
357 (string-right-trim '(#\n)
358 (with-output-to-string (*standard-output
*) (apply #'$print l
)))
360 (setf *mread-prompt
* (format-prompt nil
"~A" *mread-prompt
*))
361 (third (mread *query-io
*))))
363 ;; FUNCTION BATCH APPARENTLY NEVER CALLED. OMIT FROM GETTEXT SWEEP AND DELETE IT EVENTUALLY
364 (defun batch (filename &optional demo-p
365 &aux
(orig filename
) list
366 file-obj
(accumulated-time 0.0) (abortp t
))
367 (setq list
(if demo-p
'$file_search_demo
'$file_search_maxima
))
368 (setq filename
($file_search filename
(symbol-value list
)))
369 (or filename
(merror "Could not find ~M in ~M: ~M"
370 orig list
(symbol-value list
)))
373 (progn (batch-internal (setq file-obj
(open filename
)) demo-p
)
376 (format t
"~&Batch spent ~,4F seconds in evaluation.~%"
378 (if file-obj
(close file-obj
))
379 (when abortp
(format t
"~&(Batch of ~A aborted.)~%" filename
))))
382 (defun batch-internal (fileobj demo-p
)
383 (continue (make-echo-stream fileobj
*standard-output
*)
384 (if demo-p
':demo
':batch
)))
386 (defun $demo
(&rest arg-list
)
387 (let ((tem ($file_search
(car arg-list
) $file_search_demo
)))
388 (or tem
(merror (intl:gettext
"demo: could not find ~M in ~M.")
389 (car arg-list
) '$file_search_demo
))
390 ($batch tem
'$demo
)))
392 (defmfun $bug_report
()
393 (format t
(intl:gettext
"~%Please report bugs to:~%"))
394 (format t
" https://sourceforge.net/p/maxima/bugs~%")
395 (format t
(intl:gettext
"To report a bug, you must have a Sourceforge account.~%"))
396 (format t
(intl:gettext
"Please include the following information with your bug report:~%"))
397 (format t
"-------------------------------------------------------------~%")
398 ; Display the 2D-formatted build information
399 (let (($display2d t
))
400 (displa ($build_info
)))
401 (format t
"-------------------------------------------------------------~%")
402 (format t
(intl:gettext
"The above information is also reported by the function 'build_info()'.~%~%"))
405 ;; Declare a build_info structure, then remove it from the list of user-defined structures.
406 (defstruct1 '((%build_info
) $version $timestamp $host $lisp_name $lisp_version
))
407 (let nil
(declare (special $structures
))
408 (setq $structures
(cons '(mlist) (remove-if #'(lambda (x) (eq (caar x
) '%build_info
)) (cdr $structures
)))))
410 (defvar *maxima-build-info
* nil
)
412 (defmfun $build_info
()
418 ((year (sixth cl-user
:*maxima-build-time
*))
419 (month (fifth cl-user
:*maxima-build-time
*))
420 (day (fourth cl-user
:*maxima-build-time
*))
421 (hour (third cl-user
:*maxima-build-time
*))
422 (minute (second cl-user
:*maxima-build-time
*))
423 (seconds (first cl-user
:*maxima-build-time
*)))
428 ,(format nil
"~4,'0d-~2,'0d-~2,'0d ~2,'0d:~2,'0d:~2,'0d" year month day hour minute seconds
)
430 ,#+sbcl
(ensure-readably-printable-string (lisp-implementation-type)) #-sbcl
(lisp-implementation-type)
431 ,#+sbcl
(ensure-readably-printable-string (lisp-implementation-version)) #-sbcl
(lisp-implementation-version)))))))
433 ;; SBCL base strings aren't readably printable.
434 ;; Attempt a work-around. Yes, this is terribly ugly.
435 #+sbcl
(defun ensure-readably-printable-string (x)
436 (coerce x
`(simple-array character
(,(length x
)))))
438 (defun dimension-build-info (form result
)
439 (declare (special bkptht bkptdp lines break
))
440 ;; Usually the result of (MFUNCALL '$@ ...) is a string,
441 ;; but ensure that output makes sense even if it is not.
443 ((version-string (format nil
(intl:gettext
"Maxima version: ~a")
444 (coerce (mstring (mfuncall '$
@ form
'$version
)) 'string
)))
445 (timestamp-string (format nil
(intl:gettext
"Maxima build date: ~a")
446 (coerce (mstring (mfuncall '$
@ form
'$timestamp
)) 'string
)))
447 (host-string (format nil
(intl:gettext
"Host type: ~a")
448 (coerce (mstring (mfuncall '$
@ form
'$host
)) 'string
)))
449 (lisp-name-string (format nil
(intl:gettext
"Lisp implementation type: ~a")
450 (coerce (mstring (mfuncall '$
@ form
'$lisp_name
)) 'string
)))
451 (lisp-version-string (format nil
(intl:gettext
"Lisp implementation version: ~a")
452 (coerce (mstring (mfuncall '$
@ form
'$lisp_version
)) 'string
)))
457 (forcebreak result
0)
458 (forcebreak (reverse (coerce version-string
'list
)) 0)
459 (forcebreak (reverse (coerce timestamp-string
'list
)) 0)
460 (forcebreak (reverse (coerce host-string
'list
)) 0)
461 (forcebreak (reverse (coerce lisp-name-string
'list
)) 0)
462 (forcebreak (reverse (coerce lisp-version-string
'list
)) 0))
465 (setf (get '%build_info
'dimension
) 'dimension-build-info
)
467 (defvar *maxima-started
* nil
)
469 (defvar *maxima-prolog
* "")
470 (defvar *maxima-epilog
* "")
472 (declare-top (special *maxima-initmac
* *maxima-initlisp
*))
474 (defvar *maxima-quiet
* nil
)
476 (defun macsyma-top-level (&optional
(input-stream *standard-input
*) batch-flag
)
477 (let ((*package
* (find-package :maxima
)))
479 (format t
(intl:gettext
"Maxima restarted.~%"))
481 (if (not *maxima-quiet
*) (maxima-banner))
482 (setq *maxima-started
* t
)))
484 (if ($file_search
*maxima-initlisp
*) ($load
($file_search
*maxima-initlisp
*)))
485 (if ($file_search
*maxima-initmac
*) ($batchload
($file_search
*maxima-initmac
*)))
491 (catch #+kcl si
::*quit-tag
*
492 #+(or cmu scl sbcl openmcl lispworks
) 'continue
493 #-
(or kcl cmu scl sbcl openmcl lispworks
) nil
495 (continue input-stream batch-flag
)
496 (format t
*maxima-epilog
*)
499 (defun maxima-banner ()
500 (format t
*maxima-prolog
*)
501 (format t
"~&Maxima ~a http://maxima.sourceforge.net~%"
503 (format t
(intl:gettext
"using Lisp ~a ~a") (lisp-implementation-type)
504 #-clisp
(lisp-implementation-version)
505 #+clisp
(subseq (lisp-implementation-version)
506 0 (1+ (search ")" (lisp-implementation-version)))))
507 (format t
(intl:gettext
"~%Distributed under the GNU Public License. See the file COPYING.~%"))
508 (format t
(intl:gettext
"Dedicated to the memory of William Schelter.~%"))
509 (format t
(intl:gettext
"The function bug_report() provides bug reporting information.~%")))
512 (si::putprop
:t
'throw-macsyma-top
'si
::break-command
)
514 (defun throw-macsyma-top ()
515 (throw 'macsyma-quit t
))
517 (defmfun $writefile
(x)
518 (let ((msg (dribble (maxima-string x
))))
519 (format t
"~&~A~&" msg
)
522 (defvar $appendfile nil
)
523 (defvar *appendfile-data
*)
525 (defmfun $appendfile
(name)
526 (if (and (symbolp name
)
527 (char= (char (symbol-name name
) 0) #\$
))
528 (setq name
(maxima-string name
)))
529 (if $appendfile
(merror (intl:gettext
"appendfile: already in appendfile, you must call closefile first.")))
530 (let ((stream (open name
:direction
:output
532 :if-does-not-exist
:create
)))
533 (setq *appendfile-data
* (list stream
*terminal-io
* name
))
535 (setq $appendfile
(make-two-way-stream
536 (make-echo-stream *terminal-io
* stream
)
537 (make-broadcast-stream *terminal-io
* stream
))
538 *terminal-io
* $appendfile
)
539 (multiple-value-bind (sec min hour day month year
)
541 (format t
(intl:gettext
"~&/* Starts dribbling to ~A (~d/~d/~d, ~2,'0d:~2,'0d:~2,'0d).*/~&")
542 name year month day hour min sec
))
545 (defmfun $closefile
()
547 (cond ((eq $appendfile
*terminal-io
*)
548 (format t
(intl:gettext
"~&/*Finished dribbling to ~A.*/~&")
549 (nth 2 *appendfile-data
*))
550 (setq *terminal-io
* (nth 1 *appendfile-data
*)))
551 (t (warn "*TERMINAL-IO* was rebound while APPENDFILE is on.~%~
552 You may miss some dribble output.")))
553 (close (nth 0 *appendfile-data
*))
554 (setq *appendfile-data
* nil $appendfile nil
))
555 (t (let ((msg (dribble)))
556 (format t
"~&~A~&" msg
))))
560 (ed (maxima-string x
)))
562 (defun nsubstring (x y
)
566 (subseq (print-invert-case (car x
)) 1))
568 (defmspec $with_stdout
(arg)
569 (declare (special $file_output_append
))
571 (let ((output (meval (car arg
))))
574 ((*standard-output
* output
)
578 (setq result
(meval* v
)))
581 ((fname (namestring (maxima-string output
)))
583 (if (or (eq $file_output_append
'$true
)
584 (eq $file_output_append t
))
585 `(*standard-output
* ,fname
:direction
:output
:if-exists
:append
:if-does-not-exist
:create
)
586 `(*standard-output
* ,fname
:direction
:output
:if-exists
:supersede
:if-does-not-exist
:create
))))
588 `(with-open-file ,filespec
589 (let ((body ',(cdr arg
)) result
)
591 (setq result
(meval* v
)))
594 (defun $sconcat
(&rest x
)
597 (setq ans
(concatenate 'string ans
601 (coerce (mstring v
) 'string
))))))
604 (defun $system
(&rest args
)
605 ;; If XMaxima is running, direct output from command into *SOCKET-CONNECTION*.
606 ;; From what I can tell, GCL, ECL, and Clisp cannot redirect the output into an existing stream. Oh well.
607 (let ((s (and (boundp '*socket-connection
*) *socket-connection
*))
609 #+(or gcl ecl lispworks
)
611 (declare (ignorable shell shell-opt
))
613 (cond ((string= *autoconf-windows
* "true")
614 (setf shell
"cmd") (setf shell-opt
"/c"))
615 (t (setf shell
"/bin/sh") (setf shell-opt
"-c")))
617 #+gcl
(system::system
(apply '$sconcat args
))
618 #+ecl
(si:system
(apply '$concat args
))
619 #+clisp
(let ((output (ext:run-shell-command
(apply '$sconcat args
)
620 :wait t
:output
:stream
)))
621 (loop for line
= (read-line output nil
)
623 (format (or s t
) "~a~%" line
)))
624 #+(or cmu scl
) (ext:run-program shell
(list shell-opt
(apply '$sconcat args
)) :output
(or s t
))
625 #+allegro
(excl:run-shell-command
(apply '$sconcat args
) :wait t
:output
(or s nil
))
626 #+sbcl
(sb-ext:run-program shell
627 #+(or win32 win64
) (cons shell-opt
(mapcar '$sconcat args
))
628 #-
(or win32 win64
) (list shell-opt
(apply '$sconcat args
))
629 :search t
:output
(or s t
))
630 #+openmcl
(ccl::run-program shell
631 #+windows
(cons shell-opt
(mapcar '$sconcat args
))
632 #-windows
(list shell-opt
(apply '$sconcat args
))
634 #+abcl
(extensions::run-shell-command
(apply '$sconcat args
) :output
(or s
*standard-output
*))
635 #+lispworks
(system:run-shell-command
(apply '$sconcat args
) :wait t
)))
637 (defun $room
(&optional
(arg nil arg-p
))
638 (if (and arg-p
(member arg
'(t nil
) :test
#'eq
))
642 (defun maxima-lisp-debugger (condition me-or-my-encapsulation
)
643 (declare (ignore me-or-my-encapsulation
))
644 (format t
(intl:gettext
"~&Maxima encountered a Lisp error:~%~% ~A") condition
)
645 (format t
(intl:gettext
"~&~%Automatically continuing.~%To enable the Lisp debugger set *debugger-hook* to nil.~%"))
646 (throw 'return-from-debugger t
))
648 (let ((t0-real 0) (t0-run 0)
649 (float-units (float internal-time-units-per-second
)))
651 (defun initialize-real-and-run-time ()
652 (setq t0-real
(get-internal-real-time))
653 (setq t0-run
(get-internal-run-time)))
655 (defun $absolute_real_time
() (get-universal-time))
657 (defun $elapsed_real_time
()
658 (let ((elapsed-real-time (- (get-internal-real-time) t0-real
)))
659 (/ elapsed-real-time float-units
)))
661 (defun $elapsed_run_time
()
662 (let ((elapsed-run-time (- (get-internal-run-time) t0-run
)))
663 (/ elapsed-run-time float-units
))))