;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; The data in this file contains enhancments. ;;;;; ;;; ;;;;; ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;; ;;; All rights reserved ;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (in-package "MAXIMA") (eval-when (compile load eval) (defmacro if (test &rest args) (cond ((> (length args) 2) ;(format t ;"~%Warning: Too many args for if:~% ~a" ;(cons 'if (cons test args))) `(lisp::if ,test ,(car args) (progn ,@ (cdr args)))) (t `(lisp:if ,test ,@ args)))) ;;this will make operators which ;;declare the type and result of numerical operations (defmacro def-op (name type op &optional return-type) `(setf (macro-function ',name) (make-operation ',type ',op ',return-type))) ;;make very sure .type .op and .return are not special!! (defun make-operation (.type .op .return) (or .return (setf .return .type)) #'(lambda (bod env) env (sloop for v in (cdr bod) when (eq t .type) collect v into body else collect `(the , .type ,v) into body finally (setq body `(, .op ,@ body)) (return (if (eq t .return) body `(the , .return ,body)))))) #+fix-debug (progn ;; these allow running of code and they print out where the error ;occurred (defvar *dbreak* t) (defun chk-type (lis na typ sho) (or (sloop for v in lis always (typep v typ)) (format t "~%Bad call ~a types:~a" (cons na sho) (sloop for v in lis collect (type-of v))) (and *dbreak* (break "hi")))) (defmacro def-op (name type old) `(defmacro ,name (&rest l) `(progn (chk-type (list ,@ l) ',',name ',',type ',l ) (,',old ,@ l)))) ) ;;note 1+ and 1- in the main macsyma code were for fixnum 1+, ;;so we should replace them by f1+ and f1- and then add the appropriate ;;definitions here. (def-op f+ fixnum +) (def-op f* fixnum *) (def-op f- fixnum -) (def-op +$ double-float +) (def-op *$ double-float *) (def-op -$ double-float -) (def-op 1-$ double-float 1-) (def-op 1+$ double-float 1+) (def-op f1- fixnum 1-) (def-op f1+ fixnum 1+) (def-op sub1 t 1-) (def-op add1 t 1+) (def-op plus t +) (def-op times t *) (def-op difference t -) (def-op quotient t quot) (def-op // t quot) ;(def-op // fixnum quot) ?? (def-op //$ double-float quot) (def-op ^ fixnum expt) (def-op ^$ double-float expt) (def-op greaterp t > ) (def-op f> fixnum > t) (def-op f< fixnum < t) (def-op f= fixnum = t) (def-op lessp t < t) (def-op remainder t rem) (def-op lsh fixnum ash) (def-op fixnum-remainder fixnum rem) (def-op minus t -) ;(def-op \\ fixnum rem) ;no calls any more ;exp is shadowed to save trouble for other packages--its declared special (setf (symbol-function 'exp) (symbol-function 'lisp::exp)) ) ;;end eval-when (symbolics needed this). ;;this is essentially what the quotient is supposed to do. (defun quot (a &rest b) (cond ((null b) (quot 1 a)) ((null (cdr b)) (setq b (car b)) (cond ((and (integerp a) (integerp b)) (values (truncate a b))) (t ( / a b)))) (t (apply 'quot (quot a (car b)) (cdr b))))) (defmacro status (option &optional item) (let ((it (intern (string item) (find-package 'keyword)))) (cond ((equal (symbol-name option) "FEATURE") `(member ,it *features*)) ((equal option 'GCTIME) 0)))) (defmacro sstatus (option item ) (let ((it (intern (string item) (find-package 'keyword)))) (cond ((equal (symbol-name option) "FEATURE") `(pushnew ,it *features*)) (t (error "unknown sstatus ~a" option))))) (defun setplist (sym val) (setf (symbol-plist sym) val)) (defun sortcar (lis &optional (test 'alphalessp)) (sort lis test :key 'car)) ;numbers count 0) while (cdr v) when (equal (cadr v) x) do (setf count (f1- count))(setf (cdr v) (cddr v)) else do (setq v (cdr v)) ) lis) (defun zl-member (x lis) (declare (object x lis)) (sloop for v on lis when (equal (car v) x) do (return v))) (defun zl-remove (item list &optional (n most-positive-fixnum)) #+lucid (setq n 16777214) ;;yukkk. #+cmu (setq n (min n (1- most-positive-fixnum))) ; yukkk (remove item list :count n :test 'equal)) (defvar *acursor* nil) (defun set-up-cursor (ar) (or *acursor* (setf *acursor* (make-array 10 :element-type 'fixnum :initial-element 0))) (let ((lis (array-dimensions ar))) (setf (aref *acursor* 0) (length lis)) (sloop for v in lis for i from 6 do (setf (aref *acursor* i) (f- v 1))) (sloop for i from 1 to (length lis) do (setf (aref *acursor* i) 0)))) (defun aset-by-cursor (ar val) (let ((curs *acursor*)) (declare (type (lisp::array fixnum) curs)) (ecase (aref curs 0) (1 (setf (aref ar (aref curs 1)) val)) (2 (setf (aref ar (aref curs 1) (aref curs 2)) val)) (3 (setf (aref ar (aref curs 1) (aref curs 2) (aref curs 3)) val))) (sloop for j downfrom (aref curs 0) do (cond ((< (aref curs j) (aref curs (f+ 5 j))) (setf (aref curs j) (f+ (aref curs j) 1)) (return-from aset-by-cursor t)) (t (setf (aref curs j) 0))) (cond ((eql j 0) (return-from aset-by-cursor nil)))))) (defun fillarray (ar x) (when (symbolp ar) (setq ar (get ar 'ARRAY))) #+cl (when (/= (array-rank ar) 1) (setq ar (make-array (array-total-size ar) :displaced-to ar))) (setq x (cond ((null x) (ecase (array-element-type ar) (fixnum '(0)) (float '(0.0)) ((t) '(nil)))) ((arrayp x)(listarray x)) ((atom x) (list x)) (t x))) (when (> (length ar) 0) (set-up-cursor ar) (sloop while (aset-by-cursor ar (car x)) do (and (cdr x) (setq x (cdr x)))))) ;(defun fillarray (ar x) ; (when (symbolp ar) ; (setq ar (get ar 'ARRAY))) ; (let ((leng (length (the (lisp:array t ) ar)))) ; (declare (fixnum leng)) ; (cond ((null x) ; (setq x (ecase (array-element-type ar) ; (fixnum 0) ; (float 0.0) ; ((t) nil))) ; (sloop for i below leng ; do (setf (aref ar i) x))) ; ((consp x) ; (sloop for i below leng ; for u in x ; do (setf (aref ar i) u) ; finally ; (sloop for j from i below leng ; do (setf (aref ar j) u)))) ; ((arrayp x) ; (sloop for i below (min leng (length x)) ; do (setf (aref ar i) (aref x i)) ; finally (sloop for j from i below leng ; with u = (aref x (f- i 1)) ; do (setf (aref ar j ) u)))) ; (t (error "bad second arg to fillarray"))))) (defun listarray (x) (when (symbolp x) (setq x (get x 'ARRAY))) (cond ((eql (array-rank x) 1) (coerce x 'list)) (t (coerce (make-array (apply '* (array-dimensions x)) :displaced-to x :element-type (array-element-type x)) 'list)))) (defmacro check-arg (place pred &rest res) (cond ((atom pred ) (setq pred (list pred place)))) `(assert ,pred (,place) ,@ res)) (defmacro deff (fun val) `(setf (symbol-function ',fun) ,val)) (defmacro xcons (x y) (cond ((atom x) `(cons ,y,x)) (t (let ((g (gensym))) `(let ((,g ,x)) (cons ,y ,g)))))) (defun nleft (n x &optional tail) (sloop for v on (nthcdr n x) for w on x when (eq v tail) do (return w) finally (return w))) (defun make-equal-hash-table (not-dim1) (let ((table (make-hash-table :test 'equal))) (or not-dim1 (setf (gethash 'dim1 table) t)) table)) ;;to do check this!! ;;the following statement does ot seem to be true. ;;thus range cl::atan = 0,2pi on explorer. ;; (zl:atan y x) == (cl:atan y x) + 2 pi if latter is negative ;;range of atan should be [0,2*pi] (defun atan (y x) (let ((tem (lisp::atan y x))) (cond((>= tem 0) tem) (t (+ tem (* 2 pi)))))) ;;range of atan2 should be (-pi,pi] ;;CL manual says that's what lisp::atan is supposed to have. ;;need xcons,nleft, simple-vector-length,make-equal-hash-table (setf (symbol-function 'atan2) (symbol-function 'lisp::atan)) (setq *READ-DEFAULT-FLOAT-FORMAT* 'double-float) (defmacro float (x &optional (y 1.0d0)) `(lisp::float ,x ,y)) ;; Use the same type as the default value of float.. (defconstant *small-flonum* (float least-positive-short-float 1.0d0))