1
1
mod enums;
2
2
mod parse;
3
-
4
- use std:: sync:: LazyLock ;
3
+ mod shared;
5
4
6
5
use parse:: { Invocation , StructuredInput } ;
7
6
use proc_macro as pm;
8
7
use proc_macro2:: { self as pm2, Span } ;
9
8
use quote:: { ToTokens , quote} ;
9
+ pub ( crate ) use shared:: { ALL_OPERATIONS , FloatTy , MathOpInfo , Ty } ;
10
10
use syn:: spanned:: Spanned ;
11
11
use syn:: visit_mut:: VisitMut ;
12
12
use syn:: { Ident , ItemEnum } ;
13
13
14
- const ALL_FUNCTIONS : & [ ( Ty , Signature , Option < Signature > , & [ & str ] ) ] = & [
15
- (
16
- // `fn(f32) -> f32`
17
- Ty :: F32 ,
18
- Signature { args : & [ Ty :: F32 ] , returns : & [ Ty :: F32 ] } ,
19
- None ,
20
- & [
21
- "acosf" , "acoshf" , "asinf" , "asinhf" , "atanf" , "atanhf" , "cbrtf" , "ceilf" , "cosf" ,
22
- "coshf" , "erff" , "exp10f" , "exp2f" , "expf" , "expm1f" , "fabsf" , "floorf" , "j0f" , "j1f" ,
23
- "lgammaf" , "log10f" , "log1pf" , "log2f" , "logf" , "rintf" , "roundf" , "sinf" , "sinhf" ,
24
- "sqrtf" , "tanf" , "tanhf" , "tgammaf" , "truncf" ,
25
- ] ,
26
- ) ,
27
- (
28
- // `(f64) -> f64`
29
- Ty :: F64 ,
30
- Signature { args : & [ Ty :: F64 ] , returns : & [ Ty :: F64 ] } ,
31
- None ,
32
- & [
33
- "acos" , "acosh" , "asin" , "asinh" , "atan" , "atanh" , "cbrt" , "ceil" , "cos" , "cosh" ,
34
- "erf" , "exp10" , "exp2" , "exp" , "expm1" , "fabs" , "floor" , "j0" , "j1" , "lgamma" , "log10" ,
35
- "log1p" , "log2" , "log" , "rint" , "round" , "sin" , "sinh" , "sqrt" , "tan" , "tanh" ,
36
- "tgamma" , "trunc" ,
37
- ] ,
38
- ) ,
39
- (
40
- // `(f32, f32) -> f32`
41
- Ty :: F32 ,
42
- Signature { args : & [ Ty :: F32 , Ty :: F32 ] , returns : & [ Ty :: F32 ] } ,
43
- None ,
44
- & [
45
- "atan2f" ,
46
- "copysignf" ,
47
- "fdimf" ,
48
- "fmaxf" ,
49
- "fminf" ,
50
- "fmodf" ,
51
- "hypotf" ,
52
- "nextafterf" ,
53
- "powf" ,
54
- "remainderf" ,
55
- ] ,
56
- ) ,
57
- (
58
- // `(f64, f64) -> f64`
59
- Ty :: F64 ,
60
- Signature { args : & [ Ty :: F64 , Ty :: F64 ] , returns : & [ Ty :: F64 ] } ,
61
- None ,
62
- & [
63
- "atan2" ,
64
- "copysign" ,
65
- "fdim" ,
66
- "fmax" ,
67
- "fmin" ,
68
- "fmod" ,
69
- "hypot" ,
70
- "nextafter" ,
71
- "pow" ,
72
- "remainder" ,
73
- ] ,
74
- ) ,
75
- (
76
- // `(f32, f32, f32) -> f32`
77
- Ty :: F32 ,
78
- Signature { args : & [ Ty :: F32 , Ty :: F32 , Ty :: F32 ] , returns : & [ Ty :: F32 ] } ,
79
- None ,
80
- & [ "fmaf" ] ,
81
- ) ,
82
- (
83
- // `(f64, f64, f64) -> f64`
84
- Ty :: F64 ,
85
- Signature { args : & [ Ty :: F64 , Ty :: F64 , Ty :: F64 ] , returns : & [ Ty :: F64 ] } ,
86
- None ,
87
- & [ "fma" ] ,
88
- ) ,
89
- (
90
- // `(f32) -> i32`
91
- Ty :: F32 ,
92
- Signature { args : & [ Ty :: F32 ] , returns : & [ Ty :: I32 ] } ,
93
- None ,
94
- & [ "ilogbf" ] ,
95
- ) ,
96
- (
97
- // `(f64) -> i32`
98
- Ty :: F64 ,
99
- Signature { args : & [ Ty :: F64 ] , returns : & [ Ty :: I32 ] } ,
100
- None ,
101
- & [ "ilogb" ] ,
102
- ) ,
103
- (
104
- // `(i32, f32) -> f32`
105
- Ty :: F32 ,
106
- Signature { args : & [ Ty :: I32 , Ty :: F32 ] , returns : & [ Ty :: F32 ] } ,
107
- None ,
108
- & [ "jnf" ] ,
109
- ) ,
110
- (
111
- // `(i32, f64) -> f64`
112
- Ty :: F64 ,
113
- Signature { args : & [ Ty :: I32 , Ty :: F64 ] , returns : & [ Ty :: F64 ] } ,
114
- None ,
115
- & [ "jn" ] ,
116
- ) ,
117
- (
118
- // `(f32, i32) -> f32`
119
- Ty :: F32 ,
120
- Signature { args : & [ Ty :: F32 , Ty :: I32 ] , returns : & [ Ty :: F32 ] } ,
121
- None ,
122
- & [ "scalbnf" , "ldexpf" ] ,
123
- ) ,
124
- (
125
- // `(f64, i64) -> f64`
126
- Ty :: F64 ,
127
- Signature { args : & [ Ty :: F64 , Ty :: I32 ] , returns : & [ Ty :: F64 ] } ,
128
- None ,
129
- & [ "scalbn" , "ldexp" ] ,
130
- ) ,
131
- (
132
- // `(f32, &mut f32) -> f32` as `(f32) -> (f32, f32)`
133
- Ty :: F32 ,
134
- Signature { args : & [ Ty :: F32 ] , returns : & [ Ty :: F32 , Ty :: F32 ] } ,
135
- Some ( Signature { args : & [ Ty :: F32 , Ty :: MutF32 ] , returns : & [ Ty :: F32 ] } ) ,
136
- & [ "modff" ] ,
137
- ) ,
138
- (
139
- // `(f64, &mut f64) -> f64` as `(f64) -> (f64, f64)`
140
- Ty :: F64 ,
141
- Signature { args : & [ Ty :: F64 ] , returns : & [ Ty :: F64 , Ty :: F64 ] } ,
142
- Some ( Signature { args : & [ Ty :: F64 , Ty :: MutF64 ] , returns : & [ Ty :: F64 ] } ) ,
143
- & [ "modf" ] ,
144
- ) ,
145
- (
146
- // `(f32, &mut c_int) -> f32` as `(f32) -> (f32, i32)`
147
- Ty :: F32 ,
148
- Signature { args : & [ Ty :: F32 ] , returns : & [ Ty :: F32 , Ty :: I32 ] } ,
149
- Some ( Signature { args : & [ Ty :: F32 , Ty :: MutCInt ] , returns : & [ Ty :: F32 ] } ) ,
150
- & [ "frexpf" , "lgammaf_r" ] ,
151
- ) ,
152
- (
153
- // `(f64, &mut c_int) -> f64` as `(f64) -> (f64, i32)`
154
- Ty :: F64 ,
155
- Signature { args : & [ Ty :: F64 ] , returns : & [ Ty :: F64 , Ty :: I32 ] } ,
156
- Some ( Signature { args : & [ Ty :: F64 , Ty :: MutCInt ] , returns : & [ Ty :: F64 ] } ) ,
157
- & [ "frexp" , "lgamma_r" ] ,
158
- ) ,
159
- (
160
- // `(f32, f32, &mut c_int) -> f32` as `(f32, f32) -> (f32, i32)`
161
- Ty :: F32 ,
162
- Signature { args : & [ Ty :: F32 , Ty :: F32 ] , returns : & [ Ty :: F32 , Ty :: I32 ] } ,
163
- Some ( Signature { args : & [ Ty :: F32 , Ty :: F32 , Ty :: MutCInt ] , returns : & [ Ty :: F32 ] } ) ,
164
- & [ "remquof" ] ,
165
- ) ,
166
- (
167
- // `(f64, f64, &mut c_int) -> f64` as `(f64, f64) -> (f64, i32)`
168
- Ty :: F64 ,
169
- Signature { args : & [ Ty :: F64 , Ty :: F64 ] , returns : & [ Ty :: F64 , Ty :: I32 ] } ,
170
- Some ( Signature { args : & [ Ty :: F64 , Ty :: F64 , Ty :: MutCInt ] , returns : & [ Ty :: F64 ] } ) ,
171
- & [ "remquo" ] ,
172
- ) ,
173
- (
174
- // `(f32, &mut f32, &mut f32)` as `(f32) -> (f32, f32)`
175
- Ty :: F32 ,
176
- Signature { args : & [ Ty :: F32 ] , returns : & [ Ty :: F32 , Ty :: F32 ] } ,
177
- Some ( Signature { args : & [ Ty :: F32 , Ty :: MutF32 , Ty :: MutF32 ] , returns : & [ ] } ) ,
178
- & [ "sincosf" ] ,
179
- ) ,
180
- (
181
- // `(f64, &mut f64, &mut f64)` as `(f64) -> (f64, f64)`
182
- Ty :: F64 ,
183
- Signature { args : & [ Ty :: F64 ] , returns : & [ Ty :: F64 , Ty :: F64 ] } ,
184
- Some ( Signature { args : & [ Ty :: F64 , Ty :: MutF64 , Ty :: MutF64 ] , returns : & [ ] } ) ,
185
- & [ "sincos" ] ,
186
- ) ,
187
- ] ;
188
-
189
14
const KNOWN_TYPES : & [ & str ] = & [ "FTy" , "CFn" , "CArgs" , "CRet" , "RustFn" , "RustArgs" , "RustRet" ] ;
190
15
191
- /// A type used in a function signature.
192
- #[ allow( dead_code) ]
193
- #[ derive( Debug , Clone , Copy ) ]
194
- enum Ty {
195
- F16 ,
196
- F32 ,
197
- F64 ,
198
- F128 ,
199
- I32 ,
200
- CInt ,
201
- MutF16 ,
202
- MutF32 ,
203
- MutF64 ,
204
- MutF128 ,
205
- MutI32 ,
206
- MutCInt ,
207
- }
208
-
209
- impl ToTokens for Ty {
210
- fn to_tokens ( & self , tokens : & mut pm2:: TokenStream ) {
211
- let ts = match self {
212
- Ty :: F16 => quote ! { f16 } ,
213
- Ty :: F32 => quote ! { f32 } ,
214
- Ty :: F64 => quote ! { f64 } ,
215
- Ty :: F128 => quote ! { f128 } ,
216
- Ty :: I32 => quote ! { i32 } ,
217
- Ty :: CInt => quote ! { :: core:: ffi:: c_int } ,
218
- Ty :: MutF16 => quote ! { & ' a mut f16 } ,
219
- Ty :: MutF32 => quote ! { & ' a mut f32 } ,
220
- Ty :: MutF64 => quote ! { & ' a mut f64 } ,
221
- Ty :: MutF128 => quote ! { & ' a mut f128 } ,
222
- Ty :: MutI32 => quote ! { & ' a mut i32 } ,
223
- Ty :: MutCInt => quote ! { & ' a mut core:: ffi:: c_int } ,
224
- } ;
225
-
226
- tokens. extend ( ts) ;
227
- }
228
- }
229
-
230
- /// Representation of e.g. `(f32, f32) -> f32`
231
- #[ derive( Debug , Clone ) ]
232
- struct Signature {
233
- args : & ' static [ Ty ] ,
234
- returns : & ' static [ Ty ] ,
235
- }
236
-
237
- /// Combined information about a function implementation.
238
- #[ derive( Debug , Clone ) ]
239
- struct FunctionInfo {
240
- name : & ' static str ,
241
- base_fty : Ty ,
242
- /// Function signature for C implementations
243
- c_sig : Signature ,
244
- /// Function signature for Rust implementations
245
- rust_sig : Signature ,
246
- }
247
-
248
- /// A flat representation of `ALL_FUNCTIONS`.
249
- static ALL_FUNCTIONS_FLAT : LazyLock < Vec < FunctionInfo > > = LazyLock :: new ( || {
250
- let mut ret = Vec :: new ( ) ;
251
-
252
- for ( base_fty, rust_sig, c_sig, names) in ALL_FUNCTIONS {
253
- for name in * names {
254
- let api = FunctionInfo {
255
- name,
256
- base_fty : * base_fty,
257
- rust_sig : rust_sig. clone ( ) ,
258
- c_sig : c_sig. clone ( ) . unwrap_or_else ( || rust_sig. clone ( ) ) ,
259
- } ;
260
- ret. push ( api) ;
261
- }
262
- }
263
-
264
- ret. sort_by_key ( |item| item. name ) ;
265
- ret
266
- } ) ;
267
-
268
16
/// Populate an enum with a variant representing function. Names are in upper camel case.
269
17
///
270
18
/// Applied to an empty enum. Expects one attribute `#[function_enum(BaseName)]` that provides
@@ -382,7 +130,7 @@ pub fn for_each_function(tokens: pm::TokenStream) -> pm::TokenStream {
382
130
/// Check for any input that is structurally correct but has other problems.
383
131
///
384
132
/// Returns the list of function names that we should expand for.
385
- fn validate ( input : & mut StructuredInput ) -> syn:: Result < Vec < & ' static FunctionInfo > > {
133
+ fn validate ( input : & mut StructuredInput ) -> syn:: Result < Vec < & ' static MathOpInfo > > {
386
134
// Collect lists of all functions that are provied as macro inputs in various fields (only,
387
135
// skip, attributes).
388
136
let attr_mentions = input
@@ -398,7 +146,7 @@ fn validate(input: &mut StructuredInput) -> syn::Result<Vec<&'static FunctionInf
398
146
399
147
// Make sure that every function mentioned is a real function
400
148
for mentioned in all_mentioned_fns {
401
- if !ALL_FUNCTIONS_FLAT . iter ( ) . any ( |func| mentioned == func. name ) {
149
+ if !ALL_OPERATIONS . iter ( ) . any ( |func| mentioned == func. name ) {
402
150
let e = syn:: Error :: new (
403
151
mentioned. span ( ) ,
404
152
format ! ( "unrecognized function name `{mentioned}`" ) ,
@@ -417,7 +165,7 @@ fn validate(input: &mut StructuredInput) -> syn::Result<Vec<&'static FunctionInf
417
165
418
166
// Construct a list of what we intend to expand
419
167
let mut fn_list = Vec :: new ( ) ;
420
- for func in ALL_FUNCTIONS_FLAT . iter ( ) {
168
+ for func in ALL_OPERATIONS . iter ( ) {
421
169
let fn_name = func. name ;
422
170
// If we have an `only` list and it does _not_ contain this function name, skip it
423
171
if input. only . as_ref ( ) . is_some_and ( |only| !only. iter ( ) . any ( |o| o == fn_name) ) {
@@ -498,7 +246,7 @@ fn validate(input: &mut StructuredInput) -> syn::Result<Vec<&'static FunctionInf
498
246
}
499
247
500
248
/// Expand our structured macro input into invocations of the callback macro.
501
- fn expand ( input : StructuredInput , fn_list : & [ & FunctionInfo ] ) -> syn:: Result < pm2:: TokenStream > {
249
+ fn expand ( input : StructuredInput , fn_list : & [ & MathOpInfo ] ) -> syn:: Result < pm2:: TokenStream > {
502
250
let mut out = pm2:: TokenStream :: new ( ) ;
503
251
let default_ident = Ident :: new ( "_" , Span :: call_site ( ) ) ;
504
252
let callback = input. callback ;
@@ -545,7 +293,7 @@ fn expand(input: StructuredInput, fn_list: &[&FunctionInfo]) -> syn::Result<pm2:
545
293
None => pm2:: TokenStream :: new ( ) ,
546
294
} ;
547
295
548
- let base_fty = func. base_fty ;
296
+ let base_fty = func. float_ty ;
549
297
let c_args = & func. c_sig . args ;
550
298
let c_ret = & func. c_sig . returns ;
551
299
let rust_args = & func. rust_sig . args ;
@@ -648,3 +396,36 @@ fn base_name(name: &str) -> &str {
648
396
. unwrap_or ( name) ,
649
397
}
650
398
}
399
+
400
+ impl ToTokens for Ty {
401
+ fn to_tokens ( & self , tokens : & mut pm2:: TokenStream ) {
402
+ let ts = match self {
403
+ Ty :: F16 => quote ! { f16 } ,
404
+ Ty :: F32 => quote ! { f32 } ,
405
+ Ty :: F64 => quote ! { f64 } ,
406
+ Ty :: F128 => quote ! { f128 } ,
407
+ Ty :: I32 => quote ! { i32 } ,
408
+ Ty :: CInt => quote ! { :: core:: ffi:: c_int } ,
409
+ Ty :: MutF16 => quote ! { & ' a mut f16 } ,
410
+ Ty :: MutF32 => quote ! { & ' a mut f32 } ,
411
+ Ty :: MutF64 => quote ! { & ' a mut f64 } ,
412
+ Ty :: MutF128 => quote ! { & ' a mut f128 } ,
413
+ Ty :: MutI32 => quote ! { & ' a mut i32 } ,
414
+ Ty :: MutCInt => quote ! { & ' a mut core:: ffi:: c_int } ,
415
+ } ;
416
+
417
+ tokens. extend ( ts) ;
418
+ }
419
+ }
420
+ impl ToTokens for FloatTy {
421
+ fn to_tokens ( & self , tokens : & mut pm2:: TokenStream ) {
422
+ let ts = match self {
423
+ FloatTy :: F16 => quote ! { f16 } ,
424
+ FloatTy :: F32 => quote ! { f32 } ,
425
+ FloatTy :: F64 => quote ! { f64 } ,
426
+ FloatTy :: F128 => quote ! { f128 } ,
427
+ } ;
428
+
429
+ tokens. extend ( ts) ;
430
+ }
431
+ }
0 commit comments