Module: internal Authors: Gary Palter Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// BOOTED: define ... class ... end; define inline-only function %double-integer-low (di :: ) => (low :: ) primitive-wrap-machine-word (primitive-cast-pointer-as-raw(primitive-initialized-slot-value(di, integer-as-raw(0)))) end function %double-integer-low; define inline-only function %double-integer-low-setter (new-low :: , di :: ) => (new-low :: ) primitive-slot-value(di, integer-as-raw(0)) := primitive-cast-raw-as-pointer(primitive-unwrap-machine-word(new-low)); new-low end function %double-integer-low-setter; define inline-only function %double-integer-high (di :: ) => (high :: ) primitive-wrap-machine-word (primitive-cast-pointer-as-raw(primitive-initialized-slot-value(di, integer-as-raw(1)))) end function %double-integer-high; define inline-only function %double-integer-high-setter (new-high :: , di :: ) => (new-high :: ) primitive-slot-value(di, integer-as-raw(1)) := primitive-cast-raw-as-pointer(primitive-unwrap-machine-word(new-high)); new-high end function %double-integer-high-setter; define sealed inline method make (class == , #key low :: , high :: ) => (di :: ) let di = system-allocate-simple-instance(); %double-integer-low(di) := low; %double-integer-high(di) := high; di end method make; define macro integer-double-comparison-methods-definer // The ?integer argument is the predicate to use in the method where the // first argument is an and ?double is for the method where the // first argument is a . In all cases, the // is the argument to the predicate. { define integer-double-comparison-methods ?:name ?integer:name ?double:name } => { define sealed inline method ?name (x :: , y :: ) => (result :: ) ?integer(y) end method ?name; define sealed inline method ?name (x :: , y :: ) => (result :: ) ?double(x) end method ?name } // With no predicate arguments, define the methods to return #f { define integer-double-comparison-methods ?:name } => { define sealed inline method ?name (x :: , y :: ) => (result :: ) #f end method ?name; define sealed inline method ?name (x :: , y :: ) => (result :: ) #f end method ?name } end macro integer-double-comparison-methods-definer; ///---*** NOTE: The DRM states that comparison between s and s ///---*** should be accomplished by converting the to a rather ///---*** than the other way around which is how we've implemented it here. define macro float-double-comparison-methods-definer { define float-double-comparison-methods ?:name } => { define sealed inline method ?name (x :: , y :: ) => (result :: ) ?name(x, as(, y)) end method ?name; define sealed inline method ?name (x :: , y :: ) => (result :: ) ?name(as(, x), y) end method ?name } end macro float-double-comparison-methods-definer; define sealed inline method \= (x :: , y :: ) => (result :: ) machine-word-equal?(%double-integer-low(x), %double-integer-low(y)) & machine-word-equal?(%double-integer-high(x), %double-integer-high(y)) end method \=; /// As and are disjoint, they will never be equal. define integer-double-comparison-methods \=; define float-double-comparison-methods \=; define sealed inline method \< (x :: , y :: ) => (result :: ) machine-word-less-than?(%double-integer-high(x), %double-integer-high(y)) | (machine-word-equal?(%double-integer-high(x), %double-integer-high(y)) & machine-word-unsigned-less-than?(%double-integer-low(x), %double-integer-low(y))) end method \<; /// As and are disjoint, an is less than /// a if, and only if, the is positive. /// Similarly, a is less than an if, and only if, /// the is negative. define integer-double-comparison-methods \< positive? negative?; define float-double-comparison-methods \<; define sealed inline method odd? (x :: ) => (odd? :: ) machine-word-logbit?(0, %double-integer-low(x)) end method odd?; define sealed inline method even? (x :: ) => (zero? :: ) ~machine-word-logbit?(0, %double-integer-low(x)) end method even?; /// As and are disjoint and 0 is an , /// no will ever be zero ... define sealed inline method zero? (x :: ) => (zero? :: ) #f end method zero?; define sealed inline method positive? (x :: ) => (positive? :: ) ~zero?(x) & ~negative?(x) end method positive?; define sealed inline method negative? (x :: ) => (negative? :: ) machine-word-less-than?(%double-integer-high(x), coerce-integer-to-machine-word(0)) end method negative?; define sealed inline method integral? (x :: ) => (integral? :: ) #t end method integral?;