diff --git a/xenomorph/xenomorph/number.rkt b/xenomorph/xenomorph/number.rkt index bb9c5ef8..97807d93 100644 --- a/xenomorph/xenomorph/number.rkt +++ b/xenomorph/xenomorph/number.rkt @@ -1,5 +1,5 @@ #lang debug racket/base -(require "base.rkt" "int.rkt" "list.rkt" racket/class) +(require "base.rkt" "int.rkt" "list.rkt" racket/class racket/contract) (provide (all-defined-out) (all-from-out "int.rkt")) #| @@ -8,6 +8,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee |# +(define (x:float? x) (is-a? x x:float%)) (define x:float% (class x:number% @@ -20,10 +21,22 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee (define/augment (x:encode val . _) (real->floating-point-bytes val @size (eq? @endian 'be))))) -(define (x:float [size 4] #:endian [endian system-endian] +(define/contract (x:float [size-arg #f] + #:size [size-kwarg 4] + #:endian [endian system-endian] #:pre-encode [pre-proc #f] #:post-decode [post-proc #f] #:base-class [base-class x:float%]) + (() + ((or/c exact-positive-integer? #false) + #:size exact-positive-integer? + #:endian endian-value? + #:pre-encode (or/c (any/c . -> . any/c) #false) + #:post-decode (or/c (any/c . -> . any/c) #false) + #:base-class (λ (c) (subclass? c x:float?))) + . ->* . + x:float?) + (define size (or size-arg size-kwarg)) (new (generate-subclass base-class pre-proc post-proc) [size size] [endian endian])) (define float (x:float 4)) diff --git a/xenomorph/xenomorph/scribblings/xenomorph.scrbl b/xenomorph/xenomorph/scribblings/xenomorph.scrbl index 34c89c35..df283188 100644 --- a/xenomorph/xenomorph/scribblings/xenomorph.scrbl +++ b/xenomorph/xenomorph/scribblings/xenomorph.scrbl @@ -378,6 +378,55 @@ Little-endian versions of the common integer types. The @racket[u] prefix indica @subsubsection{Floats} +@defclass[x:float% x:number% ()]{ +Base class for floating-point number objects. By convention, all floats are signed. Use @racket[x:float] to conveniently instantiate new floating-point number objects. +} + +@defproc[ +(x:float? +[x any/c]) +boolean?]{ +Predicate for whether @racket[x] is an object of type @racket[x:float%]. +} + +@defproc[ +(x:float +[size-arg (or/c exact-positive-integer? #false) #false] +[#:size size-kw exact-positive-integer? 2] +[#:endian endian endian-value? system-endian] +[#:pre-encode pre-encode-proc (or/c (any/c . -> . any/c) #false) #false] +[#:post-decode post-decode-proc (or/c (any/c . -> . any/c) #false) #false] +[#:base-class base-class (λ (c) (subclass? c x:float%)) x:float%] +) +x:int?]{ +Generate an instance of @racket[x:float%] (or a subclass of @racket[x:float%]) with certain optional attributes. + +@racket[size-arg] or @racket[size-kw] (whichever is provided, though @racket[size-kw] takes precedence) controls the encoded size. + +@racket[endian] controls the byte-ordering convention. + +@racket[pre-encode-proc] and @racket[post-decode-proc] control the pre-encoding and post-decodeing procedures, respectively. + +@racket[base-class] controls the class used for instantiation of the new object. +} + +@deftogether[ +(@defthing[float x:float?] +@defthing[floatbe x:float?] +@defthing[floatle x:float?]) +]{ +The common 32-bit floating-point types. They differ in byte-ordering convention: @racket[floatbe] uses big endian, @racket[floatle] uses little endian, @racket[float] uses @racket[system-endian]. +} + +@deftogether[ +(@defthing[double x:float?] +@defthing[doublebe x:float?] +@defthing[doublele x:float?]) +]{ +The common 64-bit floating-point types. They differ in byte-ordering convention: @racket[doublebe] uses big endian, @racket[doublele] uses little endian, @racket[double] uses @racket[system-endian]. +} + + @subsubsection{Fixed-points}