[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7. Systemfunktionen


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1 Einführung in Systemfunktionen

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] [ ? ]

7.2 Einfache Systemfunktionen

Globale Variable: *maxima-version*

Standardwert: 0.1

Enthält die aktuelle Version von kMaxima.

Funktion: maxima-banner

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.~%"))

Funktion: bye

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))

Funktion: $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))

Funktion: used-area &optional unused

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] [ ? ]

7.3 Marken für die Eingaben und Ausgaben

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.

Globale Variable: *linelabel*

Standardwert: nil

Globale Variable: $linenum

Standardwert: 0

Globale Variable: $inchar

Standardwert: $%i

Globale Variable: $outchar

Standardwert: $%o

Globale Variable: $linechar

Standardwert: $%t

Globale Variable: $nolabels

Standardwert: nil

Globale Variable: $labels

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.

Funktion: createlabel x num

Quelltext:

(defun createlabel (x num)
  (intern (format nil "~a~d" x num)))

Funktion: checklabel x

Quelltext:

(defun checklabel (x)
  (not (or $nolabels
           (= $linenum 0)
           (boundp (createlabel x $linenum)))))

Funktion: makelabel x

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.

Funktion: getfirstcharlabel x

Quelltext:

(defun getfirstcharlabel (x)
  (let ((c (char (symbol-name x) 1)))
    (if (char= c #\%)
        (char (symbol-name x) 2)
        c)))

Funktion: getlabels x

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))))

Funktion: getlabels2 n1 n2 &optional (flag nil)

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.

Funktion: $labels x

Quelltext:

(defun $labels (x)
  (cons '(mlist simp) (getlabels x)))

Funktion: %th 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] [ ? ]

7.4 Die Funktion 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.

Funktion: maxima-toplevel-eval form

Quelltext:

(defun maxima-toplevel-eval (form)
  (simplifya (meval form) nil))

Funktion: meval form

Quelltext:

(defun meval (form)
  (simplifya (meval1 form) nil))

Funktion: meval1 form

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))))

Funktion: mevalargs args

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] [ ? ]

7.5 Die Funktion 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.

Globale Variable: *need-prompt*

Standardwert: t

Funktion: maxima-toplevel-read stream eof-p eof

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] [ ? ]

7.6 Die Funktion 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.

Globale Variable: *prompt-prefix*

Standardwert: ""

Der Wert der globalen Variablen *prompt-prefix* wird immer vor der Ausgabe des Prompts auf der Konsole ausgegeben.

Globale Variable: *prompt-suffix*

Standardwert: ""

Der Wert der globalen Variablen *prompt-suffix* wird immer nach der Ausgabe des Prompts auf der Konsole ausgegeben.

Optionsvariable: $prompt

Standardwert: "_"

$prompt enthält das Zeichen für den Prompt der bei einer Unterbrechung von kMaxima oder im Demo-Modus ausgegeben wird.

Funktion: main-prompt

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*))
      ""))

Funktion: break-prompt

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.

Globale Variable: *general-display-prefix*

Standardwert: ""

Optionsvariable: $showtime

Standardwert: nil

Funktion: maxima-toplevel-loop input-stream mode

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] [ ? ]

7.7 Weitere Systemfunktionen

Globale Variable: *maxima-quit*

Standardwert: nil

Globale Variable: *maxima-epilog*

Standardwert: nil

Funktion: maxima-toplevel input-stream mode

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))))))

Funktion: cl-user::run

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)

Funktion: $writefile filename

Quelltext:

(defun $writefile (filename)
  (let ((msg (dribble filename)))
    (format t "~&~A~&" msg)
    '$done))

Funktion: $closefile

Quelltext:

(defun $closefile ()
  (let ((msg (dribble)))
    (format t "~&~A~&" msg))
  '$done)

Funktion: merror message &rest args

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))

Globale Variable: *values*

Standardwert: nil

Globale Variable: *options*

Standardwert: nil

Optionsvariable: $optionset

Standardwert: nil

(defprop $optionset boolset assign)

Funktion: mset

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))))

Globale Variable: *munbindp*

Standardwert: nil

Funktion: mseterror var val

Quelltext:

(defun mseterror (var val)
  (declare (special *munbindp*))
  (if *munbindp*
      'munbindp
      (merror "assignment: cannot assign ~a to ~a" val var)))

Funktion: neverset var val

Quelltext:

(defun neverset (var val)
  (mseterror var val))

Funktion: boolset var val

Quelltext:

(defun boolset (var val)
  (if (not (member val '(t nil $false $true)))
      (mseterror var val)))

Funktion: shadowset var val

Quelltext:

(defun shadowset (var val)
  (mset (get var 'shadowvar) val))

Funktion: shadowboolset var val

Quelltext:

(defun shadowboolset (var val)
  (if (not (member val '(t nil $false $true)))
      (mseterror var val)
      (mset (get var 'shadowvar) val)))

Funktion: $values

Quelltext:

(defun $values ()
  (cons '(mlist simp) (copy-list *values*)))

Funktion: $options

Quelltext:

(defun $options ()
  (cons '(mlist simp) (copy-list *options*)))

Spezialform: mquote form

Quelltext:

(defmspec mquote (form)
  (cadr form))

Spezialform: msetq l

Quelltext:

(defmspec msetq (l)
  (mset (cadr l) (meval (caddr l))))

Funktion: reset1 args

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)))))

Spezialform: $reset1 l

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.