[oct-cvs] Oct commit: oct qd-methods.lisp
rtoy
rtoy at common-lisp.net
Thu Jul 31 19:13:42 UTC 2008
Update of /project/oct/cvsroot/oct
In directory clnet:/tmp/cvs-serv30205
Modified Files:
qd-methods.lisp
Log Message:
For CMUCL, define compiler macros to convert two-arg-foo into the
appropriate CL function or QD-REAL function so we don't have to do
CLOS dispatch, if the types are known at compile-time.
--- /project/oct/cvsroot/oct/qd-methods.lisp 2008/07/18 17:02:04 1.66
+++ /project/oct/cvsroot/oct/qd-methods.lisp 2008/07/31 19:13:42 1.67
@@ -990,6 +990,76 @@
(if (cdr more-numbers)
form
`(not (two-arg-= ,number ,(car more-numbers)))))
+
+
+;; Define compiler macro the convert two-arg-foo into the appropriate
+;; CL function or QD-REAL function so we don't have to do CLOS
+;; dispatch.
+#+cmu
+(macrolet
+ ((frob (name cl-op qd-op)
+ `(define-compiler-macro ,name (&whole form x y &environment env)
+ (flet ((arg-type (arg)
+ (multiple-value-bind (def-type localp decl)
+ (ext:variable-information arg env)
+ (declare (ignore localp))
+ (when def-type
+ (cdr (assoc 'type decl))))))
+ (let ((x-type (arg-type x))
+ (y-type (arg-type y)))
+ (cond ((and (subtypep x-type 'cl:number)
+ (subtypep y-type 'cl:number))
+ `(,',cl-op ,x ,y))
+ ((and (subtypep x-type 'qd-real)
+ (subtypep y-type 'qd-real))
+ `(make-instance 'qd-real :value (,',qd-op (qd-value ,x)
+ (qd-value ,y))))
+ (t
+ ;; Don't know how to handle this, so give up.
+ form)))))))
+ (frob two-arg-+ cl:+ add-qd)
+ (frob two-arg-- cl:- sub-qd)
+ (frob two-arg-* cl:* mul-qd)
+ (frob two-arg-/ cl:/ div-qd))
+
+#+cmu
+(macrolet
+ ((frob (name cl-op qd-op cl-qd-op qd-cl-op)
+ `(define-compiler-macro ,name (&whole form x y &environment env)
+ (flet ((arg-type (arg)
+ (multiple-value-bind (def-type localp decl)
+ (ext:variable-information arg env)
+ (declare (ignore localp))
+ (when def-type
+ (cdr (assoc 'type decl))))))
+ (let ((x-type (arg-type x))
+ (y-type (arg-type y)))
+ (cond ((subtypep x-type 'cl:float)
+ (cond ((subtypep y-type 'cl:number)
+ `(,',cl-op ,x ,y))
+ ((subtypep y-type 'qd-real)
+ (if ,cl-qd-op
+ `(make-instance 'qd-real :value (,',cl-qd-op (cl:float ,x 1d0)
+ (qd-value ,y)))
+ form))
+ (t form)))
+ ((subtypep x-type 'qd-real)
+ (cond ((subtypep y-type 'cl:float)
+ (if ,qd-cl-op
+ `(make-instance 'qd-real :value (,',qd-cl-op (qd-value ,x)
+ (float ,y 1d0)))
+ form))
+ ((subtypep y-type 'qd-real)
+ `(make-instance 'qd-real :value (,',qd-op (qd-value ,x)
+ (qd-value ,y))))
+ (t form)))
+ (t
+ ;; Don't know how to handle this, so give up.
+ form)))))))
+ (frob two-arg-+ cl:+ add-qd add-d-qd add-qd-d)
+ (frob two-arg-- cl:- sub-qd sub-d-qd sub-qd-d)
+ (frob two-arg-* cl:* mul-qd mul-d-qd mul-qd-d)
+ (frob two-arg-/ cl:/ div-qd nil nil))
(defun read-qd-real-or-complex (stream)
More information about the oct-cvs
mailing list