1 ! (c)Joe Groff bsd license
2 USING: accessors alien.c-types arrays assocs classes combinators
3 combinators.short-circuit cords fry kernel locals math
4 math.vectors math.vectors.conversion.backend sequences ;
5 FROM: alien.c-types => char uchar short ushort int uint longlong ulonglong float double ;
6 IN: math.vectors.conversion
8 ERROR: bad-vconvert from-type to-type ;
9 ERROR: bad-vconvert-input value expected-type ;
13 : float-type? ( c-type -- ? )
14 { float double } member-eq? ;
15 : unsigned-type? ( c-type -- ? )
16 { uchar ushort uint ulonglong } member-eq? ;
18 : check-vconvert-type ( value expected-type -- value )
19 2dup instance? [ drop ] [ bad-vconvert-input ] if ; inline
21 :: [vconvert] ( from-element to-element from-size to-size from-type to-type -- quot )
24 [ from-element to-element eq? ]
28 [ from-element to-element [ float-type? not ] both? ]
29 [ [ underlying>> to-type boa ] ]
32 [ from-element float-type? ]
33 [ [ to-type (v>integer) ] ]
36 [ to-element float-type? ]
37 [ [ to-type (v>float) ] ]
40 [ from-type check-vconvert-type ] prepose ;
42 :: check-vpack ( from-element to-element from-type to-type steps -- )
45 [ from-element to-element [ float-type? ] bi@ xor ]
46 [ from-element unsigned-type? to-element unsigned-type? not and ]
47 } 0|| [ from-type to-type bad-vconvert ] when ;
49 :: [[vpack-unsigned]] ( from-type to-type -- quot )
50 [ [ from-type check-vconvert-type ] bi@ to-type (vpack-unsigned) ] ;
52 :: [[vpack-signed]] ( from-type to-type -- quot )
53 [ [ from-type check-vconvert-type ] bi@ to-type (vpack-signed) ] ;
55 :: [vpack] ( from-element to-element from-size to-size from-type to-type -- quot )
56 from-size to-size /i log2 :> steps
58 from-element to-element from-type to-type steps check-vpack
60 from-type to-type to-element unsigned-type?
61 [ [[vpack-unsigned]] ] [ [[vpack-signed]] ] if ;
63 :: check-vunpack ( from-element to-element from-type to-type steps -- )
66 [ from-element to-element [ float-type? ] bi@ xor ]
67 [ from-element unsigned-type? not to-element unsigned-type? and ]
68 } 0|| [ from-type to-type bad-vconvert ] when ;
70 :: [[vunpack]] ( from-type to-type -- quot )
72 from-type check-vconvert-type
73 [ to-type (vunpack-head) ] [ to-type (vunpack-tail) ] bi
76 :: [vunpack] ( from-element to-element from-size to-size from-type to-type -- quot )
77 to-size from-size /i log2 :> steps
78 from-element to-element from-type to-type steps check-vunpack
79 from-type to-type [[vunpack]] ;
83 MACRO:: vconvert ( from-type to-type -- )
84 from-type new [ element-type ] [ byte-length ] bi :> ( from-element from-length )
85 to-type new [ element-type ] [ byte-length ] bi :> ( to-element to-length )
86 from-element heap-size :> from-size
87 to-element heap-size :> to-size
89 from-length to-length = [ from-type to-type bad-vconvert ] unless
91 from-element to-element from-size to-size from-type to-type {
92 { [ from-size to-size < ] [ [vunpack] ] }
93 { [ from-size to-size = ] [ [vconvert] ] }
94 { [ from-size to-size > ] [ [vpack] ] }