X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fnumbers.lisp;h=18d679c3d7b61bc81cbb5038a108cc287911b623;hb=b2de12c4e1a6e77e7f3f22d056adcfeda79d085b;hp=8121b8e6d26bd12a088d8e25e73bfb5092a085e1;hpb=598ae9642e4fc7d24a4e55deced53694ec83b04a;p=jscl.git diff --git a/src/numbers.lisp b/src/numbers.lisp index 8121b8e..18d679c 100644 --- a/src/numbers.lisp +++ b/src/numbers.lisp @@ -15,24 +15,36 @@ ;;;; Various numeric functions and constants -;; Basic functions -(defun = (x y) (= x y)) -(defun * (x y) (* x y)) -(defun / (x y) (/ x y)) -(defun 1+ (x) (+ x 1)) -(defun 1- (x) (- x 1)) +;; TODO: Use MACROLET when it exists +(defmacro define-variadic-op (operator initial-value) + (let ((init-sym (gensym)) + (dolist-sym (gensym))) + `(defun ,operator (&rest args) + (let ((,init-sym ,initial-value)) + (dolist (,dolist-sym args) + (setq ,init-sym (,operator ,init-sym ,dolist-sym))) + ,init-sym)))) + +(define-variadic-op + 0) +(define-variadic-op * 1) + +;; - and / work differently from the above macro. +;; If only one arg is given, it negates it or takes its reciprocal. +;; Otherwise all the other args are subtracted from or divided by it. +;; TODO: Use MACROLET when it exists +(defmacro define-sub-or-div (operator unary-form) + `(defun ,operator (x &rest args) + (cond + ((null args) ,unary-form) + (t (dolist (y args) + (setq x (,operator x y))) + x)))) -(defun + (&rest args) - (let ((r 0)) - (dolist (x args r) - (incf r x)))) +(define-sub-or-div - (- x)) +(define-sub-or-div / (/ 1 x)) -(defun - (x &rest others) - (if (null others) - (- x) - (let ((r x)) - (dolist (y others r) - (decf r y))))) +(defun 1+ (x) (+ x 1)) +(defun 1- (x) (- x 1)) (defun truncate (x &optional (y 1)) (floor (/ x y))) @@ -58,8 +70,10 @@ (defcomparison >) (defcomparison >=) +(defcomparison =) (defcomparison <) (defcomparison <=) +(defcomparison /=) (defconstant pi 3.141592653589793)