3 collections::{BTreeSet, HashMap},
7 use proc_macro2::{Ident, Span, TokenStream};
8 use quote::{quote, ToTokens};
10 parse::{Parse, ParseStream},
16 impl Parse for Input {
17 fn parse(_input: ParseStream) -> syn::Result<Self> {
22 macro_rules! make_enum {
24 $vis:vis enum $ty:ident {
26 $field:ident $(= $value:expr)?,
30 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
40 $vis const VALUES: &'static [Self] = &[
75 const fn bits(self) -> u32 {
89 const fn make_possible(lossless: bool) -> Self {
96 const fn make_non_lossy(possible: bool) -> Self {
103 const fn possible(self) -> bool {
105 Convertibility::Impossible => false,
106 Convertibility::Lossy | Convertibility::Lossless => true,
112 fn is_valid(self, bits: TypeBits, vector_scalar: VectorScalar) -> bool {
114 TypeKind::Float => bits >= TypeBits::Bits16,
115 TypeKind::Bool => bits == TypeBits::Bits8 || vector_scalar == VectorScalar::Vector,
116 TypeKind::UInt | TypeKind::SInt => true,
119 fn prim_ty(self, bits: TypeBits) -> Ident {
122 TypeKind::Bool => "bool".into(),
123 TypeKind::UInt => format!("u{}", bits.bits()),
124 TypeKind::SInt => format!("i{}", bits.bits()),
125 TypeKind::Float if bits == TypeBits::Bits16 => "F16".into(),
126 TypeKind::Float => format!("f{}", bits.bits()),
131 fn ty(self, bits: TypeBits, vector_scalar: VectorScalar) -> Ident {
132 let vec_prefix = match vector_scalar {
133 VectorScalar::Scalar => "",
134 VectorScalar::Vector => "Vec",
138 TypeKind::Bool => match vector_scalar {
139 VectorScalar::Scalar => "Bool".into(),
140 VectorScalar::Vector => format!("VecBool{}", bits.bits()),
142 TypeKind::UInt => format!("{}U{}", vec_prefix, bits.bits()),
143 TypeKind::SInt => format!("{}I{}", vec_prefix, bits.bits()),
144 TypeKind::Float => format!("{}F{}", vec_prefix, bits.bits()),
149 fn convertibility_to(
152 dest_type_kind: TypeKind,
154 ) -> Convertibility {
155 Convertibility::make_possible(match (self, dest_type_kind) {
156 (TypeKind::Bool, _) | (_, TypeKind::Bool) => {
157 return Convertibility::make_non_lossy(self == dest_type_kind);
159 (TypeKind::UInt, TypeKind::UInt) => dest_bits >= src_bits,
160 (TypeKind::UInt, TypeKind::SInt) => dest_bits > src_bits,
161 (TypeKind::UInt, TypeKind::Float) => dest_bits > src_bits,
162 (TypeKind::SInt, TypeKind::UInt) => false,
163 (TypeKind::SInt, TypeKind::SInt) => dest_bits >= src_bits,
164 (TypeKind::SInt, TypeKind::Float) => dest_bits > src_bits,
165 (TypeKind::Float, TypeKind::UInt) => false,
166 (TypeKind::Float, TypeKind::SInt) => false,
167 (TypeKind::Float, TypeKind::Float) => dest_bits >= src_bits,
172 #[derive(Default, Debug)]
173 struct TokenStreamSetElement {
174 token_stream: TokenStream,
178 impl Ord for TokenStreamSetElement {
179 fn cmp(&self, other: &Self) -> Ordering {
180 self.text.cmp(&other.text)
184 impl PartialOrd for TokenStreamSetElement {
185 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
186 Some(self.cmp(other))
190 impl PartialEq for TokenStreamSetElement {
191 fn eq(&self, other: &Self) -> bool {
192 self.text == other.text
196 impl Eq for TokenStreamSetElement {}
198 impl From<TokenStream> for TokenStreamSetElement {
199 fn from(token_stream: TokenStream) -> Self {
200 let text = token_stream.to_string();
201 Self { token_stream, text }
205 impl ToTokens for TokenStreamSetElement {
206 fn to_tokens(&self, tokens: &mut TokenStream) {
207 self.token_stream.to_tokens(tokens)
210 fn to_token_stream(&self) -> TokenStream {
211 self.token_stream.to_token_stream()
214 fn into_token_stream(self) -> TokenStream {
219 type TokenStreamSet = BTreeSet<TokenStreamSetElement>;
221 #[derive(Debug, Default)]
223 trait_sets_map: HashMap<(TypeKind, TypeBits, VectorScalar), TokenStreamSet>,
231 vector_scalar: VectorScalar,
232 ) -> &mut TokenStreamSet {
233 if type_kind == TypeKind::Bool && vector_scalar == VectorScalar::Scalar {
234 bits = TypeBits::Bits8;
237 .entry((type_kind, bits, vector_scalar))
244 vector_scalar: VectorScalar,
245 v: impl Into<TokenStreamSetElement>,
247 self.get(type_kind, bits, vector_scalar).insert(v.into());
250 for &bits in TypeBits::VALUES {
251 for &type_kind in TypeKind::VALUES {
252 for &vector_scalar in VectorScalar::VALUES {
253 if !type_kind.is_valid(bits, vector_scalar) {
256 let prim_ty = type_kind.prim_ty(bits);
257 let ty = type_kind.ty(bits, vector_scalar);
258 if vector_scalar == VectorScalar::Vector {
259 let scalar_ty = type_kind.ty(bits, VectorScalar::Scalar);
264 quote! { From<Self::#scalar_ty> },
267 let bool_ty = TypeKind::Bool.ty(bits, vector_scalar);
268 let uint_ty = TypeKind::UInt.ty(bits, vector_scalar);
269 let sint_ty = TypeKind::SInt.ty(bits, vector_scalar);
270 let type_trait = match type_kind {
271 TypeKind::Bool => quote! { Bool },
273 quote! { UInt<PrimUInt = #prim_ty, SignedType = Self::#sint_ty> }
276 quote! { SInt<PrimSInt = #prim_ty, UnsignedType = Self::#uint_ty> }
278 TypeKind::Float => quote! { Float<
279 BitsType = Self::#uint_ty,
280 SignedBitsType = Self::#sint_ty,
281 PrimFloat = #prim_ty,
284 self.add_trait(type_kind, bits, vector_scalar, type_trait);
289 quote! { Compare<Bool = Self::#bool_ty> },
295 quote! { Select<Self::#ty> },
300 VectorScalar::Scalar,
301 quote! { Select<Self::#ty> },
303 for &other_bits in TypeBits::VALUES {
304 for &other_type_kind in TypeKind::VALUES {
305 if !other_type_kind.is_valid(other_bits, vector_scalar) {
308 if other_bits == bits && other_type_kind == type_kind {
311 let other_ty = other_type_kind.ty(other_bits, vector_scalar);
313 other_type_kind.convertibility_to(other_bits, type_kind, bits);
314 if convertibility == Convertibility::Lossless {
319 quote! { From<Self::#other_ty> },
322 if convertibility.possible() {
327 quote! { ConvertFrom<Self::#other_ty> },
336 quote! { Make<Context = Self, Prim = #prim_ty> },
345 fn to_tokens(&self) -> syn::Result<TokenStream> {
346 let mut types = Vec::new();
347 let mut trait_sets = TraitSets::default();
349 for &bits in TypeBits::VALUES {
350 for &type_kind in TypeKind::VALUES {
351 for &vector_scalar in VectorScalar::VALUES {
352 if !type_kind.is_valid(bits, vector_scalar) {
355 let ty = type_kind.ty(bits, vector_scalar);
356 let traits = trait_sets.get(type_kind, bits, vector_scalar);
358 type #ty: #(#traits)+*;
363 Ok(quote! {#(#types)*})
368 pub fn make_context_types(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
369 let input = parse_macro_input!(input as Input);
370 match input.to_tokens() {
371 Ok(retval) => retval,
372 Err(err) => err.to_compile_error(),
382 fn test() -> syn::Result<()> {
383 Input {}.to_tokens()?;