diff lisp/calc/calc-aent.el @ 40785:2fb9d407ae73

Initial import of Calc 2.02f.
author Eli Zaretskii <eliz@gnu.org>
date Tue, 06 Nov 2001 18:59:06 +0000
parents
children 09249b7679f6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/calc/calc-aent.el	Tue Nov 06 18:59:06 2001 +0000
@@ -0,0 +1,1163 @@
+;; Calculator for GNU Emacs, part I [calc-aent.el]
+;; Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+;; Written by Dave Gillespie, daveg@synaptics.com.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY.  No author or distributor
+;; accepts responsibility to anyone for the consequences of using it
+;; or for whether it serves any particular purpose or works at all,
+;; unless he says so in writing.  Refer to the GNU Emacs General Public
+;; License for full details.
+
+;; Everyone is granted permission to copy, modify and redistribute
+;; GNU Emacs, but only under the conditions described in the
+;; GNU Emacs General Public License.   A copy of this license is
+;; supposed to have been given to you along with GNU Emacs so you
+;; can know your rights and responsibilities.  It should be in a
+;; file named COPYING.  Among other things, the copyright notice
+;; and this notice must be preserved on all copies.
+
+
+
+;; This file is autoloaded from calc.el.
+(require 'calc)
+
+(require 'calc-macs)
+
+(defun calc-Need-calc-aent () nil)
+
+
+(defun calc-do-quick-calc ()
+  (calc-check-defines)
+  (if (eq major-mode 'calc-mode)
+      (calc-algebraic-entry t)
+    (let (buf shortbuf)
+      (save-excursion
+	(calc-create-buffer)
+	(let* ((calc-command-flags nil)
+	       (calc-dollar-values calc-quick-prev-results)
+	       (calc-dollar-used 0)
+	       (enable-recursive-minibuffers t)
+	       (calc-language (if (memq calc-language '(nil big))
+				  'flat calc-language))
+	       (entry (calc-do-alg-entry "" "Quick calc: " t))
+	       (alg-exp (mapcar (function
+				 (lambda (x)
+				   (if (and (not calc-extensions-loaded)
+					    calc-previous-alg-entry
+					    (string-match
+					     "\\`[-0-9._+*/^() ]+\\'"
+					     calc-previous-alg-entry))
+				       (calc-normalize x)
+				     (calc-extensions)
+				     (math-evaluate-expr x))))
+				entry)))
+	  (if (and (= (length alg-exp) 1)
+		   (eq (car-safe (car alg-exp)) 'calcFunc-assign)
+		   (= (length (car alg-exp)) 3)
+		   (eq (car-safe (nth 1 (car alg-exp))) 'var))
+	      (progn
+		(calc-extensions)
+		(set (nth 2 (nth 1 (car alg-exp))) (nth 2 (car alg-exp)))
+		(calc-refresh-evaltos (nth 2 (nth 1 (car alg-exp))))
+		(setq alg-exp (list (nth 2 (car alg-exp))))))
+	  (setq calc-quick-prev-results alg-exp
+		buf (mapconcat (function (lambda (x)
+					   (math-format-value x 1000)))
+			       alg-exp
+			       " ")
+		shortbuf buf)
+	  (if (and (= (length alg-exp) 1)
+		   (memq (car-safe (car alg-exp)) '(nil bigpos bigneg))
+		   (< (length buf) 20)
+		   (= calc-number-radix 10))
+	      (setq buf (concat buf "  ("
+				(let ((calc-number-radix 16))
+				  (math-format-value (car alg-exp) 1000))
+				", "
+				(let ((calc-number-radix 8))
+				  (math-format-value (car alg-exp) 1000))
+				(if (and (integerp (car alg-exp))
+					 (> (car alg-exp) 0)
+					 (< (car alg-exp) 127))
+				    (format ", \"%c\"" (car alg-exp))
+				  "")
+				")")))
+	  (if (and (< (length buf) (screen-width)) (= (length entry) 1)
+		   calc-extensions-loaded)
+	      (let ((long (concat (math-format-value (car entry) 1000)
+				  " =>  " buf)))
+		(if (<= (length long) (- (screen-width) 8))
+		    (setq buf long))))
+	  (calc-handle-whys)
+	  (message "Result: %s" buf)))
+      (if (eq last-command-char 10)
+	  (insert shortbuf)
+	(setq kill-ring (cons shortbuf kill-ring))
+	(if (> (length kill-ring) kill-ring-max)
+	    (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))
+	(setq kill-ring-yank-pointer kill-ring))))
+)
+
+(defun calc-do-calc-eval (str separator args)
+  (calc-check-defines)
+  (catch 'calc-error
+    (save-excursion
+      (calc-create-buffer)
+      (cond
+       ((and (consp str) (not (symbolp (car str))))
+	(let ((calc-language nil)
+	      (math-expr-opers math-standard-opers)
+	      (calc-internal-prec 12)
+	      (calc-word-size 32)
+	      (calc-symbolic-mode nil)
+	      (calc-matrix-mode nil)
+	      (calc-angle-mode 'deg)
+	      (calc-number-radix 10)
+	      (calc-leading-zeros nil)
+	      (calc-group-digits nil)
+	      (calc-point-char ".")
+	      (calc-frac-format '(":" nil))
+	      (calc-prefer-frac nil)
+	      (calc-hms-format "%s@ %s' %s\"")
+	      (calc-date-format '((H ":" mm C SS pp " ")
+				  Www " " Mmm " " D ", " YYYY))
+	      (calc-float-format '(float 0))
+	      (calc-full-float-format '(float 0))
+	      (calc-complex-format nil)
+	      (calc-matrix-just nil)
+	      (calc-full-vectors t)
+	      (calc-break-vectors nil)
+	      (calc-vector-commas ",")
+	      (calc-vector-brackets "[]")
+	      (calc-matrix-brackets '(R O))
+	      (calc-complex-mode 'cplx)
+	      (calc-infinite-mode nil)
+	      (calc-display-strings nil)
+	      (calc-simplify-mode nil)
+	      (calc-display-working-message 'lots)
+	      (strp (cdr str)))
+	  (while strp
+	    (set (car strp) (nth 1 strp))
+	    (setq strp (cdr (cdr strp))))
+	  (calc-do-calc-eval (car str) separator args)))
+       ((eq separator 'eval)
+	(eval str))
+       ((eq separator 'macro)
+	(calc-extensions)
+	(let* ((calc-buffer (current-buffer))
+	       (calc-window (get-buffer-window calc-buffer))
+	       (save-window (selected-window)))
+	  (if calc-window
+	      (unwind-protect
+		  (progn
+		    (select-window calc-window)
+		    (calc-execute-kbd-macro str nil (car args)))
+		(and (window-point save-window)
+		     (select-window save-window)))
+	    (save-window-excursion
+	      (select-window (get-largest-window))
+	      (switch-to-buffer calc-buffer)
+	      (calc-execute-kbd-macro str nil (car args)))))
+	nil)
+       ((eq separator 'pop)
+	(or (not (integerp str))
+	    (= str 0)
+	    (calc-pop (min str (calc-stack-size))))
+	(calc-stack-size))
+       ((eq separator 'top)
+	(and (integerp str)
+	     (> str 0)
+	     (<= str (calc-stack-size))
+	     (math-format-value (calc-top-n str (car args)) 1000)))
+       ((eq separator 'rawtop)
+	(and (integerp str)
+	     (> str 0)
+	     (<= str (calc-stack-size))
+	     (calc-top-n str (car args))))
+       (t
+	(let* ((calc-command-flags nil)
+	       (calc-next-why nil)
+	       (calc-language (if (memq calc-language '(nil big))
+				  'flat calc-language))
+	       (calc-dollar-values (mapcar
+				    (function
+				     (lambda (x)
+				       (if (stringp x)
+					   (progn
+					     (setq x (math-read-exprs x))
+					     (if (eq (car-safe x)
+						     'error)
+						 (throw 'calc-error
+							(calc-eval-error
+							 (cdr x)))
+					       (car x)))
+					 x)))
+				    args))
+	       (calc-dollar-used 0)
+	       (res (if (stringp str)
+			(math-read-exprs str)
+		      (list str)))
+	       buf)
+	  (if (eq (car res) 'error)
+	      (calc-eval-error (cdr res))
+	    (setq res (mapcar 'calc-normalize res))
+	    (and (memq 'clear-message calc-command-flags)
+		 (message ""))
+	    (cond ((eq separator 'pred)
+		   (calc-extensions)
+		   (if (= (length res) 1)
+		       (math-is-true (car res))
+		     (calc-eval-error '(0 "Single value expected"))))
+		  ((eq separator 'raw)
+		   (if (= (length res) 1)
+		       (car res)
+		     (calc-eval-error '(0 "Single value expected"))))
+		  ((eq separator 'list)
+		   res)
+		  ((memq separator '(num rawnum))
+		   (if (= (length res) 1)
+		       (if (math-constp (car res))
+			   (if (eq separator 'num)
+			       (math-format-value (car res) 1000)
+			     (car res))
+			 (calc-eval-error
+			  (list 0
+				(if calc-next-why
+				    (calc-explain-why (car calc-next-why))
+				  "Number expected"))))
+		     (calc-eval-error '(0 "Single value expected"))))
+		  ((eq separator 'push)
+		   (calc-push-list res)
+		   nil)
+		  (t (while res
+		       (setq buf (concat buf
+					 (and buf (or separator ", "))
+					 (math-format-value (car res) 1000))
+			     res (cdr res)))
+		     buf))))))))
+)
+
+(defun calc-eval-error (msg)
+  (if (and (boundp 'calc-eval-error)
+	   calc-eval-error)
+      (if (eq calc-eval-error 'string)
+	  (nth 1 msg)
+	(error "%s" (nth 1 msg)))
+    msg)
+)
+
+
+;;;; Reading an expression in algebraic form.
+
+(defun calc-auto-algebraic-entry (&optional prefix)
+  (interactive "P")
+  (calc-algebraic-entry prefix t)
+)
+
+(defun calc-algebraic-entry (&optional prefix auto)
+  (interactive "P")
+  (calc-wrapper
+   (let ((calc-language (if prefix nil calc-language))
+	 (math-expr-opers (if prefix math-standard-opers math-expr-opers)))
+     (calc-alg-entry (and auto (char-to-string last-command-char)))))
+)
+
+(defun calc-alg-entry (&optional initial prompt)
+  (let* ((sel-mode nil)
+	 (calc-dollar-values (mapcar 'calc-get-stack-element
+				     (nthcdr calc-stack-top calc-stack)))
+	 (calc-dollar-used 0)
+	 (calc-plain-entry t)
+	 (alg-exp (calc-do-alg-entry initial prompt t)))
+    (if (stringp alg-exp)
+	(progn
+	  (calc-extensions)
+	  (calc-alg-edit alg-exp))
+      (let* ((calc-simplify-mode (if (eq last-command-char ?\C-j)
+				     'none
+				   calc-simplify-mode))
+	     (nvals (mapcar 'calc-normalize alg-exp)))
+	(while alg-exp
+	  (calc-record (if calc-extensions-loaded (car alg-exp) (car nvals))
+		       "alg'")
+	  (calc-pop-push-record-list calc-dollar-used
+				     (and (not (equal (car alg-exp)
+						      (car nvals)))
+					  calc-extensions-loaded
+					  "")
+				     (list (car nvals)))
+	  (setq alg-exp (cdr alg-exp)
+		nvals (cdr nvals)
+		calc-dollar-used 0)))
+      (calc-handle-whys)))
+)
+
+(defun calc-do-alg-entry (&optional initial prompt no-normalize)
+  (let* ((calc-buffer (current-buffer))
+	 (blink-paren-hook 'calcAlg-blink-matching-open)
+	 (alg-exp 'error))
+    (if (boundp 'calc-alg-ent-map)
+	()
+      (setq calc-alg-ent-map (copy-keymap minibuffer-local-map))
+      (define-key calc-alg-ent-map "'" 'calcAlg-previous)
+      (define-key calc-alg-ent-map "`" 'calcAlg-edit)
+      (define-key calc-alg-ent-map "\C-m" 'calcAlg-enter)
+      (define-key calc-alg-ent-map "\C-j" 'calcAlg-enter)
+      (or calc-emacs-type-19
+	  (let ((i 33))
+	    (setq calc-alg-ent-esc-map (copy-sequence esc-map))
+	    (while (< i 127)
+	      (aset calc-alg-ent-esc-map i 'calcAlg-escape)
+	      (setq i (1+ i))))))
+    (or calc-emacs-type-19
+	(define-key calc-alg-ent-map "\e" nil))
+    (if (eq calc-algebraic-mode 'total)
+	(define-key calc-alg-ent-map "\e" calc-alg-ent-esc-map)
+      (define-key calc-alg-ent-map "\ep" 'calcAlg-plus-minus)
+      (define-key calc-alg-ent-map "\em" 'calcAlg-mod)
+      (define-key calc-alg-ent-map "\e=" 'calcAlg-equals)
+      (define-key calc-alg-ent-map "\e\r" 'calcAlg-equals)
+      (define-key calc-alg-ent-map "\e%" 'self-insert-command))
+    (setq calc-aborted-prefix nil)
+    (let ((buf (read-from-minibuffer (or prompt "Algebraic: ")
+				     (or initial "")
+				     calc-alg-ent-map nil)))
+      (if (eq alg-exp 'error)
+	  (if (eq (car-safe (setq alg-exp (math-read-exprs buf))) 'error)
+	      (setq alg-exp nil)))
+      (setq calc-aborted-prefix "alg'")
+      (or no-normalize
+	  (and alg-exp (setq alg-exp (mapcar 'calc-normalize alg-exp))))
+      alg-exp))
+)
+
+(defun calcAlg-plus-minus ()
+  (interactive)
+  (if (calc-minibuffer-contains ".* \\'")
+      (insert "+/- ")
+    (insert " +/- "))
+)
+
+(defun calcAlg-mod ()
+  (interactive)
+  (if (not (calc-minibuffer-contains ".* \\'"))
+      (insert " "))
+  (if (calc-minibuffer-contains ".* mod +\\'")
+      (if calc-previous-modulo
+	  (insert (math-format-flat-expr calc-previous-modulo 0))
+	(beep))
+    (insert "mod "))
+)
+
+(defun calcAlg-previous ()
+  (interactive)
+  (if (calc-minibuffer-contains "\\`\\'")
+      (if calc-previous-alg-entry
+	  (insert calc-previous-alg-entry)
+	(beep))
+    (insert "'"))
+)
+
+(defun calcAlg-equals ()
+  (interactive)
+  (unwind-protect
+      (calcAlg-enter)
+    (if (consp alg-exp)
+	(progn (setq prefix-arg (length alg-exp))
+	       (calc-unread-command ?=))))
+)
+
+(defun calcAlg-escape ()
+  (interactive)
+  (calc-unread-command)
+  (save-excursion
+    (calc-select-buffer)
+    (use-local-map calc-mode-map))
+  (calcAlg-enter)
+)
+
+(defun calcAlg-edit ()
+  (interactive)
+  (if (or (not calc-plain-entry)
+	  (calc-minibuffer-contains
+	   "\\`\\([^\"]*\"[^\"]*\"\\)*[^\"]*\"[^\"]*\\'"))
+      (insert "`")
+    (setq alg-exp (buffer-string))
+    (and (> (length alg-exp) 0) (setq calc-previous-alg-entry alg-exp))
+    (exit-minibuffer))
+)
+(setq calc-plain-entry nil)
+
+(defun calcAlg-enter ()
+  (interactive)
+  (let* ((str (buffer-string))
+	 (exp (and (> (length str) 0)
+		   (save-excursion
+		     (set-buffer calc-buffer)
+		     (math-read-exprs str)))))
+    (if (eq (car-safe exp) 'error)
+	(progn
+	  (goto-char (point-min))
+	  (forward-char (nth 1 exp))
+	  (beep)
+	  (calc-temp-minibuffer-message
+	   (concat " [" (or (nth 2 exp) "Error") "]"))
+	  (calc-clear-unread-commands))
+      (setq alg-exp (if (calc-minibuffer-contains "\\` *\\[ *\\'")
+			'((incomplete vec))
+		      exp))
+      (and (> (length str) 0) (setq calc-previous-alg-entry str))
+      (exit-minibuffer)))
+)
+
+(defun calcAlg-blink-matching-open ()
+  (let ((oldpos (point))
+	(blinkpos nil))
+    (save-excursion
+      (condition-case ()
+	  (setq blinkpos (scan-sexps oldpos -1))
+	(error nil)))
+    (if (and blinkpos
+	     (> oldpos (1+ (point-min)))
+	     (or (and (= (char-after (1- oldpos)) ?\))
+		      (= (char-after blinkpos) ?\[))
+		 (and (= (char-after (1- oldpos)) ?\])
+		      (= (char-after blinkpos) ?\()))
+	     (save-excursion
+	       (goto-char blinkpos)
+	       (looking-at ".+\\(\\.\\.\\|\\\\dots\\|\\\\ldots\\)")))
+	(let ((saved (aref (syntax-table) (char-after blinkpos))))
+	  (unwind-protect
+	      (progn
+		(aset (syntax-table) (char-after blinkpos)
+		      (+ (logand saved 255)
+			 (lsh (char-after (1- oldpos)) 8)))
+		(blink-matching-open))
+	    (aset (syntax-table) (char-after blinkpos) saved)))
+      (blink-matching-open)))
+)
+
+
+(defun calc-alg-digit-entry ()
+  (calc-alg-entry 
+   (cond ((eq last-command-char ?e)
+	  (if (> calc-number-radix 14) (format "%d.^" calc-number-radix) "1e"))
+	 ((eq last-command-char ?#) (format "%d#" calc-number-radix))
+	 ((eq last-command-char ?_) "-")
+	 ((eq last-command-char ?@) "0@ ")
+	 (t (char-to-string last-command-char))))
+)
+
+(defun calcDigit-algebraic ()
+  (interactive)
+  (if (calc-minibuffer-contains ".*[@oh] *[^'m ]+[^'m]*\\'")
+      (calcDigit-key)
+    (setq calc-digit-value (buffer-string))
+    (exit-minibuffer))
+)
+
+(defun calcDigit-edit ()
+  (interactive)
+  (calc-unread-command)
+  (setq calc-digit-value (buffer-string))
+  (exit-minibuffer)
+)
+
+
+;;; Algebraic expression parsing.   [Public]
+
+(defun math-read-exprs (exp-str)
+  (let ((exp-pos 0)
+	(exp-old-pos 0)
+	(exp-keep-spaces nil)
+	exp-token exp-data)
+    (if calc-language-input-filter
+	(setq exp-str (funcall calc-language-input-filter exp-str)))
+    (while (setq exp-token (string-match "\\.\\.\\([^.]\\|.[^.]\\)" exp-str))
+      (setq exp-str (concat (substring exp-str 0 exp-token) "\\dots"
+			    (substring exp-str (+ exp-token 2)))))
+    (math-build-parse-table)
+    (math-read-token)
+    (let ((val (catch 'syntax (math-read-expr-list))))
+      (if (stringp val)
+	  (list 'error exp-old-pos val)
+	(if (equal exp-token 'end)
+	    val
+	  (list 'error exp-old-pos "Syntax error")))))
+)
+
+(defun math-read-expr-list ()
+  (let* ((exp-keep-spaces nil)
+	 (val (list (math-read-expr-level 0)))
+	 (last val))
+    (while (equal exp-data ",")
+      (math-read-token)
+      (let ((rest (list (math-read-expr-level 0))))
+	(setcdr last rest)
+	(setq last rest)))
+    val)
+)
+
+(setq calc-user-parse-table nil)
+(setq calc-last-main-parse-table nil)
+(setq calc-last-lang-parse-table nil)
+(setq calc-user-tokens nil)
+(setq calc-user-token-chars nil)
+
+(defun math-build-parse-table ()
+  (let ((mtab (cdr (assq nil calc-user-parse-tables)))
+	(ltab (cdr (assq calc-language calc-user-parse-tables))))
+    (or (and (eq mtab calc-last-main-parse-table)
+	     (eq ltab calc-last-lang-parse-table))
+	(let ((p (append mtab ltab))
+	      (toks nil))
+	  (setq calc-user-parse-table p)
+	  (setq calc-user-token-chars nil)
+	  (while p
+	    (math-find-user-tokens (car (car p)))
+	    (setq p (cdr p)))
+	  (setq calc-user-tokens (mapconcat 'identity
+					    (sort (mapcar 'car toks)
+						  (function (lambda (x y)
+							      (> (length x)
+								 (length y)))))
+					    "\\|")
+		calc-last-main-parse-table mtab
+		calc-last-lang-parse-table ltab))))
+)
+
+(defun math-find-user-tokens (p)   ; uses "toks"
+  (while p
+    (cond ((and (stringp (car p))
+		(or (> (length (car p)) 1) (equal (car p) "$")
+		    (equal (car p) "\""))
+		(string-match "[^a-zA-Z0-9]" (car p)))
+	   (let ((s (regexp-quote (car p))))
+	     (if (string-match "\\`[a-zA-Z0-9]" s)
+		 (setq s (concat "\\<" s)))
+	     (if (string-match "[a-zA-Z0-9]\\'" s)
+		 (setq s (concat s "\\>")))
+	     (or (assoc s toks)
+		 (progn
+		   (setq toks (cons (list s) toks))
+		   (or (memq (aref (car p) 0) calc-user-token-chars)
+		       (setq calc-user-token-chars
+			     (cons (aref (car p) 0)
+				   calc-user-token-chars)))))))
+	  ((consp (car p))
+	   (math-find-user-tokens (nth 1 (car p)))
+	   (or (eq (car (car p)) '\?)
+	       (math-find-user-tokens (nth 2 (car p))))))
+    (setq p (cdr p)))
+)
+
+(defun math-read-token ()
+  (if (>= exp-pos (length exp-str))
+      (setq exp-old-pos exp-pos
+	    exp-token 'end
+	    exp-data "\000")
+    (let ((ch (aref exp-str exp-pos)))
+      (setq exp-old-pos exp-pos)
+      (cond ((memq ch '(32 10 9))
+	     (setq exp-pos (1+ exp-pos))
+	     (if exp-keep-spaces
+		 (setq exp-token 'space
+		       exp-data " ")
+	       (math-read-token)))
+	    ((and (memq ch calc-user-token-chars)
+		  (let ((case-fold-search nil))
+		    (eq (string-match calc-user-tokens exp-str exp-pos)
+			exp-pos)))
+	     (setq exp-token 'punc
+		   exp-data (math-match-substring exp-str 0)
+		   exp-pos (match-end 0)))
+	    ((or (and (>= ch ?a) (<= ch ?z))
+		 (and (>= ch ?A) (<= ch ?Z)))
+	     (string-match (if (memq calc-language '(c fortran pascal maple))
+			       "[a-zA-Z0-9_#]*"
+			     "[a-zA-Z0-9'#]*")
+			   exp-str exp-pos)
+	     (setq exp-token 'symbol
+		   exp-pos (match-end 0)
+		   exp-data (math-restore-dashes
+			     (math-match-substring exp-str 0)))
+	     (if (eq calc-language 'eqn)
+		 (let ((code (assoc exp-data math-eqn-ignore-words)))
+		   (cond ((null code))
+			 ((null (cdr code))
+			  (math-read-token))
+			 ((consp (nth 1 code))
+			  (math-read-token)
+			  (if (assoc exp-data (cdr code))
+			      (setq exp-data (format "%s %s"
+						     (car code) exp-data))))
+			 ((eq (nth 1 code) 'punc)
+			  (setq exp-token 'punc
+				exp-data (nth 2 code)))
+			 (t
+			  (math-read-token)
+			  (math-read-token))))))
+	    ((or (and (>= ch ?0) (<= ch ?9))
+		 (and (eq ch '?\.)
+		      (eq (string-match "\\.[0-9]" exp-str exp-pos) exp-pos))
+		 (and (eq ch '?_)
+		      (eq (string-match "_\\.?[0-9]" exp-str exp-pos) exp-pos)
+		      (or (eq exp-pos 0)
+			  (and (memq calc-language '(nil flat big unform
+							 tex eqn))
+			       (eq (string-match "[^])}\"a-zA-Z0-9'$]_"
+						 exp-str (1- exp-pos))
+				   (1- exp-pos))))))
+	     (or (and (eq calc-language 'c)
+		      (string-match "0[xX][0-9a-fA-F]+" exp-str exp-pos))
+		 (string-match "_?\\([0-9]+.?0*@ *\\)?\\([0-9]+.?0*' *\\)?\\(0*\\([2-9]\\|1[0-4]\\)\\(#\\|\\^\\^\\)[0-9a-dA-D.]+[eE][-+_]?[0-9]+\\|0*\\([2-9]\\|[0-2][0-9]\\|3[0-6]\\)\\(#\\|\\^\\^\\)[0-9a-zA-Z:.]+\\|[0-9]+:[0-9:]+\\|[0-9.]+\\([eE][-+_]?[0-9]+\\)?\"?\\)?" exp-str exp-pos))
+	     (setq exp-token 'number
+		   exp-data (math-match-substring exp-str 0)
+		   exp-pos (match-end 0)))
+	    ((eq ch ?\$)
+	     (if (and (eq calc-language 'pascal)
+		      (eq (string-match
+			   "\\(\\$[0-9a-fA-F]+\\)\\($\\|[^0-9a-zA-Z]\\)"
+			   exp-str exp-pos)
+			  exp-pos))
+		 (setq exp-token 'number
+		       exp-data (math-match-substring exp-str 1)
+		       exp-pos (match-end 1))
+	       (if (eq (string-match "\\$\\([1-9][0-9]*\\)" exp-str exp-pos)
+		       exp-pos)
+		   (setq exp-data (- (string-to-int (math-match-substring
+						     exp-str 1))))
+		 (string-match "\\$+" exp-str exp-pos)
+		 (setq exp-data (- (match-end 0) (match-beginning 0))))
+	       (setq exp-token 'dollar
+		     exp-pos (match-end 0))))
+	    ((eq ch ?\#)
+	     (if (eq (string-match "#\\([1-9][0-9]*\\)" exp-str exp-pos)
+		     exp-pos)
+		 (setq exp-data (string-to-int
+				 (math-match-substring exp-str 1))
+		       exp-pos (match-end 0))
+	       (setq exp-data 1
+		     exp-pos (1+ exp-pos)))
+	     (setq exp-token 'hash))
+	    ((eq (string-match "~=\\|<=\\|>=\\|<>\\|/=\\|\\+/-\\|\\\\dots\\|\\\\ldots\\|\\*\\*\\|<<\\|>>\\|==\\|!=\\|&&&\\||||\\|!!!\\|&&\\|||\\|!!\\|:=\\|::\\|=>"
+			       exp-str exp-pos)
+		 exp-pos)
+	     (setq exp-token 'punc
+		   exp-data (math-match-substring exp-str 0)
+		   exp-pos (match-end 0)))
+	    ((and (eq ch ?\")
+		  (string-match "\\(\"\\([^\"\\]\\|\\\\.\\)*\\)\\(\"\\|\\'\\)" exp-str exp-pos))
+	     (if (eq calc-language 'eqn)
+		 (progn
+		   (setq exp-str (copy-sequence exp-str))
+		   (aset exp-str (match-beginning 1) ?\{)
+		   (if (< (match-end 1) (length exp-str))
+		       (aset exp-str (match-end 1) ?\}))
+		   (math-read-token))
+	       (setq exp-token 'string
+		     exp-data (math-match-substring exp-str 1)
+		     exp-pos (match-end 0))))
+	    ((and (= ch ?\\) (eq calc-language 'tex)
+		  (< exp-pos (1- (length exp-str))))
+	     (or (string-match "\\\\hbox *{\\([a-zA-Z0-9]+\\)}" exp-str exp-pos)
+		 (string-match "\\(\\\\\\([a-zA-Z]+\\|[^a-zA-Z]\\)\\)" exp-str exp-pos))
+	     (setq exp-token 'symbol
+		   exp-pos (match-end 0)
+		   exp-data (math-restore-dashes
+			     (math-match-substring exp-str 1)))
+	     (let ((code (assoc exp-data math-tex-ignore-words)))
+	       (cond ((null code))
+		     ((null (cdr code))
+		      (math-read-token))
+		     ((eq (nth 1 code) 'punc)
+		      (setq exp-token 'punc
+			    exp-data (nth 2 code)))
+		     ((and (eq (nth 1 code) 'mat)
+			   (string-match " *{" exp-str exp-pos))
+		      (setq exp-pos (match-end 0)
+			    exp-token 'punc
+			    exp-data "[")
+		      (let ((right (string-match "}" exp-str exp-pos)))
+			(and right
+			     (setq exp-str (copy-sequence exp-str))
+			     (aset exp-str right ?\])))))))
+	    ((and (= ch ?\.) (eq calc-language 'fortran)
+		  (eq (string-match "\\.[a-zA-Z][a-zA-Z][a-zA-Z]?\\."
+				    exp-str exp-pos) exp-pos))
+	     (setq exp-token 'punc
+		   exp-data (upcase (math-match-substring exp-str 0))
+		   exp-pos (match-end 0)))
+	    ((and (eq calc-language 'math)
+		  (eq (string-match "\\[\\[\\|->\\|:>" exp-str exp-pos)
+		      exp-pos))
+	     (setq exp-token 'punc
+		   exp-data (math-match-substring exp-str 0)
+		   exp-pos (match-end 0)))
+	    ((and (eq calc-language 'eqn)
+		  (eq (string-match "->\\|<-\\|+-\\|\\\\dots\\|~\\|\\^"
+				    exp-str exp-pos)
+		      exp-pos))
+	     (setq exp-token 'punc
+		   exp-data (math-match-substring exp-str 0)
+		   exp-pos (match-end 0))
+	     (and (eq (string-match "\\\\dots\\." exp-str exp-pos) exp-pos)
+		  (setq exp-pos (match-end 0)))
+	     (if (memq (aref exp-data 0) '(?~ ?^))
+		 (math-read-token)))
+	    ((eq (string-match "%%.*$" exp-str exp-pos) exp-pos)
+	     (setq exp-pos (match-end 0))
+	     (math-read-token))
+	    (t
+	     (if (and (eq ch ?\{) (memq calc-language '(tex eqn)))
+		 (setq ch ?\())
+	     (if (and (eq ch ?\}) (memq calc-language '(tex eqn)))
+		 (setq ch ?\)))
+	     (if (and (eq ch ?\&) (eq calc-language 'tex))
+		 (setq ch ?\,))
+	     (setq exp-token 'punc
+		   exp-data (char-to-string ch)
+		   exp-pos (1+ exp-pos))))))
+)
+
+
+(defun math-read-expr-level (exp-prec &optional exp-term)
+  (let* ((x (math-read-factor)) (first t) op op2)
+    (while (and (or (and calc-user-parse-table
+			 (setq op (calc-check-user-syntax x exp-prec))
+			 (setq x op
+			       op '("2x" ident 999999 -1)))
+		    (and (setq op (assoc exp-data math-expr-opers))
+			 (/= (nth 2 op) -1)
+			 (or (and (setq op2 (assoc
+					     exp-data
+					     (cdr (memq op math-expr-opers))))
+				  (eq (= (nth 3 op) -1)
+				      (/= (nth 3 op2) -1))
+				  (eq (= (nth 3 op2) -1)
+				      (not (math-factor-after)))
+				  (setq op op2))
+			     t))
+		    (and (or (eq (nth 2 op) -1)
+			     (memq exp-token '(symbol number dollar hash))
+			     (equal exp-data "(")
+			     (and (equal exp-data "[")
+				  (not (eq calc-language 'math))
+				  (not (and exp-keep-spaces
+					    (eq (car-safe x) 'vec)))))
+			 (or (not (setq op (assoc exp-data math-expr-opers)))
+			     (/= (nth 2 op) -1))
+			 (or (not calc-user-parse-table)
+			     (not (eq exp-token 'symbol))
+			     (let ((p calc-user-parse-table))
+			       (while (and p
+					   (or (not (integerp
+						     (car (car (car p)))))
+					       (not (equal
+						     (nth 1 (car (car p)))
+						     exp-data))))
+				 (setq p (cdr p)))
+			       (not p)))
+			 (setq op (assoc "2x" math-expr-opers))))
+		(not (and exp-term (equal exp-data exp-term)))
+		(>= (nth 2 op) exp-prec))
+      (if (not (equal (car op) "2x"))
+	  (math-read-token))
+      (and (memq (nth 1 op) '(sdev mod))
+	   (calc-extensions))
+      (setq x (cond ((consp (nth 1 op))
+		     (funcall (car (nth 1 op)) x op))
+		    ((eq (nth 3 op) -1)
+		     (if (eq (nth 1 op) 'ident)
+			 x
+		       (if (eq (nth 1 op) 'closing)
+			   (if (eq (nth 2 op) exp-prec)
+			       (progn
+				 (setq exp-prec 1000)
+				 x)
+			     (throw 'syntax "Mismatched delimiters"))
+			 (list (nth 1 op) x))))
+		    ((and (not first)
+			  (memq (nth 1 op) math-alg-inequalities)
+			  (memq (car-safe x) math-alg-inequalities))
+		     (calc-extensions)
+		     (math-composite-inequalities x op))
+		    (t (list (nth 1 op)
+			     x
+			     (math-read-expr-level (nth 3 op) exp-term))))
+	    first nil))
+    x)
+)
+
+(defun calc-check-user-syntax (&optional x prec)
+  (let ((p calc-user-parse-table)
+	(matches nil)
+	match rule)
+    (while (and p
+		(or (not (progn
+			   (setq rule (car (car p)))
+			   (if x
+			       (and (integerp (car rule))
+				    (>= (car rule) prec)
+				    (equal exp-data
+					   (car (setq rule (cdr rule)))))
+			     (equal exp-data (car rule)))))
+		    (let ((save-exp-pos exp-pos)
+			  (save-exp-old-pos exp-old-pos)
+			  (save-exp-token exp-token)
+			  (save-exp-data exp-data))
+		      (or (not (listp
+				(setq matches (calc-match-user-syntax rule))))
+			  (let ((args (progn
+					(calc-extensions)
+					calc-arg-values))
+				(conds nil)
+				temp)
+			    (if x
+				(setq matches (cons x matches)))
+			    (setq match (cdr (car p)))
+			    (while (and (eq (car-safe match)
+					    'calcFunc-condition)
+					(= (length match) 3))
+			      (setq conds (append (math-flatten-lands
+						   (nth 2 match))
+						  conds)
+				    match (nth 1 match)))
+			    (while (and conds match)
+			      (calc-extensions)
+			      (cond ((eq (car-safe (car conds))
+					 'calcFunc-let)
+				     (setq temp (car conds))
+				     (or (= (length temp) 3)
+					 (and (= (length temp) 2)
+					      (eq (car-safe (nth 1 temp))
+						  'calcFunc-assign)
+					      (= (length (nth 1 temp)) 3)
+					      (setq temp (nth 1 temp)))
+					 (setq match nil))
+				     (setq matches (cons
+						    (math-normalize
+						     (math-multi-subst
+						      (nth 2 temp)
+						      args matches))
+						    matches)
+					   args (cons (nth 1 temp)
+						      args)))
+				    ((and (eq (car-safe (car conds))
+					      'calcFunc-matches)
+					  (= (length (car conds)) 3))
+				     (setq temp (calcFunc-vmatches
+						 (math-multi-subst
+						  (nth 1 (car conds))
+						  args matches)
+						 (nth 2 (car conds))))
+				     (if (eq temp 0)
+					 (setq match nil)
+				       (while (setq temp (cdr temp))
+					 (setq matches (cons (nth 2 (car temp))
+							     matches)
+					       args (cons (nth 1 (car temp))
+							  args)))))
+				    (t
+				     (or (math-is-true (math-simplify
+							(math-multi-subst
+							 (car conds)
+							 args matches)))
+					 (setq match nil))))
+			      (setq conds (cdr conds)))
+			    (if match
+				(not (setq match (math-multi-subst
+						  match args matches)))
+			      (setq exp-old-pos save-exp-old-pos
+				    exp-token save-exp-token
+				    exp-data save-exp-data
+				    exp-pos save-exp-pos)))))))
+      (setq p (cdr p)))
+    (and p match))
+)
+
+(defun calc-match-user-syntax (p &optional term)
+  (let ((matches nil)
+	(save-exp-pos exp-pos)
+	(save-exp-old-pos exp-old-pos)
+	(save-exp-token exp-token)
+	(save-exp-data exp-data))
+    (while (and p
+		(cond ((stringp (car p))
+		       (and (equal exp-data (car p))
+			    (progn
+			      (math-read-token)
+			      t)))
+		      ((integerp (car p))
+		       (and (setq m (catch 'syntax
+				      (math-read-expr-level
+				       (car p)
+				       (if (cdr p)
+					   (if (consp (nth 1 p))
+					       (car (nth 1 (nth 1 p)))
+					     (nth 1 p))
+					 term))))
+			    (not (stringp m))
+			    (setq matches (nconc matches (list m)))))
+		      ((eq (car (car p)) '\?)
+		       (setq m (calc-match-user-syntax (nth 1 (car p))))
+		       (or (nth 2 (car p))
+			   (setq matches
+				 (nconc matches
+					(list
+					 (cons 'vec (and (listp m) m))))))
+		       (or (listp m) (not (nth 2 (car p)))
+			   (not (eq (aref (car (nth 2 (car p))) 0) ?\$))
+			   (eq exp-token 'end)))
+		      (t
+		       (setq m (calc-match-user-syntax (nth 1 (car p))
+						       (car (nth 2 (car p)))))
+		       (if (listp m)
+			   (let ((vec (cons 'vec m))
+				 opos mm)
+			     (while (and (listp
+					  (setq opos exp-pos
+						mm (calc-match-user-syntax
+						    (or (nth 2 (car p))
+							(nth 1 (car p)))
+						    (car (nth 2 (car p))))))
+					 (> exp-pos opos))
+			       (setq vec (nconc vec mm)))
+			     (setq matches (nconc matches (list vec))))
+			 (and (eq (car (car p)) '*)
+			      (setq matches (nconc matches (list '(vec)))))))))
+      (setq p (cdr p)))
+    (if p
+	(setq exp-pos save-exp-pos
+	      exp-old-pos save-exp-old-pos
+	      exp-token save-exp-token
+	      exp-data save-exp-data
+	      matches "Failed"))
+    matches)
+)
+
+(defconst math-alg-inequalities
+  '(calcFunc-lt calcFunc-gt calcFunc-leq calcFunc-geq
+		calcFunc-eq calcFunc-neq))
+
+(defun math-remove-dashes (x)
+  (if (string-match "\\`\\(.*\\)-\\(.*\\)\\'" x)
+      (math-remove-dashes
+       (concat (math-match-substring x 1) "#" (math-match-substring x 2)))
+    x)
+)
+
+(defun math-restore-dashes (x)
+  (if (string-match "\\`\\(.*\\)[#_]\\(.*\\)\\'" x)
+      (math-restore-dashes
+       (concat (math-match-substring x 1) "-" (math-match-substring x 2)))
+    x)
+)
+
+(defun math-read-if (cond op)
+  (let ((then (math-read-expr-level 0)))
+    (or (equal exp-data ":")
+	(throw 'syntax "Expected ':'"))
+    (math-read-token)
+    (list 'calcFunc-if cond then (math-read-expr-level (nth 3 op))))
+)
+
+(defun math-factor-after ()
+  (let ((exp-pos exp-pos)
+	exp-old-pos exp-token exp-data)
+    (math-read-token)
+    (or (memq exp-token '(number symbol dollar hash string))
+	(and (assoc exp-data '(("-") ("+") ("!") ("|") ("/")))
+	     (assoc (concat "u" exp-data) math-expr-opers))
+	(eq (nth 2 (assoc exp-data math-expr-opers)) -1)
+	(assoc exp-data '(("(") ("[") ("{")))))
+)
+
+(defun math-read-factor ()
+  (let (op)
+    (cond ((eq exp-token 'number)
+	   (let ((num (math-read-number exp-data)))
+	     (if (not num)
+		 (progn
+		   (setq exp-old-pos exp-pos)
+		   (throw 'syntax "Bad format")))
+	     (math-read-token)
+	     (if (and math-read-expr-quotes
+		      (consp num))
+		 (list 'quote num)
+	       num)))
+	  ((and calc-user-parse-table
+		(setq op (calc-check-user-syntax)))
+	   op)
+	  ((or (equal exp-data "-")
+	       (equal exp-data "+")
+	       (equal exp-data "!")
+	       (equal exp-data "|")
+	       (equal exp-data "/"))
+	   (setq exp-data (concat "u" exp-data))
+	   (math-read-factor))
+	  ((and (setq op (assoc exp-data math-expr-opers))
+		(eq (nth 2 op) -1))
+	   (if (consp (nth 1 op))
+	       (funcall (car (nth 1 op)) op)
+	     (math-read-token)
+	     (let ((val (math-read-expr-level (nth 3 op))))
+	       (cond ((eq (nth 1 op) 'ident)
+		      val)
+		     ((and (Math-numberp val)
+			   (equal (car op) "u-"))
+		      (math-neg val))
+		     (t (list (nth 1 op) val))))))
+	  ((eq exp-token 'symbol)
+	   (let ((sym (intern exp-data)))
+	     (math-read-token)
+	     (if (equal exp-data calc-function-open)
+		 (let ((f (assq sym math-expr-function-mapping)))
+		   (math-read-token)
+		   (if (consp (cdr f))
+		       (funcall (car (cdr f)) f sym)
+		     (let ((args (if (or (equal exp-data calc-function-close)
+					 (eq exp-token 'end))
+				     nil
+				   (math-read-expr-list))))
+		       (if (not (or (equal exp-data calc-function-close)
+				    (eq exp-token 'end)))
+			   (throw 'syntax "Expected `)'"))
+		       (math-read-token)
+		       (if (and (eq calc-language 'fortran) args
+				(calc-extensions)
+				(let ((calc-matrix-mode 'scalar))
+				  (math-known-matrixp
+				   (list 'var sym
+					 (intern
+					  (concat "var-"
+						  (symbol-name sym)))))))
+			   (math-parse-fortran-subscr sym args)
+			 (if f
+			     (setq sym (cdr f))
+			   (and (= (aref (symbol-name sym) 0) ?\\)
+				(< (prefix-numeric-value calc-language-option)
+				   0)
+				(setq sym (intern (substring (symbol-name sym)
+							     1))))
+			   (or (string-match "-" (symbol-name sym))
+			       (setq sym (intern
+					  (concat "calcFunc-"
+						  (symbol-name sym))))))
+			 (cons sym args)))))
+	       (if math-read-expr-quotes
+		   sym
+		 (let ((val (list 'var
+				  (intern (math-remove-dashes
+					   (symbol-name sym)))
+				  (if (string-match "-" (symbol-name sym))
+				      sym
+				    (intern (concat "var-"
+						    (symbol-name sym)))))))
+		   (let ((v (assq (nth 1 val) math-expr-variable-mapping)))
+		     (and v (setq val (if (consp (cdr v))
+					  (funcall (car (cdr v)) v val)
+					(list 'var
+					      (intern
+					       (substring (symbol-name (cdr v))
+							  4))
+					      (cdr v))))))
+		   (while (and (memq calc-language '(c pascal maple))
+			       (equal exp-data "["))
+		     (math-read-token)
+		     (setq val (append (list 'calcFunc-subscr val)
+				       (math-read-expr-list)))
+		     (if (equal exp-data "]")
+			 (math-read-token)
+		       (throw 'syntax "Expected ']'")))
+		   val)))))
+	  ((eq exp-token 'dollar)
+	   (let ((abs (if (> exp-data 0) exp-data (- exp-data))))
+	     (if (>= (length calc-dollar-values) abs)
+		 (let ((num exp-data))
+		   (math-read-token)
+		   (setq calc-dollar-used (max calc-dollar-used num))
+		   (math-check-complete (nth (1- abs) calc-dollar-values)))
+	       (throw 'syntax (if calc-dollar-values
+				  "Too many $'s"
+				"$'s not allowed in this context")))))
+	  ((eq exp-token 'hash)
+	   (or calc-hashes-used
+	       (throw 'syntax "#'s not allowed in this context"))
+	   (calc-extensions)
+	   (if (<= exp-data (length calc-arg-values))
+	       (let ((num exp-data))
+		 (math-read-token)
+		 (setq calc-hashes-used (max calc-hashes-used num))
+		 (nth (1- num) calc-arg-values))
+	     (throw 'syntax "Too many # arguments")))
+	  ((equal exp-data "(")
+	   (let* ((exp (let ((exp-keep-spaces nil))
+			 (math-read-token)
+			 (if (or (equal exp-data "\\dots")
+				 (equal exp-data "\\ldots"))
+			     '(neg (var inf var-inf))
+			   (math-read-expr-level 0)))))
+	     (let ((exp-keep-spaces nil))
+	       (cond
+		((equal exp-data ",")
+		 (progn
+		   (math-read-token)
+		   (let ((exp2 (math-read-expr-level 0)))
+		     (setq exp
+			   (if (and exp2 (Math-realp exp) (Math-realp exp2))
+			       (math-normalize (list 'cplx exp exp2))
+			     (list '+ exp (list '* exp2 '(var i var-i))))))))
+		((equal exp-data ";")
+		 (progn
+		   (math-read-token)
+		   (let ((exp2 (math-read-expr-level 0)))
+		     (setq exp (if (and exp2 (Math-realp exp)
+					(Math-anglep exp2))
+				   (math-normalize (list 'polar exp exp2))
+				 (calc-extensions)
+				 (list '* exp
+				       (list 'calcFunc-exp
+					     (list '*
+						   (math-to-radians-2 exp2)
+						   '(var i var-i)))))))))
+		((or (equal exp-data "\\dots")
+		     (equal exp-data "\\ldots"))
+		 (progn
+		   (math-read-token)
+		   (let ((exp2 (if (or (equal exp-data ")")
+				       (equal exp-data "]")
+				       (eq exp-token 'end))
+				   '(var inf var-inf)
+				 (math-read-expr-level 0))))
+		     (setq exp
+			   (list 'intv
+				 (if (equal exp-data ")") 0 1)
+				 exp
+				 exp2)))))))
+	     (if (not (or (equal exp-data ")")
+			  (and (equal exp-data "]") (eq (car-safe exp) 'intv))
+			  (eq exp-token 'end)))
+		 (throw 'syntax "Expected `)'"))
+	     (math-read-token)
+	     exp))
+	  ((eq exp-token 'string)
+	   (calc-extensions)
+	   (math-read-string))
+	  ((equal exp-data "[")
+	   (calc-extensions)
+	   (math-read-brackets t "]"))
+	  ((equal exp-data "{")
+	   (calc-extensions)
+	   (math-read-brackets nil "}"))
+	  ((equal exp-data "<")
+	   (calc-extensions)
+	   (math-read-angle-brackets))
+	  (t (throw 'syntax "Expected a number"))))
+)
+
+
+