(in-package :maxima)

;; reading this in and running  use_segment(true) does this..

;;   f(a,b,segment(c,d),e)  --> f(a,b,c,d,e)
;;   w:segment(a,b)
;;   f(a,b,w,e) --> f(a,b,a,b,e)

;; save the old function definition, if it has not already been
;; saved by previously loading this file.
;; this slows down Maxima by some amount.
;; author: (c)  Richard Fateman 7/24/2014.  You can use it for any purpose. No warranty.

(eval-when (load)(if (not(fboundp 'mevalargs)) (error "Can only load segment-new AFTER definition of mevalargs in mlisp.lisp")))


(if (fboundp 'orig-mevalargs) nil 
  (setf (symbol-function 'orig-mevalargs)
    (symbol-function 'mevalargs)))

(defun mevalargs-segment (args)
  (cond (noevalargs (setq noevalargs nil) args)
	(t (setf args(mapcar #'meval args))
	   (cond ((every #'nonsegmentp args)
		      args)
		 (t (splice-segment-args args))))))
	   
(defun nonsegmentp(r)(or (atom r)
			 (not (listp (car r)))
			 (not (eq (caar r) '$segment))))

(defun splice-segment-args(h)
  (let ((res nil))
    (map nil #'(lambda(r) 
		 (if (nonsegmentp r)
		     (push (list r) res)
		   (push (reverse (cdr r)) res))) ;reverse makes fresh copy
	 h)
    (nreverse (apply #'nconc res)) ))

(defun $use_segment(flag)  ;;flip segments on or off.
 ;; that is, command:   use_segment(true) turns it on  ;; use_segment(false) turns it off
  (cond (flag (setf (symbol-function 'mevalargs) #'mevalargs-segment)
	      "Segment is enabled")
	(t (setf (symbol-function 'mevalargs)  #'orig-mevalargs)
	   "Segment treatment is disabled")))

;; if you read this file, then turn on segments as default
(setf (symbol-function 'mevalargs) #'mevalargs-segment)