Function: math-read-big-rec

math-read-big-rec is an autoloaded and byte-compiled function defined in calc-lang.el.gz.

Signature

(math-read-big-rec RB-H1 RB-V1 RB-H2 RB-V2 &optional BASELINE PREC SHORT)

Source Code

;; Defined in /usr/src/emacs/lisp/calc/calc-lang.el.gz
(defun math-read-big-rec (rb-h1 rb-v1 rb-h2 rb-v2
                                     &optional baseline prec short)
  (or prec (setq prec 0))
  (let ((math-rb-h1 rb-h1)
        (math-rb-v1 rb-v1)
        (math-rb-h2 rb-h2)
        (math-rb-v2 rb-v2))
  ;; Clip whitespace above or below.
  (while (and (< math-rb-v1 math-rb-v2)
              (math-read-big-emptyp math-rb-h1 math-rb-v1 math-rb-h2 (1+ math-rb-v1)))
    (setq math-rb-v1 (1+ math-rb-v1)))
  (while (and (< math-rb-v1 math-rb-v2)
              (math-read-big-emptyp math-rb-h1 (1- math-rb-v2) math-rb-h2 math-rb-v2))
    (setq math-rb-v2 (1- math-rb-v2)))

  ;; If formula is a single line high, normal parser can handle it.
  (if (<= math-rb-v2 (1+ math-rb-v1))
      (if (or (<= math-rb-v2 math-rb-v1)
	      (> math-rb-h1 (length (setq math-rb-v2
                                          (nth math-rb-v1 math-read-big-lines)))))
	  (math-read-big-error math-rb-h1 math-rb-v1)
	(setq math-read-big-baseline math-rb-v1
	      math-read-big-h2 math-rb-h2
	      math-rb-v2 (nth math-rb-v1 math-read-big-lines)
	      math-rb-h2 (math-read-expr
                          (substring math-rb-v2 math-rb-h1
                                     (min math-rb-h2 (length math-rb-v2)))))
	(if (eq (car-safe math-rb-h2) 'error)
	    (math-read-big-error (+ math-rb-h1 (nth 1 math-rb-h2))
                                 math-rb-v1 (nth 2 math-rb-h2))
	  math-rb-h2))

    ;; Clip whitespace at left or right.
    (while (and (< math-rb-h1 math-rb-h2)
                (math-read-big-emptyp math-rb-h1 math-rb-v1 (1+ math-rb-h1) math-rb-v2))
      (setq math-rb-h1 (1+ math-rb-h1)))
    (while (and (< math-rb-h1 math-rb-h2)
                (math-read-big-emptyp (1- math-rb-h2) math-rb-v1 math-rb-h2 math-rb-v2))
      (setq math-rb-h2 (1- math-rb-h2)))

    ;; Scan to find widest left-justified "----" in the region.
    (let* ((widest nil)
	   (widest-h2 0)
	   (lines-v1 (nthcdr math-rb-v1 math-read-big-lines))
	   (p lines-v1)
	   (v math-rb-v1)
	   (other-v nil)
	   other-char line len h)
      (while (< v math-rb-v2)
	(setq line (car p)
	      len (min math-rb-h2 (length line)))
	(and (< math-rb-h1 len)
	     (/= (aref line math-rb-h1) ?\ )
	     (if (and (= (aref line math-rb-h1) ?\-)
		      ;; Make sure it's not a minus sign.
		      (or (and (< (1+ math-rb-h1) len)
                               (= (aref line (1+ math-rb-h1)) ?\-))
			  (/= (math-read-big-char math-rb-h1 (1- v)) ?\ )
			  (/= (math-read-big-char math-rb-h1 (1+ v)) ?\ )))
		 (progn
		   (setq h math-rb-h1)
		   (while (and (< (setq h (1+ h)) len)
			       (= (aref line h) ?\-)))
		   (if (> h widest-h2)
		       (setq widest v
			     widest-h2 h)))
	       (or other-v (setq other-v v other-char (aref line math-rb-h1)))))
	(setq v (1+ v)
	      p (cdr p)))

      (cond ((not (setq v other-v))
	     (math-read-big-error math-rb-h1 math-rb-v1))   ; Should never happen!

	    ;; Quotient.
	    (widest
	     (setq h widest-h2
		   v widest)
	     (let ((num (math-read-big-rec math-rb-h1 math-rb-v1 h v))
		   (den (math-read-big-rec math-rb-h1 (1+ v) h math-rb-v2)))
	       (setq p (if (and (math-integerp num) (math-integerp den))
			   (math-make-frac num den)
			 (list '/ num den)))))

	    ;; Big radical sign.
	    ((= other-char ?\\)
	     (or (= (math-read-big-char (1+ math-rb-h1) v) ?\|)
		 (math-read-big-error (1+ math-rb-h1) v "Malformed root sign"))
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 (1+ math-rb-h1) v nil t)
	     (while (= (math-read-big-char (1+ math-rb-h1) (setq v (1- v))) ?\|))
	     (or (= (math-read-big-char (setq h (+ math-rb-h1 2)) v) ?\_)
		 (math-read-big-error h v "Malformed root sign"))
	     (while (= (math-read-big-char (setq h (1+ h)) v) ?\_))
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 (1+ math-rb-h1) v nil t)
	     (math-read-big-emptyp math-rb-h1 (1+ other-v) h math-rb-v2 nil t)
	     (setq p (list 'calcFunc-sqrt (math-read-big-rec
					   (+ math-rb-h1 2) (1+ v)
					   h (1+ other-v) baseline))
		   v math-read-big-baseline))

	    ;; Small radical sign.
	    ((and (memq other-char '(?V ?√))
		  (= (math-read-big-char (1+ math-rb-h1) (1- v)) ?\_))
	     (setq h (1+ math-rb-h1))
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 h (1- v) nil t)
	     (math-read-big-emptyp math-rb-h1 (1+ v) h math-rb-v2 nil t)
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 (1+ math-rb-h1) v nil t)
	     (while (= (math-read-big-char (setq h (1+ h)) (1- v)) ?\_))
	     (setq p (list 'calcFunc-sqrt (math-read-big-rec
					   (1+ math-rb-h1) v h (1+ v) t))
		   v math-read-big-baseline))

	    ;; Binomial coefficient.
	    ((and (= other-char ?\()
		  (= (math-read-big-char (1+ math-rb-h1) v) ?\ )
		  (= (string-match "( *)" (nth v math-read-big-lines)
                                   math-rb-h1) math-rb-h1))
	     (setq h (match-end 0))
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 (1+ math-rb-h1) v nil t)
	     (math-read-big-emptyp math-rb-h1 (1+ v) (1+ math-rb-h1) math-rb-v2 nil t)
	     (math-read-big-emptyp (1- h) math-rb-v1 h v nil t)
	     (math-read-big-emptyp (1- h) (1+ v) h math-rb-v2 nil t)
	     (setq p (list 'calcFunc-choose
			   (math-read-big-rec (1+ math-rb-h1) math-rb-v1 (1- h) v)
			   (math-read-big-rec (1+ math-rb-h1) (1+ v)
					      (1- h) math-rb-v2))))

	    ;; Minus sign.
	    ((= other-char ?\-)
	     (setq p (list 'neg (math-read-big-rec (1+ math-rb-h1) math-rb-v1
                                                   math-rb-h2 math-rb-v2 v 250 t))
		   v math-read-big-baseline
		   h math-read-big-h2))

	    ;; Parentheses.
	    ((= other-char ?\()
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 (1+ math-rb-h1) v nil t)
	     (math-read-big-emptyp math-rb-h1 (1+ v) (1+ math-rb-h1) math-rb-v2 nil t)
	     (setq h (math-read-big-balance (1+ math-rb-h1) v "(" t))
	     (math-read-big-emptyp (1- h) math-rb-v1 h v nil t)
	     (math-read-big-emptyp (1- h) (1+ v) h math-rb-v2 nil t)
	     (let ((sep (math-read-big-char (1- h) v))
		   hmid)
	       (if (= sep ?\.)
		   (setq h (1+ h)))
	       (if (= sep ?\])
		   (math-read-big-error (1- h) v "Expected `)'"))
	       (if (= sep ?\))
		   (setq p (math-read-big-rec
                            (1+ math-rb-h1) math-rb-v1 (1- h) math-rb-v2 v))
		 (setq hmid (math-read-big-balance h v "(")
		       p (list p
                               (math-read-big-rec h math-rb-v1 (1- hmid) math-rb-v2 v))
		       h hmid)
		 (cond ((= sep ?\.)
			(setq p (cons 'intv (cons (if (= (math-read-big-char
							  (1- h) v)
							 ?\))
						      0 1)
						  p))))
		       ((= (math-read-big-char (1- h) v) ?\])
			(math-read-big-error (1- h) v "Expected `)'"))
		       ((= sep ?\,)
			(or (and (math-realp (car p)) (math-realp (nth 1 p)))
			    (math-read-big-error
			     math-rb-h1 v "Complex components must be real"))
			(setq p (cons 'cplx p)))
		       ((= sep ?\;)
			(or (and (math-realp (car p)) (math-anglep (nth 1 p)))
			    (math-read-big-error
			     math-rb-h1 v "Complex components must be real"))
			(setq p (cons 'polar p)))))))

	    ;; Matrix.
	    ((and (= other-char ?\[)
		  (or (= (math-read-big-char (setq h math-rb-h1) (1+ v)) ?\[)
		      (= (math-read-big-char (setq h (1+ h)) v) ?\[)
		      (and (= (math-read-big-char h v) ?\ )
			   (= (math-read-big-char (setq h (1+ h)) v) ?\[)))
		  (= (math-read-big-char h (1+ v)) ?\[))
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 h v nil t)
	     (let ((vtop v)
		   (hleft h)
		   (hright nil))
	       (setq p nil)
	       (while (progn
			(setq h (math-read-big-balance (1+ hleft) v "["))
			(if hright
			    (or (= h hright)
				(math-read-big-error hright v "Expected `]'"))
			  (setq hright h))
			(setq p (cons (math-read-big-rec
				       hleft v h (1+ v)) p))
			(and (memq (math-read-big-char h v) '(?\  ?\,))
			     (= (math-read-big-char hleft (1+ v)) ?\[)))
		 (setq v (1+ v)))
	       (or (= hleft math-rb-h1)
		   (progn
		     (if (= (math-read-big-char h v) ?\ )
			 (setq h (1+ h)))
		     (and (= (math-read-big-char h v) ?\])
			  (setq h (1+ h))))
		   (math-read-big-error (1- h) v "Expected `]'"))
	       (if (= (math-read-big-char h vtop) ?\,)
		   (setq h (1+ h)))
	       (math-read-big-emptyp math-rb-h1 (1+ v) (1- h) math-rb-v2 nil t)
	       (setq v (+ vtop (/ (- v vtop) 2))
		     p (cons 'vec (nreverse p)))))

	    ;; Square brackets.
	    ((= other-char ?\[)
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 (1+ math-rb-h1) v nil t)
	     (math-read-big-emptyp math-rb-h1 (1+ v) (1+ math-rb-h1) math-rb-v2 nil t)
	     (setq p nil
		   h (1+ math-rb-h1))
	     (while (progn
		      (setq widest (math-read-big-balance h v "[" t))
		      (math-read-big-emptyp (1- h) math-rb-v1 h v nil t)
		      (math-read-big-emptyp (1- h) (1+ v) h math-rb-v2 nil t)
		      (setq p (cons (math-read-big-rec
				     h math-rb-v1 (1- widest) math-rb-v2 v) p)
			    h widest)
		      (= (math-read-big-char (1- h) v) ?\,)))
	     (setq widest (math-read-big-char (1- h) v))
	     (if (or (memq widest '(?\; ?\)))
		     (and (eq widest ?\.) (cdr p)))
		 (math-read-big-error (1- h) v "Expected `]'"))
	     (if (= widest ?\.)
		 (setq h (1+ h)
		       widest (math-read-big-balance h v "[")
		       p (nconc p (list (math-read-big-rec
					 h math-rb-v1 (1- widest) math-rb-v2 v)))
		       h widest
		       p (cons 'intv (cons (if (= (math-read-big-char (1- h) v)
						  ?\])
					       3 2)
					   p)))
	       (setq p (cons 'vec (nreverse p)))))

	    ;; Date form.
	    ((= other-char ?\<)
	     (setq line (nth v math-read-big-lines))
	     (string-match ">" line math-rb-h1)
	     (setq h (match-end 0))
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 h v nil t)
	     (math-read-big-emptyp math-rb-h1 (1+ v) h math-rb-v2 nil t)
	     (setq p (math-read-big-rec math-rb-h1 v h (1+ v) v)))

	    ;; Variable name or function call.
	    ((or (and (>= other-char ?a) (<= other-char ?z))
		 (and (>= other-char ?A) (<= other-char ?Z))
		 (and (>= other-char ?α) (<= other-char ?ω))
		 (and (>= other-char ?Α) (<= other-char ?Ω)))
	     (setq line (nth v math-read-big-lines))
	     (string-match "\\([a-zA-Zα-ωΑ-Ω'_]+\\) *" line math-rb-h1)
	     (setq h (match-end 1)
		   widest (match-end 0)
		   p (math-match-substring line 1))
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 h v nil t)
	     (math-read-big-emptyp math-rb-h1 (1+ v) h math-rb-v2 nil t)
	     (if (= (math-read-big-char widest v) ?\()
		 (progn
		   (setq line (if (string-search "-" p)
				  (intern p)
				(intern (concat "calcFunc-" p)))
			 h (1+ widest)
			 p nil)
		   (math-read-big-emptyp widest math-rb-v1 h v nil t)
		   (math-read-big-emptyp widest (1+ v) h math-rb-v2 nil t)
		   (while (progn
			    (setq widest (math-read-big-balance h v "(" t))
			    (math-read-big-emptyp (1- h) math-rb-v1 h v nil t)
			    (math-read-big-emptyp (1- h) (1+ v) h math-rb-v2 nil t)
			    (setq p (cons (math-read-big-rec
					   h math-rb-v1 (1- widest) math-rb-v2 v) p)
				  h widest)
			    (= (math-read-big-char (1- h) v) ?\,)))
		   (or (= (math-read-big-char (1- h) v) ?\))
		       (math-read-big-error (1- h) v "Expected `)'"))
		   (setq p (cons line (nreverse p))))
	       (setq p (list 'var
			     (intern (math-remove-dashes p))
			     (if (string-search "-" p)
				 (intern p)
			       (intern (concat "var-" p)))))))

	    ;; Number.
	    (t
	     (setq line (nth v math-read-big-lines))
	     (or (= (string-match "_?\\([0-9]+.?0*@ *\\)?\\([0-9]+.?0*' *\\)?\\([0-9]+\\(#\\|\\^\\^\\)[0-9a-zA-Z:]+\\|[0-9]+:[0-9:]+\\|[0-9.]+\\([eE][-+_]?[0-9]+\\)?\"?\\)?" line math-rb-h1) math-rb-h1)
		 (math-read-big-error h v "Expected a number"))
	     (setq h (match-end 0)
		   p (math-read-number (math-match-substring line 0)))
	     (math-read-big-emptyp math-rb-h1 math-rb-v1 h v nil t)
	     (math-read-big-emptyp math-rb-h1 (1+ v) h math-rb-v2 nil t)))

      ;; Now left term is bounded by math-rb-h1, math-rb-v1, h, math-rb-v2;
      ;; baseline = v.
      (if baseline
	  (or (= v baseline)
	      (math-read-big-error math-rb-h1 v "Inconsistent baseline in formula"))
	(setq baseline v))

      ;; Look for superscripts or subscripts.
      (setq line (nth baseline math-read-big-lines)
	    len (min math-rb-h2 (length line))
	    widest h)
      (while (and (< widest len)
		  (= (aref line widest) ?\ ))
	(setq widest (1+ widest)))
      (and (>= widest len) (setq widest math-rb-h2))
      (if (math-read-big-emptyp h v widest math-rb-v2)
	  (if (math-read-big-emptyp h math-rb-v1 widest v)
	      (setq h widest)
	    (setq p (list '^ p (math-read-big-rec h math-rb-v1 widest v))
		  h widest))
	  (if (math-read-big-emptyp h math-rb-v1 widest v)
	      (setq p (list 'calcFunc-subscr p
			    (math-read-big-rec h v widest math-rb-v2))
		    h widest)))

      ;; Look for an operator name and grab additional terms.
      (while (and (< h len)
		  (if (setq widest (and (math-read-big-emptyp
					 h math-rb-v1 (1+ h) v)
					(math-read-big-emptyp
					 h (1+ v) (1+ h) math-rb-v2)
					(string-match "<=\\|>=\\|\\+/-\\|!=\\|&&\\|||\\|:=\\|=>\\|." line h)
					(assoc (math-match-substring line 0)
					       (math-standard-ops))))
		      (and (>= (nth 2 widest) prec)
			   (setq h (match-end 0)))
		    (and (not (eq (string-match ",\\|;\\|\\.\\.\\|)\\|\\]\\|:" line h)
				  h))
			 (setq widest '("2x" * 196 195)))))
	(cond ((eq (nth 3 widest) -1)
	       (setq p (list (nth 1 widest) p)))
	      ((equal (car widest) "?")
	       (let ((y (math-read-big-rec h math-rb-v1 math-rb-h2
                                           math-rb-v2 baseline nil t)))
		 (or (= (math-read-big-char math-read-big-h2 baseline) ?\:)
		     (math-read-big-error math-read-big-h2 baseline
                                          "Expected `:'"))
		 (setq p (list (nth 1 widest) p y
			       (math-read-big-rec
                                (1+ math-read-big-h2) math-rb-v1 math-rb-h2 math-rb-v2
                                baseline (nth 3 widest) t))
		       h math-read-big-h2)))
	      (t
	       (setq p (list (nth 1 widest) p
			     (math-read-big-rec h math-rb-v1 math-rb-h2 math-rb-v2
						baseline (nth 3 widest) t))
		     h math-read-big-h2))))

      ;; Return all relevant information to caller.
      (setq math-read-big-baseline baseline
	    math-read-big-h2 h)
      (or short (= math-read-big-h2 math-rb-h2)
	  (math-read-big-error h baseline))
      p))))