Skip to content

Commit

Permalink
check if unsigned numbers underflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Jobhdez committed Oct 18, 2023
1 parent d03d8cc commit e962184
Showing 1 changed file with 35 additions and 1 deletion.
36 changes: 35 additions & 1 deletion library/math/num.lisp
Expand Up @@ -161,6 +161,35 @@
;;; Num instances for integers
;;;

(cl:eval-when (:compile-toplevel :load-toplevel)
(cl:defmacro define-unsigned-num-underflow (type bits)
"Define a `Num' instance for Type which signals an error on underflow."
`(define-instance (Num ,type)
(define (+ a b)
(lisp ,type (a b)
(cl:if (cl:and (cl:< b 0) (cl:< a (cl:- 0 b)))
(cl:error ,(cl:format cl:nil "Unsigned value underflowed ~D bits." bits))
(cl:+ a b))))

(define (- a b)
(lisp ,type (a b)
(cl:if (cl:and (cl:>= b 0) (cl:< a (cl:+ 0 b)))
(cl:error ,(cl:format cl:nil "Unsigned value underflowed ~D bits." bits))
(cl:- a b))))

(define (* a b)
(lisp ,type (a b)
(cl:if (cl:or (cl:and (cl:and (cl:> b 0) (cl:< a 0)) (cl:< a (cl:/ 0 b)))
(cl:and (cl:and (cl:< b 0) (cl:> a 0)) (cl:> a (cl:/ 0 b))))
(cl:error ,(cl:format cl:nil "Unsigned value underflowed ~D bits." bits))
(cl:* a b))))

(define (fromInt x)
(lisp ,type (x)
(cl:if (cl:< x 0)
(cl:error ,(cl:format cl:nil "Unsigned value underflowed ~D bits." bits))
x))))))

(cl:eval-when (:compile-toplevel :load-toplevel)
(cl:defmacro define-num-checked (type overflow-handler)
"Define a `Num' instance for TYPE which signals on overflow."
Expand Down Expand Up @@ -214,7 +243,12 @@
(define-num-wrapping U16 16)
(define-num-wrapping U32 32)
(define-num-wrapping U64 64)
(define-num-wrapping UFix #.+unsigned-fixnum-bits+))
(define-num-wrapping UFix #.+unsigned-fixnum-bits+)

(define-unsigned-num-underflow U8 8)
(define-unsigned-num-underflow U16 16)
(define-unsigned-num-underflow U32 32)
(define-unsigned-num-underflow U64 64))

;;;
;;; Num instances for floats
Expand Down

0 comments on commit e962184

Please sign in to comment.