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 (sys::gsgc-totalloc .oldspace t
)
154 (list (aref .oldspace
0) (aref .oldspace
2) .oldgcu
)))) ;; report just two kinds of space,
155 ;; cons-cells and other bytes,
156 ;; also report gc-user time
159 (defun used-area (&optional unused
)
160 (declare (ignore unused
))
161 (getf (system:room-values
) :total-allocated
))
163 #-
(or cmu scl sbcl clisp allegro openmcl lispworks
)
164 (defun used-area (&optional unused
)
165 (declare (ignore unused
))
168 (defun continue (&optional
(input-stream *standard-input
*)
170 (declare (special *socket-connection
*))
171 (if (eql batch-or-demo-flag
:demo
)
174 "~%At the '~A' prompt, type ';' and <enter> to get next demonstration.~&")
175 (print-invert-case (stripdollar $prompt
))))
190 (catch 'return-from-debugger
191 (when (or (not (checklabel $inchar
))
192 (not (checklabel $outchar
)))
194 (setq c-tag
(makelabel $inchar
))
195 (let ((*mread-prompt
* (if batch-or-demo-flag nil
(main-prompt)))
199 (setq r
(dbm-read input-stream nil eof
))
200 ;; This is something of a hack. If we are running in a server mode
201 ;; (which we determine by checking *socket-connection*) and we get
202 ;; an eof on an input-stream that is not *standard-input*, switch
203 ;; the input stream to *standard-input*.
204 ;; There should probably be a better scheme for server mode.
208 (not (eq input-stream
*standard-input
*))
209 (boundp '*socket-connection
*))
211 (setq input-stream
*standard-input
*)
212 (if batch-or-demo-flag
215 (setq *mread-prompt
* nil
)
216 (setq r
(dbm-read input-stream nil eof
))))))
218 (cond ((and (eq r eof
) (boundp '*socket-connection
*)
219 (eq input-stream
*socket-connection
*))
220 (cond ((>= (setq eof-count
(+ 1 eof-count
)) 10)
221 (print "exiting on eof")
224 (cond ((and (consp r
) (keywordp (car r
)))
225 (break-call (car r
) (cdr r
) 'break-command
)
227 (format t
"~a" *general-display-prefix
*)
228 (if (eq r eof
) (return '$done
))
230 (unless $nolabels
(set c-tag $__
))
231 (cond (batch-or-demo-flag
232 (let (($display2d nil
))
233 (displa `((mlabel) ,c-tag
, $__
)))))
234 (setq time-before
(get-internal-run-time)
235 etime-before
(get-internal-real-time))
236 (setq area-before
(used-area))
237 (setq $%
(toplevel-macsyma-eval $__
))
238 (setq etime-after
(get-internal-real-time)
239 time-after
(get-internal-run-time))
240 (setq area-after
(used-area))
241 (setq time-used
(quotient
242 (float (- time-after time-before
))
243 internal-time-units-per-second
)
245 (float (- etime-after etime-before
))
246 internal-time-units-per-second
))
247 (incf accumulated-time time-used
)
248 (setq d-tag
(makelabel $outchar
))
249 (unless $nolabels
(set d-tag $%
))
251 (when $showtime
;; we don't distinguish showtime:all?? /RJF
252 (format t
(intl:gettext
"Evaluation took ~,4F seconds (~,4F elapsed)")
253 time-used etime-used
)
256 #+(or cmu scl sbcl clisp openmcl
)
257 (let ((total-bytes (- area-after area-before
)))
258 (cond ((> total-bytes
(* 1024 1024))
259 (format t
(intl:gettext
" using ~,3F MB.~%")
260 (/ total-bytes
(* 1024.0 1024.0))))
261 ((> total-bytes
1024)
262 (format t
(intl:gettext
" using ~,3F KB.~%") (/ total-bytes
1024.0)))
264 (format t
(intl:gettext
" using ~:D bytes.~%") total-bytes
))))
267 (let ((conses (- (car area-after
) (car area-before
)))
268 (other (- (cadr area-after
) (cadr area-before
)))
269 (gctime (- (caddr area-after
) (caddr area-before
))))
270 (if (= 0 gctime
) nil
(format t
(intl:gettext
" including GC time ~s s,") (* 0.001 gctime
)))
271 (format t
(intl:gettext
" using ~s cons-cells and ~s other bytes.~%") conses other
)))
273 (putprop '$%
(cons time-used
0) 'time
)
274 (putprop d-tag
(cons time-used
0) 'time
))
275 (if (eq (caar r
) 'displayinput
)
276 (displa `((mlabel) ,d-tag
,$%
)))
277 (when (eq batch-or-demo-flag
':demo
)
278 (princ (break-prompt))
282 ;;those are common lisp characters you're reading here
283 (case (setq char
(read-char *terminal-io
*))
286 (princ (break-prompt))
291 " Pausing. Type a ';' and <enter> to continue demo.~%")))
292 ((#\space
#\
; #\n #\e #\x #\t))
294 (if quitting
(throw 'abort-demo nil
) (return nil
)))
295 (t (setq quitting t
))))))
296 ;; This is sort of a kludge -- eat newlines and blanks so that
298 (and batch-or-demo-flag
300 (setq char
(read-char input-stream nil nil
))
302 (throw 'macsyma-quit nil
))
303 (unless (member char
'(#\space
#\newline
#\return
#\tab
) :test
#'equal
)
304 (unread-char char input-stream
)
307 (defun $break
(&rest arg-list
)
308 (prog1 (apply #'$print arg-list
)
311 (defun mbreak-loop ()
312 (let ((*standard-input
* *debug-io
*)
313 (*standard-output
* *debug-io
*))
315 (format t
(intl:gettext
"~%Entering a Maxima break point. Type 'exit;' to resume."))
318 (setq r
(caddr (let ((*mread-prompt
* (break-prompt)))
319 (mread *standard-input
*))))
321 (($exit
) (throw 'break-exit t
))
322 (t (errset (displa (meval r
)) t
)))))))
324 (defun merrbreak (&optional arg
)
325 (format *debug-io
* "~%Merrbreak:~A" arg
)
328 (defun retrieve (msg flag
&aux
(print? nil
))
329 (declare (special msg flag print?
))
330 (or (eq flag
'noprint
) (setq print? t
))
333 (format-prompt t
""))
335 (format-prompt t
""))
337 (format-prompt t
"~A" msg
)
340 (format-prompt t
"~{~A~}" (cdr msg
))
343 (format-prompt t
"~M" msg
)
345 (let ((res (mread-noprompt *query-io
* nil
)))
346 (princ *general-display-prefix
*)
349 (defmfun $read
(&rest l
)
350 (meval (apply #'$readonly l
)))
352 (defmfun $readonly
(&rest l
)
353 (let ((*mread-prompt
*
355 (string-right-trim '(#\n)
356 (with-output-to-string (*standard-output
*) (apply #'$print l
)))
358 (setf *mread-prompt
* (format-prompt nil
"~A" *mread-prompt
*))
359 (third (mread *query-io
*))))
361 ;; FUNCTION BATCH APPARENTLY NEVER CALLED. OMIT FROM GETTEXT SWEEP AND DELETE IT EVENTUALLY
362 (defun batch (filename &optional demo-p
363 &aux
(orig filename
) list
364 file-obj
(accumulated-time 0.0) (abortp t
))
365 (setq list
(if demo-p
'$file_search_demo
'$file_search_maxima
))
366 (setq filename
($file_search filename
(symbol-value list
)))
367 (or filename
(merror "Could not find ~M in ~M: ~M"
368 orig list
(symbol-value list
)))
371 (progn (batch-internal (setq file-obj
(open filename
)) demo-p
)
374 (format t
"~&Batch spent ~,4F seconds in evaluation.~%"
376 (if file-obj
(close file-obj
))
377 (when abortp
(format t
"~&(Batch of ~A aborted.)~%" filename
))))
380 (defun batch-internal (fileobj demo-p
)
381 (continue (make-echo-stream fileobj
*standard-output
*)
382 (if demo-p
':demo
':batch
)))
384 (defmspec $grindef
(form)
385 (eval `(grindef ,@(cdr form
)))
388 (defun $demo
(&rest arg-list
)
389 (let ((tem ($file_search
(car arg-list
) $file_search_demo
)))
390 (or tem
(merror (intl:gettext
"demo: could not find ~M in ~M.")
391 (car arg-list
) '$file_search_demo
))
392 ($batch tem
'$demo
)))
394 (defmfun $bug_report
()
395 (format t
(intl:gettext
"~%Please report bugs to:~%"))
396 (format t
" http://sourceforge.net/p/maxima/bugs~%")
397 (format t
(intl:gettext
"To report a bug, you must have a Sourceforge account.~%"))
398 (format t
(intl:gettext
"Please include the following information with your bug report:~%"))
399 (format 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 ,(lisp-implementation-type)
431 ,(lisp-implementation-version)))))))
433 (defun dimension-build-info (form result
)
434 (declare (special bkptht bkptdp lines break
))
435 ;; Usually the result of (MFUNCALL '$@ ...) is a string,
436 ;; but ensure that output makes sense even if it is not.
438 ((version-string (format nil
(intl:gettext
"Maxima version: ~a")
439 (coerce (mstring (mfuncall '$
@ form
'$version
)) 'string
)))
440 (timestamp-string (format nil
(intl:gettext
"Maxima build date: ~a")
441 (coerce (mstring (mfuncall '$
@ form
'$timestamp
)) 'string
)))
442 (host-string (format nil
(intl:gettext
"Host type: ~a")
443 (coerce (mstring (mfuncall '$
@ form
'$host
)) 'string
)))
444 (lisp-name-string (format nil
(intl:gettext
"Lisp implementation type: ~a")
445 (coerce (mstring (mfuncall '$
@ form
'$lisp_name
)) 'string
)))
446 (lisp-version-string (format nil
(intl:gettext
"Lisp implementation version: ~a")
447 (coerce (mstring (mfuncall '$
@ form
'$lisp_version
)) 'string
)))
452 (forcebreak result
0)
453 (forcebreak (reverse (coerce version-string
'list
)) 0)
454 (forcebreak (reverse (coerce timestamp-string
'list
)) 0)
455 (forcebreak (reverse (coerce host-string
'list
)) 0)
456 (forcebreak (reverse (coerce lisp-name-string
'list
)) 0)
457 (forcebreak (reverse (coerce lisp-version-string
'list
)) 0))
460 (setf (get '%build_info
'dimension
) 'dimension-build-info
)
462 (defvar *maxima-started
* nil
)
464 (defvar *maxima-prolog
* "")
465 (defvar *maxima-epilog
* "")
467 (declare-top (special *maxima-initmac
* *maxima-initlisp
*))
469 (defvar *maxima-quiet
* nil
)
471 (defun macsyma-top-level (&optional
(input-stream *standard-input
*) batch-flag
)
472 (let ((*package
* (find-package :maxima
)))
474 (format t
(intl:gettext
"Maxima restarted.~%"))
476 (if (not *maxima-quiet
*) (maxima-banner))
477 (setq *maxima-started
* t
)))
479 (if ($file_search
*maxima-initlisp
*) ($load
($file_search
*maxima-initlisp
*)))
480 (if ($file_search
*maxima-initmac
*) ($batchload
($file_search
*maxima-initmac
*)))
486 (catch #+kcl si
::*quit-tag
*
487 #+(or cmu scl sbcl openmcl lispworks
) 'continue
488 #-
(or kcl cmu scl sbcl openmcl lispworks
) nil
490 (continue input-stream batch-flag
)
491 (format t
*maxima-epilog
*)
494 (defun maxima-banner ()
495 (format t
*maxima-prolog
*)
496 (format t
"~&Maxima ~a http://maxima.sourceforge.net~%"
498 (format t
(intl:gettext
"using Lisp ~a ~a") (lisp-implementation-type)
499 #-clisp
(lisp-implementation-version)
500 #+clisp
(subseq (lisp-implementation-version)
501 0 (1+ (search ")" (lisp-implementation-version)))))
502 #+gcl
(format t
" (a.k.a. GCL)")
503 (format t
(intl:gettext
"~%Distributed under the GNU Public License. See the file COPYING.~%"))
504 (format t
(intl:gettext
"Dedicated to the memory of William Schelter.~%"))
505 (format t
(intl:gettext
"The function bug_report() provides bug reporting information.~%")))
508 (si::putprop
:t
'throw-macsyma-top
'si
::break-command
)
510 (defun throw-macsyma-top ()
511 (throw 'macsyma-quit t
))
513 (defmfun $writefile
(x)
514 (let ((msg (dribble (maxima-string x
))))
515 (format t
"~&~A~&" msg
)
518 (defvar $appendfile nil
)
519 (defvar *appendfile-data
*)
521 (defmfun $appendfile
(name)
522 (if (and (symbolp name
)
523 (member (char (symbol-name name
) 0) '(#\$
) :test
#'char
=))
524 (setq name
(maxima-string name
)))
525 (if $appendfile
(merror (intl:gettext
"appendfile: already in appendfile, you must call closefile first.")))
526 (let ((stream (open name
:direction
:output
528 :if-does-not-exist
:create
)))
529 (setq *appendfile-data
* (list stream
*terminal-io
* name
))
531 (setq $appendfile
(make-two-way-stream
532 (make-echo-stream *terminal-io
* stream
)
533 (make-broadcast-stream *terminal-io
* stream
))
534 *terminal-io
* $appendfile
)
535 (multiple-value-bind (sec min hour day month year
)
537 (format t
(intl:gettext
"~&/* Starts dribbling to ~A (~d/~d/~d, ~d:~d:~d).*/~&")
538 name year month day hour min sec
))
541 (defmfun $closefile
()
543 (cond ((eq $appendfile
*terminal-io
*)
544 (format t
(intl:gettext
"~&/*Finished dribbling to ~A.*/~&")
545 (nth 2 *appendfile-data
*))
546 (setq *terminal-io
* (nth 1 *appendfile-data
*)))
547 (t (warn "*TERMINAL-IO* was rebound while APPENDFILE is on.~%~
548 You may miss some dribble output.")))
549 (close (nth 0 *appendfile-data
*))
550 (setq *appendfile-data
* nil $appendfile nil
))
551 (t (let ((msg (dribble)))
552 (format t
"~&~A~&" msg
))))
556 (ed (maxima-string x
)))
558 (defun nsubstring (x y
)
562 (subseq (print-invert-case (car x
)) 1))
564 (defmspec $with_stdout
(arg)
565 (declare (special $file_output_append
))
567 (let ((output (meval (car arg
))))
570 ((*standard-output
* output
)
574 (setq result
(meval* v
)))
577 ((fname (namestring (maxima-string output
)))
579 (if (or (eq $file_output_append
'$true
)
580 (eq $file_output_append t
))
581 `(*standard-output
* ,fname
:direction
:output
:if-exists
:append
:if-does-not-exist
:create
)
582 `(*standard-output
* ,fname
:direction
:output
:if-exists
:supersede
:if-does-not-exist
:create
))))
584 `(with-open-file ,filespec
585 (let ((body ',(cdr arg
)) result
)
587 (setq result
(meval* v
)))
590 (defun $sconcat
(&rest x
)
593 (setq ans
(concatenate 'string ans
597 (coerce (mstring v
) 'string
))))))
600 (defun $system
(&rest args
)
601 ;; If XMaxima is running, direct output from command into *SOCKET-CONNECTION*.
602 ;; From what I can tell, GCL, ECL, and Clisp cannot redirect the output into an existing stream. Oh well.
603 (let ((s (and (boundp '*socket-connection
*) *socket-connection
*))
605 #+(or gcl ecl clisp lispworks
)
608 (cond ((string= *autoconf-win32
* "true")
609 (setf shell
"cmd") (setf shell-opt
"/c"))
610 (t (setf shell
"/bin/sh") (setf shell-opt
"-c")))
612 #+gcl
(lisp:system
(apply '$sconcat args
))
613 #+ecl
(si:system
(apply '$concat args
))
614 #+clisp
(let ((output (ext:run-shell-command
(apply '$sconcat args
)
615 :wait t
:output
:stream
)))
616 (loop for line
= (read-line output nil
)
618 (format (or s t
) "~a~%" line
)))
619 #+(or cmu scl
) (ext:run-program shell
(list shell-opt
(apply '$sconcat args
)) :output
(or s t
))
620 #+allegro
(excl:run-shell-command
(apply '$sconcat args
) :wait t
:output
(or s nil
))
621 #+sbcl
(sb-ext:run-program shell
622 #+win32
(cons shell-opt
(mapcar '$sconcat args
))
623 #-win32
(list shell-opt
(apply '$sconcat args
))
624 :search t
:output
(or s t
))
625 #+openmcl
(ccl::run-program shell
626 #+windows
(cons shell-opt
(mapcar '$sconcat args
))
627 #-windows
(list shell-opt
(apply '$sconcat args
))
629 #+abcl
(extensions::run-shell-command
(apply '$sconcat args
) :output
(or s
*standard-output
*))
630 #+lispworks
(system:run-shell-command
(apply '$sconcat args
) :wait t
)))
632 (defun $room
(&optional
(arg nil arg-p
))
637 (defun maxima-lisp-debugger (condition me-or-my-encapsulation
)
638 (declare (ignore me-or-my-encapsulation
))
639 (format t
(intl:gettext
"~&Maxima encountered a Lisp error:~%~% ~A") condition
)
640 (format t
(intl:gettext
"~&~%Automatically continuing.~%To enable the Lisp debugger set *debugger-hook* to nil.~%"))
641 (throw 'return-from-debugger t
))
643 (let ((t0-real 0) (t0-run 0)
644 (float-units (float internal-time-units-per-second
)))
646 (defun initialize-real-and-run-time ()
647 (setq t0-real
(get-internal-real-time))
648 (setq t0-run
(get-internal-run-time)))
650 (defun $absolute_real_time
() (get-universal-time))
652 (defun $elapsed_real_time
()
653 (let ((elapsed-real-time (- (get-internal-real-time) t0-real
)))
654 (/ elapsed-real-time float-units
)))
656 (defun $elapsed_run_time
()
657 (let ((elapsed-run-time (- (get-internal-run-time) t0-run
)))
658 (/ elapsed-run-time float-units
))))