[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Mit der Implementation des Parsers und den Routinen für die lineare Anzeige
und der 2D-Anzeige kann jetzt die zentrale Routine maxima-toplevel-loop
vollständig implementiert werden. In der ersten Implementation wird eine
Lisp-read-eval-Schleife ausgeführt. Die Lisp-Funktion eval
ist durch
die Maxima-Funktion meval
ersetzt. Die Lisp-Funktion read
wird
nun durch die Maxima-Funktion mread
ersetzt und die Lisp-Funktion
format
wird durch die Maxima-Funktion mdisplay
ersetzt.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Standardwert: 0.1
Enthält die aktuelle Version von kMaxima.
Die Funktion maxima-banner
gibt beim Starten von kMaxima eine Information
auf der Konsole aus. Darunter ist die aktuelle Version, die in der
globalen Variablen *maxima-version*
abgelegt ist.
Quelltext:
(defun maxima-banner () (format t "~&kMaxima ~a~%" *maxima-version*) (format t "using Lisp ~a ~a~%" (lisp-implementation-type) (lisp-implementation-version)) (format t "Distributed under the GNU Public License. ~ See the file COPYING.~%") (format t "Dedicated to the memory of William Schelter.~%"))
Beendet die kMaxima- und die Lisp-Sitzung. Die Implementation ist abhängig von dem verwendeten Lisp. Hier ist eine Implementation für 10 verschiedene Lisp-Varianten gezeigt.
Quelltext:
(defun bye () #+(or cmu scl clisp) (ext:quit) #+sbcl (sb-ext:quit) #+allegro (excl:exit) #+(or mcl openmcl) (ccl:quit) #+gcl (lisp:quit) #+ecl (si:quit) #+lispworks (lispworks:quit))
Mit der Funktion $quit
wird eine kMaxima-Sitzung beendet.
Die Lisp-Sitzung wird nicht beendet.
Quelltext:
(defun $quit () (throw 'maxima-quit-to-lisp 0))
Gibt Information über die Nutzung des Speicherplatzes aus.
Quelltext:
(defun used-area (&optional unused) (declare (ignore unused)) (sb-ext:get-bytes-consed))
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
kMaxima speichert die Eingaben und die Ergebnisse in Marken ab. Mit diesen
Marken kann der Nutzer auf vorherige Eingaben und Ergebnisse zurückgreifen.
Standardmäßig ist %i
das Zeichen für die Eingabemarken und
%o
das Zeichen für die Ausgabemarken. kMaxima kennt noch
Zwischenmarken %t
, die noch keine Rolle spielen, aber bereits hier
eingeführt werden. Die Marken werden fortlaufend nummeriert. Die hier
definierten Funktionen und Variablen werden von der Funktion
maxima-toplevel-loop
genutzt.
Folgende Variablen sind für die Verwaltung der Marken definiert. Die globale
Variable *linelabel*
enthält die zuletzt erzeugte Marke. Die
Optionsvariable $linenum
enthält die Nummer der aktuellen Eingabe und
Ausgabe. Die Optionsvariablen $inchar
, $outchar
und
$linechar
enthalten die Zeichen für die die Eingabe-, Ausgaben- und
Zwischenmarken. Mit der Optionsvariablen $nolabels
kann das abspeichern
in den Marken ausgeschaltet werden. Die Optionsvariable $labels
enthält eine Liste aller erzeugten Marken.
Standardwert: nil
Standardwert: 0
Standardwert: $%i
Standardwert: $%o
Standardwert: $%t
Standardwert: nil
Standardwert: (list '(mlist simp))
Die Funktion createlabel
setzt ein Symbol oder eine Zeichenkette x
und eine Nummer num
zu einem Symbol zusammen, das in das aktuelle
Package eingetragen wird. Mit der Funktion checklabel
wird geprüft, ob
eine Marke zum Symbol x
frei ist. Die Rückgabe ist T
, wenn
die Marke genutzt werden kann, ansonsten NIL
. Hat die Optionsvariable
$nolabels
den Wert T
, ist die Rückgabe immer NIL
. Zudem
ist die Rückgabe NIL
, wenn $linenum
den Wert 0
hat. Die
Funktion makelabel
generiert eine Marke zum Symbol x
. Das Symbol
x
ist ein Wert einer der Variablen $inchar
, $outchar
oder
$linechar
. Wenn die Optionsvariable $nolabels
den Wert NIL
hat, sollen Marken genutzt werden und die erzeugte Marke wird der Liste in der
Optionsvariablen $labels
hinzugefügt.
Quelltext:
(defun createlabel (x num) (intern (format nil "~a~d" x num)))
Quelltext:
(defun checklabel (x) (not (or $nolabels (= $linenum 0) (boundp (createlabel x $linenum)))))
Quelltext:
(defun makelabel (x) (declare (special *linelabel*)) (setq *linelabel* (createlabel x $linenum)) (unless $nolabels (when (or (null (cdr $labels)) (when (member *linelabel* (cddr $labels) :test #'equal) (setf $labels (delete *linelabel* $labels :count 1 :test #'eq)) t) (not (eq *linelabel* (cadr $labels)))) (setq $labels (cons (car $labels) (cons *linelabel* (cdr $labels)))))) *linelabel*)
Beispiele: Die folgenden Beispiele zeigen die Verwendung der Funktionen
createlabel
, checklabel
und makelabel
.
* (createlabel $inchar $linenum) $%I0 NIL * (checklabel (createlabel $inchar $linenum)) NIL * (incf $linenum) 1 * (createlabel $inchar $linenum) $%I1 NIL * (checklabel (createlabel $inchar $linenum)) T * (makelabel $inchar) $%I1 * *linelabel* $%I1 * $labels ((MLIST SIMP) $%I1) * (set *linelabel* '((mplus) $a $b)) ((MPLUS) $A $B) * *linelabel* $%I1 * $%I1 ((MPLUS) $A $B) * (checklabel $inchar) NIL * (incf $linenum) 2 * (makelabel $inchar) $%I2 * $labels ((MLIST SIMP) $%I2 $%I1)
Mit den Funktionen getlabels
und getlabels2
werden genutzte
Marken heraus gefiltert. Die Funktion getlabels
gibt die Marken
zurück, die mit einem einem bestimmten Zeichen beginnen. Die Funktion
getlabels
gibt dagegen die Marken in einem Bereich zurück, der mit
den Argumenten n1
und n2
angegeben wird. Hat das optionale
Argument flag
den Wert T
werden nur Eingabemarken ausgewählt.
Die Funktion getfirstcharlabel
ermittelt das erste Zeichen einer Marke,
das verschieden von dem Zeichen $
und %
ist.
Quelltext:
(defun getfirstcharlabel (x) (let ((c (char (symbol-name x) 1))) (if (char= c #\%) (char (symbol-name x) 2) c)))
Quelltext:
(defun getlabels (x) (do ((l (cdr $labels) (cdr l)) (ch (getfirstcharlabel x)) (acc)) ((null l) (reverse acc)) (if (char= (getfirstcharlabel (car l)) ch) (push (car l) acc))))
Quelltext:
(defun getlabels2 (n1 n2 &optional (flag nil)) (do ((i n1 (1+ i)) (acc) (l (if flag (list $inchar) (list $inchar $outchar $linechar)))) ((> i n2) (reverse acc)) (do ((l l (cdr l)) (z)) ((null l)) (if (boundp (setq z (createlabel (first l) i))) (push z acc)))))
Zuletzt folgt noch die Implementierung der Nutzerfunktionen $labels
und
$%th
. Die Funktion $labels
gibt eine Liste aller Marken zurück,
die mit dem Argument x
beginnen. Mit der Funktion $%th
kann auf
das n-te vorhergehende Ergebnis zurückgegriffen werden.
Quelltext:
(defun $labels (x) (cons '(mlist simp) (getlabels x)))
Quelltext:
(defun $%th (x) (prog (l outchar) (if (or (not (fixnump x)) (= x 0)) (merror "Improper argument to ~:M:~%~M" '$%th x)) (if (> x 0) (setq x (- x))) (if (cdr $labels) (setq l (cddr $labels) outchar (getfirstcharlabel $outchar))) loop (if (null l) (merror "Improper call to %th")) (if (and (char= (getfirstcharlabel (car l)) outchar) (= (setq x (1+ x)) 0)) (return (meval (car l)))) (setq l (cdr l)) (go loop)))
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
maxima-toplevel-eval
Die Funktion meval
ersetzt die Lisp-Funktion eval
im
kMaxima-Evaluator der in Der erste Evaluator beschrieben ist. In einem
Computeralgebrasystem werden mathematische Ausdrücke nicht nur ausgewertet,
sondern nach der Auswertung auch vereinfacht. Wir bereiten die Auswertung an
dieser Stelle mit der Einführung der Funktion maxima-toplevel-eval
vor.
Die Funktion ruft zunächst meval
für die Auswertung auf und dann die
Funktion simplifya
, die den ausgewerteten Ausdruck vereinfacht. Die
Rückgabe ist ein ausgwerteter und vereinfachter Ausdruck. Die Funktion
wird von maxima-toplevel-loop
aufgerufen.
Quelltext:
(defun maxima-toplevel-eval (form) (simplifya (meval form) nil))
Quelltext:
(defun meval (form) (simplifya (meval1 form) nil))
Quelltext:
(defun meval1 (form &aux u) (cond ((atom form) (cond ((not (symbolp form)) form) ((not (boundp form)) form) (t (symbol-value form)))) ((consp (car form)) (let ((op (caar form))) (cond ((mfunctionp op) (apply op (mevalargs (cdr form)))) ((setq u (getprop op 'mspec)) (apply u (cons form nil))) ((macro-function op) (eval (cons op (cdr form)))) (t (cons (car form) (mevalargs (cdr form))))))) (t (eval form))))
Quelltext:
(defun mevalargs (args) (mapcar #'meval args))
Die Funktion simplifya
implementiert den Vereinfacher des
Computeralgebrasystems. An dieser Stelle führen wir eine Dummy-Funktion ein,
die erst in einem späteren Kapitel mit Code aufgefüllt wird. Die
Dummy-Funktion hat die Aufgabe das Argument unverändert zurückzugeben. Das
zweite Argument ist ein Schalter, der später genutzt wird, um dem Vereinfacher
mitzuteilen, dass die Argumente eines Operators bereits vereinfacht sind.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
maxima-toplevel-read
Mit dem Parser ist die Funktion mread
definiert worden, die die Eingabe
liest und in einen kMaxima-Ausdruck umwandelt. Die Funktion
maxima-toplevel-loop
ruft nun nicht direkt die Funktion mread
auf,
sondern die Funktion maxima-toplevel-read
. Zunächst wird geprüft, ob
eine Eingabe von der Tastatur erforderlich ist. Ist dies der Fall, wird eine
Eingabeaufforderung ausgegeben. Dann wird geprüft, ob noch Zeichen die
Verschiedenen von #\newline
und #\return
einzulesen sind. Ist
dies nicht der Fall kehrt die Funktion mit dem Ergebnis eof
zurück.
Jetzt wird in der cond
-Anweisung geprüft, ob die Eingabe mit einem
speziellen Symbol beginnt. Maxima kennt die speziellen Zeichen ?
und
:
, die nicht von mread
gelesen werden, sondern bereits an dieser
Stelle verarbeitet werden. Mit :
werden Break-Kommandos eingeleitet.
Dies implementieren wir an dieser Stelle nicht. Mit ?
sowie ??
denen ein Leerzeichen folgt, wird eine abkürzende Schreibweise für den Abruf
von Dokumentation ermöglicht. Anstatt dem Kommando
describe("integrate")
kann der Nutzer auch ? integrate
oder
?? integrate
eingeben. Diese Eingaben werden in den entsprechenden
kMaxima-Ausdruck umgewandelt und als Ergebnis zurückgegeben. Wird das Zeichen
?
einem Symbol vorangestellt, so wird ein Lisp-Symbol bezeichnet. In
diesem Fall wird die Eingabe an die Funktion mread
weitergereicht, die
auch Lisp-Symbole verarbeitet. Liegt kein spezielles Zeichen vor, wird die
Eingabe in der letzten cond
-Anweisung von der Funktion mread
gelesen. Nach dem Einlesen von der Eingabe wird noch geprüft, ob weitere
Zeichen in der Eingabe vorhanden sind. Ist dies nicht der Fall, wird die
Variable *need-prompt*
auf den Wert t
gesetzt, um zu
signalisieren, dass beim nächsten Aufruf der Funktion
maxima-toplevel-read
eine Eingabeaufforderung auszugeben ist.
Standardwert: t
Quelltext:
(defun maxima-toplevel-read (stream eof-p eof) (let ((mprompt *mread-prompt*) (*mread-prompt* "") ch) (if (and *need-prompt* (> (length mprompt) 0)) (progn (fresh-line *standard-output*) (princ mprompt *standard-output*) (force-output *standard-output*) (setf *prompt-on-read-hang* nil)) (progn (setf *prompt-on-read-hang* t) (setf *read-hang-prompt* mprompt))) (tagbody top (setq ch (read-char stream eof-p eof)) (cond ((or (eql ch #\newline) (eql ch #\return)) (go top)) ((eq ch eof) (return-from maxima-toplevel-read eof))) (unread-char ch stream)) (cond ((eql #\? ch) (read-char stream) (let ((next (peek-char nil stream nil))) (cond ((member next '(#\space #\tab #\!)) (let ((line (string-trim '(#\space #\tab #\; #\$ ) (subseq (read-line stream eof-p eof) 1)))) `((displayinput) nil (($describe) ,line $exact)))) ((equal next #\?) (let ((line (string-trim '(#\space #\tab #\; #\$ ) (subseq (read-line stream eof-p eof) 1)))) `((displayinput) nil (($describe) ,line $inexact)))) (t (mread (make-concatenated-stream (make-string-input-stream "?") stream) eof))))) (t (let ((result (mread stream eof)) (next-char (read-char-no-hang stream eof-p eof))) (cond ((or (eql next-char nil) (equal next-char '(nil))) (setf *need-prompt* t)) ((member next-char '(#\newline #\return)) (setf *need-prompt* t)) (t (setf *need-prompt* nil) (unread-char next-char stream))) result)))))
Beispiele: Die ersten Beispiele zeigen die Ergebnisse, wenn das spezielle
Zeichen ?
in der Eingabe gefunden wird. Das letzte Beispiel zeigt die
Eingabe eines mathematischen Ausdrucks.
* (maxima-toplevel-read *standard-input* nil nil) ? integrate ((DISPLAYINPUT) NIL (($DESCRIBE) "integrate" $EXACT)) * (maxima-toplevel-read *standard-input* nil nil) ?? integrate ((DISPLAYINPUT) NIL (($DESCRIBE) "integrate" $INEXACT)) * (maxima-toplevel-read *standard-input* nil nil) ?integrate; ((DISPLAYINPUT) NIL INTEGRATE) * (maxima-toplevel-read *standard-input* nil nil) sin(x)+x^2; ((DISPLAYINPUT) NIL ((MPLUS) (($SIN) $X) ((MEXPT) $X 2)))
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
maxima-toplevel-loop
Wir können nun mit der Funktion maxima-toplevel-loop
die vollständige
Abfolge des Einlesen, des Auswertens, Vereinfachens von Ausdrücken und der
Anzeige des Ergebnisses implementieren. Wir beginnen mit einigen Hilfsfunktionen
und Variablen.
Standardwert: ""
Der Wert der globalen Variablen *prompt-prefix*
wird immer vor der
Ausgabe des Prompts auf der Konsole ausgegeben.
Standardwert: ""
Der Wert der globalen Variablen *prompt-suffix*
wird immer nach der
Ausgabe des Prompts auf der Konsole ausgegeben.
Standardwert: "_"
$prompt
enthält das Zeichen für den Prompt der bei einer
Unterbrechung von kMaxima oder im Demo-Modus ausgegeben wird.
Generiert den Prompt für die Eingabeaufforderung von einer Konsole und gibt diesen als Ergebnis zurück.
Quelltext:
(defun main-prompt () (declare (special *display-labels-p* $inchar $linenum)) (if *display-labels-p* (let ((*print-circle* nil)) (format nil "~A(~A~D) ~A" *prompt-prefix* (print-invert-case (stripdollar $inchar)) $linenum *prompt-suffix*)) ""))
Quelltext:
(defun break-prompt () (let ((*print-circle* nil)) (format nil "~A~A~A" *prompt-prefix* (print-invert-case (stripdollar $prompt)) *prompt-suffix*)))
Mit den Funktionen main-prompt
und break-prompt
werden zwei
unterschiedliche Eingabeaufforderungen implementiert. Die Funktion
main-prompt
gibt die Eingabeforderung zurück, die ausgegeben wird, wenn
die Eingabe eines Nutzers von der Tastatur erwartet wird. Hat die Variable
$inchar
den Standardwert %i
und hat $linenum
zum Beispiel
den Wert 1
, dann gibt main-prompt
die Zeichenkette ($i1)
zurück. Siehe auch Marken für die Eingaben und Ausgaben. Der
Eingabeaufforderung wird die Zeichenkette *prompt-prefix*
vorangestellt und die Zeichenkette *prompt-suffix*
nachgestellt. Mit
diesen Zeichenketten können besondere Steuerbefehle an ein Terminal gesendet
werden, um zum Beispiel die Farbe, den Font oder die Schriftgröße der
Eingabeaufforderung festzulegen.
Die Funktion break-prompt
arbeitet wie die Funktion main-prompt
.
Diese Eingabeaufforderung wird verwendet, wenn eine Datei in einem Demomodus
ausgeführt wird oder wenn das Programm unterbrochen wird, um einen Debugger
aufzurufen. Zu diesem Zeitpunkt ist weder ein Demomodus, noch ein Debugger
für kMaxima implementiert. Das Zeichen für die Eingabeaufforderung ist in
diesem Fall in der Optionsvariablen $prompt
abgelegt und kann vom Nutzer
geändert werden.
Standardwert: ""
Standardwert: nil
Quelltext:
(defun maxima-toplevel-loop (input-stream mode) (declare (special $% $_ $__)) (when (eql mode :demo) (format t "~%At the '~A' prompt, type ';' and <enter> to get next demonstration.~&" (print-invert-case (stripdollar $prompt)))) (catch 'abort-demo (do ((form) (time) (etime) (area) (eof (list nil)) (i-tag) (o-tag)) (nil) (catch 'return-from-debugger (when (or (not (checklabel $inchar)) (not (checklabel $outchar))) (incf $linenum)) (setq i-tag (makelabel $inchar)) (let ((*mread-prompt* (if mode nil (main-prompt)))) (setq form (maxima-toplevel-read input-stream nil eof))) (format t "~a" *general-display-prefix*) (if (eq form eof) (return '$done)) (setq $__ (caddr form)) (unless $nolabels (set i-tag $__)) (when mode (linear-display `((mlabel) ,i-tag , $__))) (setq time (get-internal-run-time) etime (get-internal-real-time)) (setq area (used-area)) (setq $% (maxima-toplevel-eval $__)) (setq time (/ (float (- (get-internal-run-time) time)) internal-time-units-per-second) etime (/ (float (- (get-internal-real-time) etime)) internal-time-units-per-second)) (setq o-tag (makelabel $outchar)) (unless $nolabels (set o-tag $%)) (setq $_ $__) (when $showtime (format t "Evaluation took ~,4F seconds (~,4F elapsed)" time etime) (let ((total-bytes (- (used-area) area))) (cond ((> total-bytes (* 1024 1024)) (format t " using ~,3F MB.~%" (/ total-bytes (* 1024.0 1024.0)))) ((> total-bytes 1024) (format t " using ~,3F KB.~%" (/ total-bytes 1024.0))) (t (format t " using ~:D bytes.~%" total-bytes))))) (unless $nolabels (putprop '$% (cons time etime) 'time) (putprop o-tag (cons time etime) 'time)) (if (eq (caar form) 'displayinput) (linear-display `((mlabel) ,o-tag ,$%))) (when (eq mode ':demo) (princ (break-prompt)) (force-output) (let (quitting) (do ((char)) (nil) (case (setq char (read-char *terminal-io*)) ((#\page) (fresh-line) (princ (break-prompt)) (force-output)) ((#\?) (format t "Pausing. Type a ';' and <enter> to continue demo.~%")) ((#\space #\; #\n #\e #\x #\t)) ((#\newline) (if quitting (throw 'abort-demo nil) (return nil))) (t (setq quitting t)))))) (when mode (do ((char)) (()) (setq char (read-char input-stream nil nil)) (when (null char) (throw 'macsyma-quit nil)) (unless (member char '(#\space #\newline #\return #\tab)) (unread-char char input-stream) (return nil))))))))
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Standardwert: nil
Standardwert: nil
Quelltext:
(let ((maxima-started nil)) (defun maxima-toplevel (input-stream mode) (in-package :kmaxima) (if maxima-started (format t "Maxima restarted.~%") (progn (if (not *maxima-quiet*) (maxima-banner)) (setq maxima-started t))) (catch 'maxima-quit-toplevel (loop (catch 'maxima-continue (maxima-toplevel-loop input-stream mode) (format t *maxima-epilog*) (bye))))))
Quelltext:
(defun cl-user::run () (in-package :kmaxima) (let ((input-stream *standard-input*) (mode nil)) (catch 'maxima-quit-to-lisp (loop (with-simple-restart (kmaxima "Return to kMaxima top level.") (maxima-toplevel input-stream mode)))))) (import 'cl-user::run)
Quelltext:
(defun $writefile (filename) (let ((msg (dribble filename))) (format t "~&~A~&" msg) '$done))
Quelltext:
(defun $closefile () (let ((msg (dribble))) (format t "~&~A~&" msg)) '$done)
Quelltext:
(defun merror (message &rest args) (apply #'format `(t ,message ,@args)) (format t "~& -- an error. To debug this try: debugmode(true);~%") (throw 'maxima-continue 'maxima-error))
Standardwert: nil
Standardwert: nil
Standardwert: nil
(defprop $optionset boolset assign)
Quelltext:
(defun mset (x y) (cond ((symbolp x) (let ((f (getprop x 'assign))) (if (and f (or (not (eq x y)) (eq f 'neverset))) (if (eq (funcall f x y) 'munbindp) (return-from mset nil)))) (cond ((not (boundp x)) (push x *values*)) ((and (not (eq x y)) (boundp x) (not (member x *values*))) (if $optionset (format t "assignment: assigning to option ~A~%" x)) (push x *options*))) (return-from mset (setf (symbol-value x) y))) (t (merror "assignment: cannot assign to ~A~%" x))))
Standardwert: nil
Quelltext:
(defun mseterror (var val) (declare (special *munbindp*)) (if *munbindp* 'munbindp (merror "assignment: cannot assign ~a to ~a" val var)))
Quelltext:
(defun neverset (var val) (mseterror var val))
Quelltext:
(defun boolset (var val) (if (not (member val '(t nil $false $true))) (mseterror var val)))
Quelltext:
(defun shadowset (var val) (mset (get var 'shadowvar) val))
Quelltext:
(defun shadowboolset (var val) (if (not (member val '(t nil $false $true))) (mseterror var val) (mset (get var 'shadowvar) val)))
Quelltext:
(defun $values () (cons '(mlist simp) (copy-list *values*)))
Quelltext:
(defun $options () (cons '(mlist simp) (copy-list *options*)))
Quelltext:
(defmspec mquote (form) (cadr form))
Quelltext:
(defmspec msetq (l) (mset (cadr l) (meval (caddr l))))
Quelltext:
(defun reset1 (args) (declare (special *variable-initial-values*)) (labels ((maybe-reset (key val) (let ((reset nil)) (when (and (boundp key) (not (alike1 (symbol-value key) val))) (setq reset key) (let ((*munbindp* t) ($optionset nil)) (declare (special *munbindp* $optionset)) (meval `((msetq) ,key ((mquote) ,val))))) reset))) (let ((actually-reset nil)) (if args (mapcar #'(lambda (key) (multiple-value-bind (val found-p) (gethash key *variable-initial-values*) (if found-p (if (maybe-reset key val) (push key actually-reset))))) args) (maphash #'(lambda (key val) (if (maybe-reset key val) (push key actually-reset))) *variable-initial-values*)) (cons '(mlist) (nreverse actually-reset)))))
Quelltext:
(defmspec $reset (l) (reset1 (cdr l)))
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Dieter Kaiser on Dezember, 13 2011 using texi2html 1.76.