glsl_lang_pp/types/
token.rs

1use lang_util::SmolStr;
2
3use crate::{lexer, util::Unescaped};
4
5use super::{
6    keywords::KeywordAtom,
7    type_names::{TypeNameAtom, TypeNameState},
8};
9
10#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, derive_more::Display)]
11#[allow(non_camel_case_types)]
12pub enum TypeName {
13    /// "void"
14    #[display("void")]
15    VOID,
16    /// "int"
17    #[display("int")]
18    INT,
19    /// "bool"
20    #[display("bool")]
21    BOOL,
22    /// "float"
23    #[display("float")]
24    FLOAT,
25    /// "double"
26    #[display("double")]
27    DOUBLE,
28    /// "vec2"
29    #[display("vec2")]
30    VEC2,
31    /// "vec3"
32    #[display("vec3")]
33    VEC3,
34    /// "vec4"
35    #[display("vec4")]
36    VEC4,
37    /// "ivec2"
38    #[display("ivec2")]
39    IVEC2,
40    /// "ivec3"
41    #[display("ivec3")]
42    IVEC3,
43    /// "ivec4"
44    #[display("ivec4")]
45    IVEC4,
46    /// "bvec2"
47    #[display("bvec2")]
48    BVEC2,
49    /// "bvec3"
50    #[display("bvec3")]
51    BVEC3,
52    /// "bvec4"
53    #[display("bvec4")]
54    BVEC4,
55    /// "uint"
56    #[display("uint")]
57    UINT,
58    /// "atomic_uint"
59    #[display("atomic_uint")]
60    ATOMIC_UINT,
61    /// "uvec2"
62    #[display("uvec2")]
63    UVEC2,
64    /// "uvec3"
65    #[display("uvec3")]
66    UVEC3,
67    /// "uvec4"
68    #[display("uvec4")]
69    UVEC4,
70    /// "dvec2"
71    #[display("dvec2")]
72    DVEC2,
73    /// "dvec3"
74    #[display("dvec3")]
75    DVEC3,
76    /// "dvec4"
77    #[display("dvec4")]
78    DVEC4,
79    /// "mat2"
80    #[display("mat2")]
81    MAT2,
82    /// "mat3"
83    #[display("mat3")]
84    MAT3,
85    /// "mat4"
86    #[display("mat4")]
87    MAT4,
88    /// "mat2x2"
89    #[display("mat2x2")]
90    MAT2X2,
91    /// "mat2x3"
92    #[display("mat2x3")]
93    MAT2X3,
94    /// "mat2x4"
95    #[display("mat2x4")]
96    MAT2X4,
97    /// "mat3x2"
98    #[display("mat3x2")]
99    MAT3X2,
100    /// "mat3x3"
101    #[display("mat3x3")]
102    MAT3X3,
103    /// "mat3x4"
104    #[display("mat3x4")]
105    MAT3X4,
106    /// "mat4x2"
107    #[display("mat4x2")]
108    MAT4X2,
109    /// "mat4x3"
110    #[display("mat4x3")]
111    MAT4X3,
112    /// "mat4x4"
113    #[display("mat4x4")]
114    MAT4X4,
115    /// "dmat2"
116    #[display("dmat2")]
117    DMAT2,
118    /// "dmat3"
119    #[display("dmat3")]
120    DMAT3,
121    /// "dmat4"
122    #[display("dmat4")]
123    DMAT4,
124    /// "dmat2x2"
125    #[display("dmat2x2")]
126    DMAT2X2,
127    /// "dmat2x3"
128    #[display("dmat2x3")]
129    DMAT2X3,
130    /// "dmat2x4"
131    #[display("dmat2x4")]
132    DMAT2X4,
133    /// "dmat3x2"
134    #[display("dmat3x2")]
135    DMAT3X2,
136    /// "dmat3x3"
137    #[display("dmat3x3")]
138    DMAT3X3,
139    /// "dmat3x4"
140    #[display("dmat3x4")]
141    DMAT3X4,
142    /// "dmat4x2"
143    #[display("dmat4x2")]
144    DMAT4X2,
145    /// "dmat4x3"
146    #[display("dmat4x3")]
147    DMAT4X3,
148    /// "dmat4x4"
149    #[display("dmat4x4")]
150    DMAT4X4,
151    /// "sampler1D"
152    #[display("sampler1D")]
153    SAMPLER1D,
154    /// "sampler1DShadow"
155    #[display("sampler1DShadow")]
156    SAMPLER1DSHADOW,
157    /// "sampler1DArray"
158    #[display("sampler1DArray")]
159    SAMPLER1DARRAY,
160    /// "sampler1DArrayShadow"
161    #[display("sampler1DArrayShadow")]
162    SAMPLER1DARRAYSHADOW,
163    /// "isampler1D"
164    #[display("isampler1D")]
165    ISAMPLER1D,
166    /// "isampler1DArray"
167    #[display("isampler1DArray")]
168    ISAMPLER1DARRAY,
169    /// "usampler1D"
170    #[display("usampler1D")]
171    USAMPLER1D,
172    /// "usampler1DArray"
173    #[display("usampler1DArray")]
174    USAMPLER1DARRAY,
175    /// "sampler2D"
176    #[display("sampler2D")]
177    SAMPLER2D,
178    /// "sampler2DShadow"
179    #[display("sampler2DShadow")]
180    SAMPLER2DSHADOW,
181    /// "sampler2DArray"
182    #[display("sampler2DArray")]
183    SAMPLER2DARRAY,
184    /// "sampler2DArrayShadow"
185    #[display("sampler2DArrayShadow")]
186    SAMPLER2DARRAYSHADOW,
187    /// "isampler2D"
188    #[display("isampler2D")]
189    ISAMPLER2D,
190    /// "isampler2DArray"
191    #[display("isampler2DArray")]
192    ISAMPLER2DARRAY,
193    /// "usampler2D"
194    #[display("usampler2D")]
195    USAMPLER2D,
196    /// "usampler2DArray"
197    #[display("usampler2DArray")]
198    USAMPLER2DARRAY,
199    /// "sampler2DRect"
200    #[display("sampler2DRect")]
201    SAMPLER2DRECT,
202    /// "sampler2DRectShadow"
203    #[display("sampler2DRectShadow")]
204    SAMPLER2DRECTSHADOW,
205    /// "isampler2DRect"
206    #[display("isampler2DRect")]
207    ISAMPLER2DRECT,
208    /// "usampler2DRect"
209    #[display("usampler2DRect")]
210    USAMPLER2DRECT,
211    /// "sampler2DMS"
212    #[display("sampler2DMS")]
213    SAMPLER2DMS,
214    /// "isampler2DMS"
215    #[display("isampler2DMS")]
216    ISAMPLER2DMS,
217    /// "usampler2DMS"
218    #[display("usampler2DMS")]
219    USAMPLER2DMS,
220    /// "sampler2DMSArray"
221    #[display("sampler2DMSArray")]
222    SAMPLER2DMSARRAY,
223    /// "isampler2DMSArray"
224    #[display("isampler2DMSArray")]
225    ISAMPLER2DMSARRAY,
226    /// "usampler2DMSArray"
227    #[display("usampler2DMSArray")]
228    USAMPLER2DMSARRAY,
229    /// "sampler3D"
230    #[display("sampler3D")]
231    SAMPLER3D,
232    /// "isampler3D"
233    #[display("isampler3D")]
234    ISAMPLER3D,
235    /// "usampler3D"
236    #[display("usampler3D")]
237    USAMPLER3D,
238    /// "samplerCube"
239    #[display("samplerCube")]
240    SAMPLERCUBE,
241    /// "samplerCubeShadow"
242    #[display("samplerCubeShadow")]
243    SAMPLERCUBESHADOW,
244    /// "isamplerCube"
245    #[display("isamplerCube")]
246    ISAMPLERCUBE,
247    /// "usamplerCube"
248    #[display("usamplerCube")]
249    USAMPLERCUBE,
250    /// "samplerCubeArray"
251    #[display("samplerCubeArray")]
252    SAMPLERCUBEARRAY,
253    /// "samplerCubeArrayShadow"
254    #[display("samplerCubeArrayShadow")]
255    SAMPLERCUBEARRAYSHADOW,
256    /// "isamplerCubeArray"
257    #[display("isamplerCubeArray")]
258    ISAMPLERCUBEARRAY,
259    /// "usamplerCubeArray"
260    #[display("usamplerCubeArray")]
261    USAMPLERCUBEARRAY,
262    /// "samplerBuffer"
263    #[display("samplerBuffer")]
264    SAMPLERBUFFER,
265    /// "isamplerBuffer"
266    #[display("isamplerBuffer")]
267    ISAMPLERBUFFER,
268    /// "usamplerBuffer"
269    #[display("usamplerBuffer")]
270    USAMPLERBUFFER,
271    /// "image1D"
272    #[display("image1D")]
273    IMAGE1D,
274    /// "iimage1D"
275    #[display("iimage1D")]
276    IIMAGE1D,
277    /// "uimage1D"
278    #[display("uimage1D")]
279    UIMAGE1D,
280    /// "image1DArray"
281    #[display("image1DArray")]
282    IMAGE1DARRAY,
283    /// "iimage1DArray"
284    #[display("iimage1DArray")]
285    IIMAGE1DARRAY,
286    /// "uimage1DArray"
287    #[display("uimage1DArray")]
288    UIMAGE1DARRAY,
289    /// "image2D"
290    #[display("image2D")]
291    IMAGE2D,
292    /// "iimage2D"
293    #[display("iimage2D")]
294    IIMAGE2D,
295    /// "uimage2D"
296    #[display("uimage2D")]
297    UIMAGE2D,
298    /// "image2DArray"
299    #[display("image2DArray")]
300    IMAGE2DARRAY,
301    /// "iimage2DArray"
302    #[display("iimage2DArray")]
303    IIMAGE2DARRAY,
304    /// "uimage2DArray"
305    #[display("uimage2DArray")]
306    UIMAGE2DARRAY,
307    /// "image2DRect"
308    #[display("image2DRect")]
309    IMAGE2DRECT,
310    /// "iimage2DRect"
311    #[display("iimage2DRect")]
312    IIMAGE2DRECT,
313    /// "uimage2DRect"
314    #[display("uimage2DRect")]
315    UIMAGE2DRECT,
316    /// "image2DMS"
317    #[display("image2DMS")]
318    IMAGE2DMS,
319    /// "iimage2DMS"
320    #[display("iimage2DMS")]
321    IIMAGE2DMS,
322    /// "uimage2DMS"
323    #[display("uimage2DMS")]
324    UIMAGE2DMS,
325    /// "image2DMSArray"
326    #[display("image2DMSArray")]
327    IMAGE2DMSARRAY,
328    /// "iimage2DMSArray"
329    #[display("iimage2DMSArray")]
330    IIMAGE2DMSARRAY,
331    /// "uimage2DMSArray"
332    #[display("uimage2DMSArray")]
333    UIMAGE2DMSARRAY,
334    /// "image3D"
335    #[display("image3D")]
336    IMAGE3D,
337    /// "iimage3D"
338    #[display("iimage3D")]
339    IIMAGE3D,
340    /// "uimage3D"
341    #[display("uimage3D")]
342    UIMAGE3D,
343    /// "imageCube"
344    #[display("imageCube")]
345    IMAGECUBE,
346    /// "iimageCube"
347    #[display("iimageCube")]
348    IIMAGECUBE,
349    /// "uimageCube"
350    #[display("uimageCube")]
351    UIMAGECUBE,
352    /// "imageCubeArray"
353    #[display("imageCubeArray")]
354    IMAGECUBEARRAY,
355    /// "iimageCubeArray"
356    #[display("iimageCubeArray")]
357    IIMAGECUBEARRAY,
358    /// "uimageCubeArray"
359    #[display("uimageCubeArray")]
360    UIMAGECUBEARRAY,
361    /// "imageBuffer"
362    #[display("imageBuffer")]
363    IMAGEBUFFER,
364    /// "iimageBuffer"
365    #[display("iimageBuffer")]
366    IIMAGEBUFFER,
367    /// "uimageBuffer"
368    #[display("uimageBuffer")]
369    UIMAGEBUFFER,
370    // Vulkan type names
371    /// "texture1D"
372    #[display("texture1D")]
373    TEXTURE1D,
374    /// "texture1DArray"
375    #[display("texture1DArray")]
376    TEXTURE1DARRAY,
377    /// "itexture1D"
378    #[display("itexture1D")]
379    ITEXTURE1D,
380    /// "itexture1DArray"
381    #[display("itexture1DArray")]
382    ITEXTURE1DARRAY,
383    /// "utexture1D"
384    #[display("utexture1D")]
385    UTEXTURE1D,
386    /// "utexture1DArray"
387    #[display("utexture1DArray")]
388    UTEXTURE1DARRAY,
389    /// "texture2D"
390    #[display("texture2D")]
391    TEXTURE2D,
392    /// "texture2DArray"
393    #[display("texture2DArray")]
394    TEXTURE2DARRAY,
395    /// "itexture2D"
396    #[display("itexture2D")]
397    ITEXTURE2D,
398    /// "itexture2DArray"
399    #[display("itexture2DArray")]
400    ITEXTURE2DARRAY,
401    /// "utexture2D"
402    #[display("utexture2D")]
403    UTEXTURE2D,
404    /// "utexture2DArray"
405    #[display("utexture2DArray")]
406    UTEXTURE2DARRAY,
407    /// "texture2DRect"
408    #[display("texture2DRect")]
409    TEXTURE2DRECT,
410    /// "itexture2DRect"
411    #[display("itexture2DRect")]
412    ITEXTURE2DRECT,
413    /// "utexture2DRect"
414    #[display("utexture2DRect")]
415    UTEXTURE2DRECT,
416    /// "texture2DMS"
417    #[display("texture2DMS")]
418    TEXTURE2DMS,
419    /// "itexture2DMS"
420    #[display("itexture2DMS")]
421    ITEXTURE2DMS,
422    /// "utexture2DMS"
423    #[display("utexture2DMS")]
424    UTEXTURE2DMS,
425    /// "texture2DMSArray"
426    #[display("texture2DMSArray")]
427    TEXTURE2DMSARRAY,
428    /// "itexture2DMSArray"
429    #[display("itexture2DMSArray")]
430    ITEXTURE2DMSARRAY,
431    /// "utexture2DMSArray"
432    #[display("utexture2DMSArray")]
433    UTEXTURE2DMSARRAY,
434    /// "texture3D"
435    #[display("texture3D")]
436    TEXTURE3D,
437    /// "itexture3D"
438    #[display("itexture3D")]
439    ITEXTURE3D,
440    /// "utexture3D"
441    #[display("utexture3D")]
442    UTEXTURE3D,
443    /// "textureCube"
444    #[display("textureCube")]
445    TEXTURECUBE,
446    /// "itextureCube"
447    #[display("itextureCube")]
448    ITEXTURECUBE,
449    /// "utextureCube"
450    #[display("utextureCube")]
451    UTEXTURECUBE,
452    /// "textureCubeArray"
453    #[display("textureCubeArray")]
454    TEXTURECUBEARRAY,
455    /// "itextureCubeArray"
456    #[display("itextureCubeArray")]
457    ITEXTURECUBEARRAY,
458    /// "utextureCubeArray"
459    #[display("utextureCubeArray")]
460    UTEXTURECUBEARRAY,
461    /// "textureBuffer"
462    #[display("textureBuffer")]
463    TEXTUREBUFFER,
464    /// "itextureBuffer"
465    #[display("itextureBuffer")]
466    ITEXTUREBUFFER,
467    /// "utextureBuffer"
468    #[display("utextureBuffer")]
469    UTEXTUREBUFFER,
470    /// "sampler"
471    #[display("sampler")]
472    SAMPLER,
473    /// "samplerShadow"
474    #[display("samplerShadow")]
475    SAMPLERSHADOW,
476    /// "subpassInput"
477    #[display("subpassInput")]
478    SUBPASSINPUT,
479    /// "isubpassInput"
480    #[display("isubpassInput")]
481    ISUBPASSINPUT,
482    /// "usubpassInput"
483    #[display("usubpassInput")]
484    USUBPASSINPUT,
485    /// "subpassInputMS"
486    #[display("subpassInputMS")]
487    SUBPASSINPUTMS,
488    /// "isubpassInputMS"
489    #[display("isubpassInputMS")]
490    ISUBPASSINPUTMS,
491    /// "usubpassInputMS"
492    #[display("usubpassInputMS")]
493    USUBPASSINPUTMS,
494    /// Reserved for future use
495    RESERVED(TypeNameAtom),
496    /// Generic type name
497    OTHER(TypeNameAtom),
498}
499
500impl TypeName {
501    fn gate(
502        self,
503        version_gate: bool,
504        reserved_gate: bool,
505        atom: TypeNameAtom,
506        is_type_name: impl Fn(&TypeNameAtom) -> TypeNameState,
507    ) -> Option<(Self, Option<TypeNameState>)> {
508        // Check if the version gate allows this
509        if version_gate {
510            return Some((self, None));
511        }
512
513        // Check if an extension enabled this
514        let result = is_type_name(&atom);
515        if result.is_type_name() {
516            return Some((self, Some(result)));
517        }
518
519        // Check if it's reserved
520        if reserved_gate {
521            return Some((Self::RESERVED(atom), None));
522        }
523
524        // Else it's unknown
525        None
526    }
527
528    pub(crate) fn parse(
529        name: &str,
530        version: u16,
531        target_vulkan: bool,
532        is_type_name: impl Fn(&TypeNameAtom) -> TypeNameState,
533    ) -> Option<(Self, Option<TypeNameState>)> {
534        // TODO: Check type names rules for OpenGL ES
535
536        use TypeName::*;
537
538        let type_name_atom = TypeNameAtom::from(name);
539
540        if type_name_atom == type_name!("void") {
541            return VOID.gate(version >= 100, false, type_name_atom, is_type_name);
542        } else if type_name_atom == type_name!("int") {
543            return INT.gate(version >= 100, false, type_name_atom, is_type_name);
544        } else if type_name_atom == type_name!("bool") {
545            return BOOL.gate(version >= 100, false, type_name_atom, is_type_name);
546        } else if type_name_atom == type_name!("float") {
547            return FLOAT.gate(version >= 100, false, type_name_atom, is_type_name);
548        } else if type_name_atom == type_name!("vec2") {
549            return VEC2.gate(version >= 100, false, type_name_atom, is_type_name);
550        } else if type_name_atom == type_name!("vec3") {
551            return VEC3.gate(version >= 100, false, type_name_atom, is_type_name);
552        } else if type_name_atom == type_name!("vec4") {
553            return VEC4.gate(version >= 100, false, type_name_atom, is_type_name);
554        } else if type_name_atom == type_name!("ivec2") {
555            return IVEC2.gate(version >= 100, false, type_name_atom, is_type_name);
556        } else if type_name_atom == type_name!("ivec3") {
557            return IVEC3.gate(version >= 100, false, type_name_atom, is_type_name);
558        } else if type_name_atom == type_name!("ivec4") {
559            return IVEC4.gate(version >= 100, false, type_name_atom, is_type_name);
560        } else if type_name_atom == type_name!("bvec2") {
561            return BVEC2.gate(version >= 100, false, type_name_atom, is_type_name);
562        } else if type_name_atom == type_name!("bvec3") {
563            return BVEC3.gate(version >= 100, false, type_name_atom, is_type_name);
564        } else if type_name_atom == type_name!("bvec4") {
565            return BVEC4.gate(version >= 100, false, type_name_atom, is_type_name);
566        } else if type_name_atom == type_name!("mat2") {
567            return MAT2.gate(version >= 100, false, type_name_atom, is_type_name);
568        } else if type_name_atom == type_name!("mat3") {
569            return MAT3.gate(version >= 100, false, type_name_atom, is_type_name);
570        } else if type_name_atom == type_name!("mat4") {
571            return MAT4.gate(version >= 100, false, type_name_atom, is_type_name);
572        } else if type_name_atom == type_name!("sampler1D") {
573            return SAMPLER1D.gate(version >= 100, false, type_name_atom, is_type_name);
574        } else if type_name_atom == type_name!("sampler1DShadow") {
575            return SAMPLER1DSHADOW.gate(version >= 100, false, type_name_atom, is_type_name);
576        } else if type_name_atom == type_name!("sampler2D") {
577            return SAMPLER2D.gate(version >= 100, false, type_name_atom, is_type_name);
578        } else if type_name_atom == type_name!("sampler2DShadow") {
579            return SAMPLER2DSHADOW.gate(version >= 100, false, type_name_atom, is_type_name);
580        } else if type_name_atom == type_name!("sampler3D") {
581            return SAMPLER3D.gate(version >= 100, false, type_name_atom, is_type_name);
582        } else if type_name_atom == type_name!("samplerCube") {
583            return SAMPLERCUBE.gate(version >= 100, false, type_name_atom, is_type_name);
584        }
585
586        // 120 type names
587        if type_name_atom == type_name!("mat2x2") {
588            return MAT2X2.gate(version >= 120, false, type_name_atom, is_type_name);
589        } else if type_name_atom == type_name!("mat2x3") {
590            return MAT2X3.gate(version >= 120, false, type_name_atom, is_type_name);
591        } else if type_name_atom == type_name!("mat2x4") {
592            return MAT2X4.gate(version >= 120, false, type_name_atom, is_type_name);
593        } else if type_name_atom == type_name!("mat3x2") {
594            return MAT3X2.gate(version >= 120, false, type_name_atom, is_type_name);
595        } else if type_name_atom == type_name!("mat3x3") {
596            return MAT3X3.gate(version >= 120, false, type_name_atom, is_type_name);
597        } else if type_name_atom == type_name!("mat3x4") {
598            return MAT3X4.gate(version >= 120, false, type_name_atom, is_type_name);
599        } else if type_name_atom == type_name!("mat4x2") {
600            return MAT4X2.gate(version >= 120, false, type_name_atom, is_type_name);
601        } else if type_name_atom == type_name!("mat4x3") {
602            return MAT4X3.gate(version >= 120, false, type_name_atom, is_type_name);
603        } else if type_name_atom == type_name!("mat4x4") {
604            return MAT4X4.gate(version >= 120, false, type_name_atom, is_type_name);
605        }
606
607        // 130 type names
608        if type_name_atom == type_name!("uint") {
609            return UINT.gate(version >= 130, false, type_name_atom, is_type_name);
610        } else if type_name_atom == type_name!("uvec2") {
611            return UVEC2.gate(version >= 130, false, type_name_atom, is_type_name);
612        } else if type_name_atom == type_name!("uvec3") {
613            return UVEC3.gate(version >= 130, false, type_name_atom, is_type_name);
614        } else if type_name_atom == type_name!("uvec4") {
615            return UVEC4.gate(version >= 130, false, type_name_atom, is_type_name);
616        } else if type_name_atom == type_name!("isampler1D") {
617            return ISAMPLER1D.gate(version >= 130, false, type_name_atom, is_type_name);
618        } else if type_name_atom == type_name!("isampler1DArray") {
619            return ISAMPLER1DARRAY.gate(version >= 130, false, type_name_atom, is_type_name);
620        } else if type_name_atom == type_name!("isampler2D") {
621            return ISAMPLER2D.gate(version >= 130, false, type_name_atom, is_type_name);
622        } else if type_name_atom == type_name!("isampler2DArray") {
623            return ISAMPLER2DARRAY.gate(version >= 130, false, type_name_atom, is_type_name);
624        } else if type_name_atom == type_name!("isampler3D") {
625            return ISAMPLER3D.gate(version >= 130, false, type_name_atom, is_type_name);
626        } else if type_name_atom == type_name!("isamplerCube") {
627            return ISAMPLERCUBE.gate(version >= 130, false, type_name_atom, is_type_name);
628        } else if type_name_atom == type_name!("sampler1DArray") {
629            return SAMPLER1DARRAY.gate(version >= 130, false, type_name_atom, is_type_name);
630        } else if type_name_atom == type_name!("sampler1DArrayShadow") {
631            return SAMPLER1DARRAYSHADOW.gate(version >= 130, false, type_name_atom, is_type_name);
632        } else if type_name_atom == type_name!("sampler2DArray") {
633            return SAMPLER2DARRAY.gate(version >= 130, false, type_name_atom, is_type_name);
634        } else if type_name_atom == type_name!("sampler2DArrayShadow") {
635            return SAMPLER2DARRAYSHADOW.gate(version >= 130, false, type_name_atom, is_type_name);
636        } else if type_name_atom == type_name!("samplerCubeShadow") {
637            return SAMPLERCUBESHADOW.gate(version >= 130, false, type_name_atom, is_type_name);
638        } else if type_name_atom == type_name!("usampler1D") {
639            return USAMPLER1D.gate(version >= 130, false, type_name_atom, is_type_name);
640        } else if type_name_atom == type_name!("usampler1DArray") {
641            return USAMPLER1DARRAY.gate(version >= 130, false, type_name_atom, is_type_name);
642        } else if type_name_atom == type_name!("usampler2D") {
643            return USAMPLER2D.gate(version >= 130, false, type_name_atom, is_type_name);
644        } else if type_name_atom == type_name!("usampler2DArray") {
645            return USAMPLER2DARRAY.gate(version >= 130, false, type_name_atom, is_type_name);
646        } else if type_name_atom == type_name!("usampler3D") {
647            return USAMPLER3D.gate(version >= 130, false, type_name_atom, is_type_name);
648        } else if type_name_atom == type_name!("usamplerCube") {
649            return USAMPLERCUBE.gate(version >= 130, false, type_name_atom, is_type_name);
650        }
651
652        // 140 type names
653        if type_name_atom == type_name!("sampler2DRect") {
654            return SAMPLER2DRECT.gate(
655                version >= 140,
656                version >= 110,
657                type_name_atom,
658                is_type_name,
659            );
660        } else if type_name_atom == type_name!("sampler2DRectShadow") {
661            return SAMPLER2DRECTSHADOW.gate(
662                version >= 140,
663                version >= 110,
664                type_name_atom,
665                is_type_name,
666            );
667        } else if type_name_atom == type_name!("isampler2DRect") {
668            return ISAMPLER2DRECT.gate(version >= 140, false, type_name_atom, is_type_name);
669        } else if type_name_atom == type_name!("usampler2DRect") {
670            return USAMPLER2DRECT.gate(version >= 140, false, type_name_atom, is_type_name);
671        } else if type_name_atom == type_name!("samplerBuffer") {
672            return SAMPLERBUFFER.gate(version >= 140, false, type_name_atom, is_type_name);
673        } else if type_name_atom == type_name!("isamplerBuffer") {
674            return ISAMPLERBUFFER.gate(version >= 140, false, type_name_atom, is_type_name);
675        } else if type_name_atom == type_name!("usamplerBuffer") {
676            return USAMPLERBUFFER.gate(version >= 140, false, type_name_atom, is_type_name);
677        }
678
679        // 150 type names
680        if type_name_atom == type_name!("sampler2DMS") {
681            return SAMPLER2DMS.gate(version >= 150, false, type_name_atom, is_type_name);
682        } else if type_name_atom == type_name!("isampler2DMS") {
683            return ISAMPLER2DMS.gate(version >= 150, false, type_name_atom, is_type_name);
684        } else if type_name_atom == type_name!("usampler2DMS") {
685            return USAMPLER2DMS.gate(version >= 150, false, type_name_atom, is_type_name);
686        } else if type_name_atom == type_name!("sampler2DMSArray") {
687            return SAMPLER2DMSARRAY.gate(version >= 150, false, type_name_atom, is_type_name);
688        } else if type_name_atom == type_name!("isampler2DMSArray") {
689            return ISAMPLER2DMSARRAY.gate(version >= 150, false, type_name_atom, is_type_name);
690        } else if type_name_atom == type_name!("usampler2DMSArray") {
691            return USAMPLER2DMSARRAY.gate(version >= 150, false, type_name_atom, is_type_name);
692        }
693
694        // 400 type names
695        if type_name_atom == type_name!("double") {
696            return DOUBLE.gate(version >= 400, version >= 110, type_name_atom, is_type_name);
697        } else if type_name_atom == type_name!("dvec2") {
698            return DVEC2.gate(version >= 400, false, type_name_atom, is_type_name);
699        } else if type_name_atom == type_name!("dvec3") {
700            return DVEC3.gate(version >= 400, false, type_name_atom, is_type_name);
701        } else if type_name_atom == type_name!("dvec4") {
702            return DVEC4.gate(version >= 400, false, type_name_atom, is_type_name);
703        } else if type_name_atom == type_name!("dmat2") {
704            return DMAT2.gate(version >= 400, false, type_name_atom, is_type_name);
705        } else if type_name_atom == type_name!("dmat3") {
706            return DMAT3.gate(version >= 400, false, type_name_atom, is_type_name);
707        } else if type_name_atom == type_name!("dmat4") {
708            return DMAT4.gate(version >= 400, false, type_name_atom, is_type_name);
709        } else if type_name_atom == type_name!("dmat2x2") {
710            return DMAT2X2.gate(version >= 400, false, type_name_atom, is_type_name);
711        } else if type_name_atom == type_name!("dmat2x3") {
712            return DMAT2X3.gate(version >= 400, false, type_name_atom, is_type_name);
713        } else if type_name_atom == type_name!("dmat2x4") {
714            return DMAT2X4.gate(version >= 400, false, type_name_atom, is_type_name);
715        } else if type_name_atom == type_name!("dmat3x2") {
716            return DMAT3X2.gate(version >= 400, false, type_name_atom, is_type_name);
717        } else if type_name_atom == type_name!("dmat3x3") {
718            return DMAT3X3.gate(version >= 400, false, type_name_atom, is_type_name);
719        } else if type_name_atom == type_name!("dmat3x4") {
720            return DMAT3X4.gate(version >= 400, false, type_name_atom, is_type_name);
721        } else if type_name_atom == type_name!("dmat4x2") {
722            return DMAT4X2.gate(version >= 400, false, type_name_atom, is_type_name);
723        } else if type_name_atom == type_name!("dmat4x3") {
724            return DMAT4X3.gate(version >= 400, false, type_name_atom, is_type_name);
725        } else if type_name_atom == type_name!("dmat4x4") {
726            return DMAT4X4.gate(version >= 400, false, type_name_atom, is_type_name);
727        } else if type_name_atom == type_name!("samplerCubeArray") {
728            return SAMPLERCUBEARRAY.gate(version >= 400, false, type_name_atom, is_type_name);
729        } else if type_name_atom == type_name!("samplerCubeArrayShadow") {
730            return SAMPLERCUBEARRAYSHADOW.gate(
731                version >= 400,
732                false,
733                type_name_atom,
734                is_type_name,
735            );
736        } else if type_name_atom == type_name!("isamplerCubeArray") {
737            return ISAMPLERCUBEARRAY.gate(version >= 400, false, type_name_atom, is_type_name);
738        } else if type_name_atom == type_name!("usamplerCubeArray") {
739            return USAMPLERCUBEARRAY.gate(version >= 400, false, type_name_atom, is_type_name);
740        }
741
742        // 420 type names
743        if type_name_atom == type_name!("atomic_uint") {
744            return ATOMIC_UINT.gate(version >= 420, false, type_name_atom, is_type_name);
745        } else if type_name_atom == type_name!("image1D") {
746            return IMAGE1D.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
747        } else if type_name_atom == type_name!("iimage1D") {
748            return IIMAGE1D.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
749        } else if type_name_atom == type_name!("uimage1D") {
750            return UIMAGE1D.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
751        } else if type_name_atom == type_name!("image1DArray") {
752            return IMAGE1DARRAY.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
753        } else if type_name_atom == type_name!("iimage1DArray") {
754            return IIMAGE1DARRAY.gate(
755                version >= 420,
756                version >= 130,
757                type_name_atom,
758                is_type_name,
759            );
760        } else if type_name_atom == type_name!("uimage1DArray") {
761            return UIMAGE1DARRAY.gate(
762                version >= 420,
763                version >= 130,
764                type_name_atom,
765                is_type_name,
766            );
767        } else if type_name_atom == type_name!("image2D") {
768            return IMAGE2D.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
769        } else if type_name_atom == type_name!("iimage2D") {
770            return IIMAGE2D.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
771        } else if type_name_atom == type_name!("uimage2D") {
772            return UIMAGE2D.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
773        } else if type_name_atom == type_name!("image2DArray") {
774            return IMAGE2DARRAY.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
775        } else if type_name_atom == type_name!("iimage2DArray") {
776            return IIMAGE2DARRAY.gate(
777                version >= 420,
778                version >= 130,
779                type_name_atom,
780                is_type_name,
781            );
782        } else if type_name_atom == type_name!("uimage2DArray") {
783            return UIMAGE2DARRAY.gate(
784                version >= 420,
785                version >= 130,
786                type_name_atom,
787                is_type_name,
788            );
789        } else if type_name_atom == type_name!("image2DRect") {
790            return IMAGE2DRECT.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
791        } else if type_name_atom == type_name!("iimage2DRect") {
792            return IIMAGE2DRECT.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
793        } else if type_name_atom == type_name!("uimage2DRect") {
794            return UIMAGE2DRECT.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
795        } else if type_name_atom == type_name!("image2DMS") {
796            return IMAGE2DMS.gate(version >= 420, false, type_name_atom, is_type_name);
797        } else if type_name_atom == type_name!("iimage2DMS") {
798            return IIMAGE2DMS.gate(version >= 420, false, type_name_atom, is_type_name);
799        } else if type_name_atom == type_name!("uimage2DMS") {
800            return UIMAGE2DMS.gate(version >= 420, false, type_name_atom, is_type_name);
801        } else if type_name_atom == type_name!("image2DMSArray") {
802            return IMAGE2DMSARRAY.gate(version >= 420, false, type_name_atom, is_type_name);
803        } else if type_name_atom == type_name!("iimage2DMSArray") {
804            return IIMAGE2DMSARRAY.gate(version >= 420, false, type_name_atom, is_type_name);
805        } else if type_name_atom == type_name!("uimage2DMSArray") {
806            return UIMAGE2DMSARRAY.gate(version >= 420, false, type_name_atom, is_type_name);
807        } else if type_name_atom == type_name!("image3D") {
808            return IMAGE3D.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
809        } else if type_name_atom == type_name!("iimage3D") {
810            return IIMAGE3D.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
811        } else if type_name_atom == type_name!("uimage3D") {
812            return UIMAGE3D.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
813        } else if type_name_atom == type_name!("imageCube") {
814            return IMAGECUBE.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
815        } else if type_name_atom == type_name!("iimageCube") {
816            return IIMAGECUBE.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
817        } else if type_name_atom == type_name!("uimageCube") {
818            return UIMAGECUBE.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
819        } else if type_name_atom == type_name!("imageCubeArray") {
820            return IMAGECUBEARRAY.gate(
821                version >= 420,
822                version >= 130,
823                type_name_atom,
824                is_type_name,
825            );
826        } else if type_name_atom == type_name!("iimageCubeArray") {
827            return IIMAGECUBEARRAY.gate(
828                version >= 420,
829                version >= 130,
830                type_name_atom,
831                is_type_name,
832            );
833        } else if type_name_atom == type_name!("uimageCubeArray") {
834            return UIMAGECUBEARRAY.gate(
835                version >= 420,
836                version >= 130,
837                type_name_atom,
838                is_type_name,
839            );
840        } else if type_name_atom == type_name!("imageBuffer") {
841            return IMAGEBUFFER.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
842        } else if type_name_atom == type_name!("iimageBuffer") {
843            return IIMAGEBUFFER.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
844        } else if type_name_atom == type_name!("uimageBuffer") {
845            return UIMAGEBUFFER.gate(version >= 420, version >= 130, type_name_atom, is_type_name);
846        }
847
848        // Vulkan type names
849        if type_name_atom == type_name!("texture1D") {
850            return TEXTURE1D.gate(
851                version >= 460 && target_vulkan,
852                false,
853                type_name_atom,
854                is_type_name,
855            );
856        } else if type_name_atom == type_name!("texture1DArray") {
857            return TEXTURE1DARRAY.gate(
858                version >= 460 && target_vulkan,
859                false,
860                type_name_atom,
861                is_type_name,
862            );
863        } else if type_name_atom == type_name!("itexture1D") {
864            return ITEXTURE1D.gate(
865                version >= 460 && target_vulkan,
866                false,
867                type_name_atom,
868                is_type_name,
869            );
870        } else if type_name_atom == type_name!("itexture1DArray") {
871            return ITEXTURE1DARRAY.gate(
872                version >= 460 && target_vulkan,
873                false,
874                type_name_atom,
875                is_type_name,
876            );
877        } else if type_name_atom == type_name!("utexture1D") {
878            return UTEXTURE1D.gate(
879                version >= 460 && target_vulkan,
880                false,
881                type_name_atom,
882                is_type_name,
883            );
884        } else if type_name_atom == type_name!("utexture1DArray") {
885            return UTEXTURE1DARRAY.gate(
886                version >= 460 && target_vulkan,
887                false,
888                type_name_atom,
889                is_type_name,
890            );
891        } else if type_name_atom == type_name!("texture2D") {
892            return TEXTURE2D.gate(
893                version >= 460 && target_vulkan,
894                false,
895                type_name_atom,
896                is_type_name,
897            );
898        } else if type_name_atom == type_name!("texture2DArray") {
899            return TEXTURE2DARRAY.gate(
900                version >= 460 && target_vulkan,
901                false,
902                type_name_atom,
903                is_type_name,
904            );
905        } else if type_name_atom == type_name!("itexture2D") {
906            return ITEXTURE2D.gate(
907                version >= 460 && target_vulkan,
908                false,
909                type_name_atom,
910                is_type_name,
911            );
912        } else if type_name_atom == type_name!("itexture2DArray") {
913            return ITEXTURE2DARRAY.gate(
914                version >= 460 && target_vulkan,
915                false,
916                type_name_atom,
917                is_type_name,
918            );
919        } else if type_name_atom == type_name!("utexture2D") {
920            return UTEXTURE2D.gate(
921                version >= 460 && target_vulkan,
922                false,
923                type_name_atom,
924                is_type_name,
925            );
926        } else if type_name_atom == type_name!("utexture2DArray") {
927            return UTEXTURE2DARRAY.gate(
928                version >= 460 && target_vulkan,
929                false,
930                type_name_atom,
931                is_type_name,
932            );
933        } else if type_name_atom == type_name!("texture2DRect") {
934            return TEXTURE2DRECT.gate(
935                version >= 460 && target_vulkan,
936                false,
937                type_name_atom,
938                is_type_name,
939            );
940        } else if type_name_atom == type_name!("itexture2DRect") {
941            return ITEXTURE2DRECT.gate(
942                version >= 460 && target_vulkan,
943                false,
944                type_name_atom,
945                is_type_name,
946            );
947        } else if type_name_atom == type_name!("utexture2DRect") {
948            return UTEXTURE2DRECT.gate(
949                version >= 460 && target_vulkan,
950                false,
951                type_name_atom,
952                is_type_name,
953            );
954        } else if type_name_atom == type_name!("texture2DMS") {
955            return TEXTURE2DMS.gate(
956                version >= 460 && target_vulkan,
957                false,
958                type_name_atom,
959                is_type_name,
960            );
961        } else if type_name_atom == type_name!("itexture2DMS") {
962            return ITEXTURE2DMS.gate(
963                version >= 460 && target_vulkan,
964                false,
965                type_name_atom,
966                is_type_name,
967            );
968        } else if type_name_atom == type_name!("utexture2DMS") {
969            return UTEXTURE2DMS.gate(
970                version >= 460 && target_vulkan,
971                false,
972                type_name_atom,
973                is_type_name,
974            );
975        } else if type_name_atom == type_name!("texture2DMSArray") {
976            return TEXTURE2DMSARRAY.gate(
977                version >= 460 && target_vulkan,
978                false,
979                type_name_atom,
980                is_type_name,
981            );
982        } else if type_name_atom == type_name!("itexture2DMSArray") {
983            return ITEXTURE2DMSARRAY.gate(
984                version >= 460 && target_vulkan,
985                false,
986                type_name_atom,
987                is_type_name,
988            );
989        } else if type_name_atom == type_name!("utexture2DMSArray") {
990            return UTEXTURE2DMSARRAY.gate(
991                version >= 460 && target_vulkan,
992                false,
993                type_name_atom,
994                is_type_name,
995            );
996        } else if type_name_atom == type_name!("texture3D") {
997            return TEXTURE3D.gate(
998                version >= 460 && target_vulkan,
999                false,
1000                type_name_atom,
1001                is_type_name,
1002            );
1003        } else if type_name_atom == type_name!("itexture3D") {
1004            return ITEXTURE3D.gate(
1005                version >= 460 && target_vulkan,
1006                false,
1007                type_name_atom,
1008                is_type_name,
1009            );
1010        } else if type_name_atom == type_name!("utexture3D") {
1011            return UTEXTURE3D.gate(
1012                version >= 460 && target_vulkan,
1013                false,
1014                type_name_atom,
1015                is_type_name,
1016            );
1017        } else if type_name_atom == type_name!("textureCube") {
1018            return TEXTURECUBE.gate(
1019                version >= 460 && target_vulkan,
1020                false,
1021                type_name_atom,
1022                is_type_name,
1023            );
1024        } else if type_name_atom == type_name!("itextureCube") {
1025            return ITEXTURECUBE.gate(
1026                version >= 460 && target_vulkan,
1027                false,
1028                type_name_atom,
1029                is_type_name,
1030            );
1031        } else if type_name_atom == type_name!("utextureCube") {
1032            return UTEXTURECUBE.gate(
1033                version >= 460 && target_vulkan,
1034                false,
1035                type_name_atom,
1036                is_type_name,
1037            );
1038        } else if type_name_atom == type_name!("textureCubeArray") {
1039            return TEXTURECUBEARRAY.gate(
1040                version >= 460 && target_vulkan,
1041                false,
1042                type_name_atom,
1043                is_type_name,
1044            );
1045        } else if type_name_atom == type_name!("itextureCubeArray") {
1046            return ITEXTURECUBEARRAY.gate(
1047                version >= 460 && target_vulkan,
1048                false,
1049                type_name_atom,
1050                is_type_name,
1051            );
1052        } else if type_name_atom == type_name!("utextureCubeArray") {
1053            return UTEXTURECUBEARRAY.gate(
1054                version >= 460 && target_vulkan,
1055                false,
1056                type_name_atom,
1057                is_type_name,
1058            );
1059        } else if type_name_atom == type_name!("textureBuffer") {
1060            return TEXTUREBUFFER.gate(
1061                version >= 460 && target_vulkan,
1062                false,
1063                type_name_atom,
1064                is_type_name,
1065            );
1066        } else if type_name_atom == type_name!("itextureBuffer") {
1067            return ITEXTUREBUFFER.gate(
1068                version >= 460 && target_vulkan,
1069                false,
1070                type_name_atom,
1071                is_type_name,
1072            );
1073        } else if type_name_atom == type_name!("utextureBuffer") {
1074            return UTEXTUREBUFFER.gate(
1075                version >= 460 && target_vulkan,
1076                false,
1077                type_name_atom,
1078                is_type_name,
1079            );
1080        } else if type_name_atom == type_name!("sampler") {
1081            return SAMPLER.gate(
1082                version >= 460 && target_vulkan,
1083                false,
1084                type_name_atom,
1085                is_type_name,
1086            );
1087        } else if type_name_atom == type_name!("samplerShadow") {
1088            return SAMPLERSHADOW.gate(
1089                version >= 460 && target_vulkan,
1090                false,
1091                type_name_atom,
1092                is_type_name,
1093            );
1094        } else if type_name_atom == type_name!("subpassInput") {
1095            return SUBPASSINPUT.gate(
1096                version >= 460 && target_vulkan,
1097                false,
1098                type_name_atom,
1099                is_type_name,
1100            );
1101        } else if type_name_atom == type_name!("isubpassInput") {
1102            return ISUBPASSINPUT.gate(
1103                version >= 460 && target_vulkan,
1104                false,
1105                type_name_atom,
1106                is_type_name,
1107            );
1108        } else if type_name_atom == type_name!("usubpassInput") {
1109            return USUBPASSINPUT.gate(
1110                version >= 460 && target_vulkan,
1111                false,
1112                type_name_atom,
1113                is_type_name,
1114            );
1115        } else if type_name_atom == type_name!("subpassInputMS") {
1116            return SUBPASSINPUTMS.gate(
1117                version >= 460 && target_vulkan,
1118                false,
1119                type_name_atom,
1120                is_type_name,
1121            );
1122        } else if type_name_atom == type_name!("isubpassInputMS") {
1123            return ISUBPASSINPUTMS.gate(
1124                version >= 460 && target_vulkan,
1125                false,
1126                type_name_atom,
1127                is_type_name,
1128            );
1129        } else if type_name_atom == type_name!("usubpassInputMS") {
1130            return USUBPASSINPUTMS.gate(
1131                version >= 460 && target_vulkan,
1132                false,
1133                type_name_atom,
1134                is_type_name,
1135            );
1136        }
1137
1138        // Reserved for future use
1139        if type_name_atom == type_name!("hvec2")
1140            || type_name_atom == type_name!("hvec3")
1141            || type_name_atom == type_name!("hvec4")
1142            || type_name_atom == type_name!("fvec2")
1143            || type_name_atom == type_name!("fvec3")
1144            || type_name_atom == type_name!("fvec4")
1145            || type_name_atom == type_name!("sampler3DRect")
1146        {
1147            return Some((RESERVED(type_name_atom), None));
1148        }
1149
1150        let result = is_type_name(&type_name_atom);
1151        if result.is_type_name() {
1152            return Some((OTHER(type_name_atom), Some(result)));
1153        }
1154
1155        None
1156    }
1157}
1158
1159#[derive(Debug, Clone, PartialEq, PartialOrd, lang_util::Token)]
1160#[allow(non_camel_case_types)]
1161pub enum Token {
1162    /// Identifier
1163    #[lang_util(parser = "IDENT", kind = "identifier")]
1164    IDENT(SmolStr),
1165    /// Type name
1166    #[lang_util(parser = "TYPE_NAME", kind = "type name")]
1167    TYPE_NAME(TypeName),
1168    /// Float constant
1169    #[lang_util(parser = "FLOAT_CONST", kind = "float constant", kind = "literal")]
1170    FLOAT_CONST(f32),
1171    /// Int constant
1172    #[lang_util(parser = "INT_CONST", kind = "int constant", kind = "literal")]
1173    INT_CONST(i32),
1174    /// Unsigned int constant
1175    #[lang_util(parser = "UINT_CONST", kind = "uint constant", kind = "literal")]
1176    UINT_CONST(u32),
1177    /// Bool constant
1178    #[lang_util(parser = "BOOL_CONST", kind = "bool constant", kind = "literal")]
1179    BOOL_CONST(bool),
1180    /// Double constant
1181    #[lang_util(parser = "DOUBLE_CONST", kind = "double constant", kind = "literal")]
1182    DOUBLE_CONST(f64),
1183    // Multi-char tokens
1184    /// <<
1185    #[lang_util(token = "<<", kind = "binary operator", kind = "operator")]
1186    LEFT_OP,
1187    /// >>
1188    #[lang_util(token = ">>", kind = "binary operator", kind = "operator")]
1189    RIGHT_OP,
1190    /// ++
1191    #[lang_util(token = "++", kind = "unary operator", kind = "operator")]
1192    INC_OP,
1193    /// --
1194    #[lang_util(token = "--", kind = "unary operator", kind = "operator")]
1195    DEC_OP,
1196    /// <=
1197    #[lang_util(token = "<=", kind = "binary operator", kind = "operator")]
1198    LE_OP,
1199    /// >=
1200    #[lang_util(token = ">=", kind = "binary operator", kind = "operator")]
1201    GE_OP,
1202    /// ==
1203    #[lang_util(token = "==", kind = "binary operator", kind = "operator")]
1204    EQ_OP,
1205    /// !=
1206    #[lang_util(token = "!=", kind = "binary operator", kind = "operator")]
1207    NE_OP,
1208    /// &&
1209    #[lang_util(token = "&&", kind = "binary operator", kind = "operator")]
1210    AND_OP,
1211    /// ||
1212    #[lang_util(token = "||", kind = "binary operator", kind = "operator")]
1213    OR_OP,
1214    /// ^^
1215    #[lang_util(token = "^^", kind = "binary operator", kind = "operator")]
1216    XOR_OP,
1217    /// *=
1218    #[lang_util(token = "*=", kind = "binary operator", kind = "operator")]
1219    MUL_ASSIGN,
1220    /// /=
1221    #[lang_util(token = "/=", kind = "binary operator", kind = "operator")]
1222    DIV_ASSIGN,
1223    /// +=
1224    #[lang_util(token = "+=", kind = "binary operator", kind = "operator")]
1225    ADD_ASSIGN,
1226    /// %=
1227    #[lang_util(token = "%=", kind = "binary operator", kind = "operator")]
1228    MOD_ASSIGN,
1229    /// <<=
1230    #[lang_util(token = "<<=", kind = "binary operator", kind = "operator")]
1231    LEFT_ASSIGN,
1232    /// >>=
1233    #[lang_util(token = ">>=", kind = "binary operator", kind = "operator")]
1234    RIGHT_ASSIGN,
1235    /// &=
1236    #[lang_util(token = "&=", kind = "binary operator", kind = "operator")]
1237    AND_ASSIGN,
1238    /// ^=
1239    #[lang_util(token = "^=", kind = "binary operator", kind = "operator")]
1240    XOR_ASSIGN,
1241    /// |=
1242    #[lang_util(token = "|=", kind = "binary operator", kind = "operator")]
1243    OR_ASSIGN,
1244    /// -=
1245    #[lang_util(token = "-=", kind = "binary operator", kind = "operator")]
1246    SUB_ASSIGN,
1247    // Single-char tokens
1248    /// (
1249    #[lang_util(token = "(")]
1250    LPAREN,
1251    /// )
1252    #[lang_util(token = ")")]
1253    RPAREN,
1254    /// [
1255    #[lang_util(token = "[")]
1256    LBRACKET,
1257    /// ]
1258    #[lang_util(token = "]")]
1259    RBRACKET,
1260    /// {
1261    #[lang_util(token = "{")]
1262    LBRACE,
1263    /// }
1264    #[lang_util(token = "}")]
1265    RBRACE,
1266    /// .
1267    #[lang_util(token = ".", kind = "binary operator", kind = "operator")]
1268    PERIOD,
1269    /// ,
1270    #[lang_util(token = ",", kind = "operator")]
1271    COMMA,
1272    /// :
1273    #[lang_util(token = ":", kind = "operator")]
1274    COLON,
1275    /// =
1276    #[lang_util(token = "=", kind = "binary operator", kind = "operator")]
1277    EQUAL,
1278    /// ;
1279    #[lang_util(token = ";")]
1280    SEMICOLON,
1281    /// !
1282    #[lang_util(token = "!", kind = "unary operator", kind = "operator")]
1283    BANG,
1284    /// -
1285    #[lang_util(
1286        token = "-",
1287        kind = "binary operator",
1288        kind = "unary operator",
1289        kind = "operator"
1290    )]
1291    DASH,
1292    /// ~
1293    #[lang_util(token = "~", kind = "unary operator", kind = "operator")]
1294    TILDE,
1295    /// +
1296    #[lang_util(
1297        token = "+",
1298        kind = "binary operator",
1299        kind = "unary operator",
1300        kind = "operator"
1301    )]
1302    PLUS,
1303    /// *
1304    #[lang_util(token = "*", kind = "binary operator", kind = "operator")]
1305    ASTERISK,
1306    /// /
1307    #[lang_util(token = "/", kind = "binary operator", kind = "operator")]
1308    SLASH,
1309    /// %
1310    #[lang_util(token = "%", kind = "binary operator", kind = "operator")]
1311    PERCENT,
1312    /// <
1313    #[lang_util(token = "<", kind = "binary operator", kind = "operator")]
1314    LANGLE,
1315    /// >
1316    #[lang_util(token = ">", kind = "binary operator", kind = "operator")]
1317    RANGLE,
1318    /// |
1319    #[lang_util(token = "|", kind = "binary operator", kind = "operator")]
1320    BAR,
1321    /// ^
1322    #[lang_util(token = "^", kind = "binary operator", kind = "operator")]
1323    CARET,
1324    /// &
1325    #[lang_util(token = "&", kind = "binary operator", kind = "operator")]
1326    AMPERSAND,
1327    /// ?
1328    #[lang_util(token = "?", kind = "operator")]
1329    QUESTION,
1330    /// #
1331    #[lang_util(token = "#")]
1332    HASH,
1333    // Keywords
1334    /// "const"
1335    #[lang_util(token = "const", kind = "storage qualifier", kind = "type qualifier")]
1336    CONST,
1337    /// "uniform"
1338    #[lang_util(token = "uniform", kind = "storage qualifier", kind = "type qualifier")]
1339    UNIFORM,
1340    /// "buffer"
1341    #[lang_util(token = "buffer", kind = "storage qualifier", kind = "type qualifier")]
1342    BUFFER,
1343    /// "shared"
1344    #[lang_util(token = "shared", kind = "storage qualifier", kind = "type qualifier")]
1345    SHARED,
1346    /// "attribute"
1347    #[lang_util(
1348        token = "attribute",
1349        kind = "storage qualifier",
1350        kind = "type qualifier"
1351    )]
1352    ATTRIBUTE,
1353    /// "varying"
1354    #[lang_util(token = "varying", kind = "storage qualifier", kind = "type qualifier")]
1355    VARYING,
1356    /// "coherent"
1357    #[lang_util(
1358        token = "coherent",
1359        kind = "storage qualifier",
1360        kind = "type qualifier"
1361    )]
1362    COHERENT,
1363    /// "volatile"
1364    #[lang_util(
1365        token = "volatile",
1366        kind = "storage qualifier",
1367        kind = "type qualifier"
1368    )]
1369    VOLATILE,
1370    /// "restrict"
1371    #[lang_util(
1372        token = "restrict",
1373        kind = "storage qualifier",
1374        kind = "type qualifier"
1375    )]
1376    RESTRICT,
1377    /// "readonly"
1378    #[lang_util(
1379        token = "readonly",
1380        kind = "storage qualifier",
1381        kind = "type qualifier"
1382    )]
1383    READONLY,
1384    /// "writeonly"
1385    #[lang_util(
1386        token = "writeonly",
1387        kind = "storage qualifier",
1388        kind = "type qualifier"
1389    )]
1390    WRITEONLY,
1391    /// "layout"
1392    #[lang_util(token = "layout", kind = "layout qualifier", kind = "type qualifier")]
1393    LAYOUT,
1394    /// "centroid"
1395    #[lang_util(
1396        token = "centroid",
1397        kind = "storage qualifier",
1398        kind = "type qualifier"
1399    )]
1400    CENTROID,
1401    /// "flat"
1402    #[lang_util(
1403        token = "flat",
1404        kind = "interpolation qualifier",
1405        kind = "type qualifier"
1406    )]
1407    FLAT,
1408    /// "smooth"
1409    #[lang_util(
1410        token = "smooth",
1411        kind = "interpolation qualifier",
1412        kind = "type qualifier"
1413    )]
1414    SMOOTH,
1415    /// "noperspective"
1416    #[lang_util(
1417        token = "noperspective",
1418        kind = "interpolation qualifier",
1419        kind = "type qualifier"
1420    )]
1421    NOPERSPECTIVE,
1422    /// "patch"
1423    #[lang_util(token = "patch", kind = "storage qualifier", kind = "type qualifier")]
1424    PATCH,
1425    /// "sample"
1426    #[lang_util(token = "sample", kind = "storage qualifier", kind = "type qualifier")]
1427    SAMPLE,
1428    /// "invariant"
1429    #[lang_util(token = "invariant", kind = "type qualifier")]
1430    INVARIANT,
1431    /// "precise"
1432    #[lang_util(token = "precise", kind = "type qualifier")]
1433    PRECISE,
1434    /// "break"
1435    #[lang_util(token = "break", kind = "keyword")]
1436    BREAK,
1437    /// "continue"
1438    #[lang_util(token = "continue", kind = "keyword")]
1439    CONTINUE,
1440    /// "do"
1441    #[lang_util(token = "do", kind = "keyword")]
1442    DO,
1443    /// "for"
1444    #[lang_util(token = "for", kind = "keyword")]
1445    FOR,
1446    /// "while"
1447    #[lang_util(token = "while", kind = "keyword")]
1448    WHILE,
1449    /// "switch"
1450    #[lang_util(token = "switch", kind = "keyword")]
1451    SWITCH,
1452    /// "case"
1453    #[lang_util(token = "case", kind = "keyword")]
1454    CASE,
1455    /// "default"
1456    #[lang_util(token = "default", kind = "keyword")]
1457    DEFAULT,
1458    /// "if"
1459    #[lang_util(token = "if", kind = "keyword")]
1460    IF,
1461    /// "else"
1462    #[lang_util(token = "else", kind = "keyword")]
1463    ELSE,
1464    /// "subroutine"
1465    #[lang_util(
1466        token = "subroutine",
1467        kind = "storage qualifier",
1468        kind = "type qualifier"
1469    )]
1470    SUBROUTINE,
1471    /// "in"
1472    #[lang_util(token = "in", kind = "storage qualifier", kind = "type qualifier")]
1473    IN,
1474    /// "out"
1475    #[lang_util(token = "out", kind = "storage qualifier", kind = "type qualifier")]
1476    OUT,
1477    /// "inout"
1478    #[lang_util(token = "inout", kind = "storage qualifier", kind = "type qualifier")]
1479    INOUT,
1480    /// "discard"
1481    #[lang_util(token = "discard", kind = "keyword")]
1482    DISCARD,
1483    /// "return"
1484    #[lang_util(token = "return", kind = "keyword")]
1485    RETURN,
1486    /// "lowp"
1487    #[lang_util(token = "lowp", kind = "precision qualifier", kind = "type qualifier")]
1488    LOWP,
1489    /// "mediump"
1490    #[lang_util(
1491        token = "mediump",
1492        kind = "precision qualifier",
1493        kind = "type qualifier"
1494    )]
1495    MEDIUMP,
1496    /// "highp"
1497    #[lang_util(token = "highp", kind = "precision qualifier", kind = "type qualifier")]
1498    HIGHP,
1499    /// "precision"
1500    #[lang_util(token = "precision")]
1501    PRECISION,
1502    /// "struct"
1503    #[lang_util(token = "struct", kind = "struct", kind = "keyword")]
1504    STRUCT,
1505    // Reserved for future use
1506    /// "common"
1507    #[lang_util(token = "common", kind = "reserved keyword")]
1508    COMMON,
1509    /// "partition"
1510    #[lang_util(token = "partition", kind = "reserved keyword")]
1511    PARTITION,
1512    /// "active"
1513    #[lang_util(token = "active", kind = "reserved keyword")]
1514    ACTIVE,
1515    /// "asm"
1516    #[lang_util(token = "asm", kind = "reserved keyword")]
1517    ASM,
1518    /// "class"
1519    #[lang_util(token = "class", kind = "reserved keyword")]
1520    CLASS,
1521    /// "union"
1522    #[lang_util(token = "union", kind = "reserved keyword")]
1523    UNION,
1524    /// "enum"
1525    #[lang_util(token = "enum", kind = "reserved keyword")]
1526    ENUM,
1527    /// "typedef"
1528    #[lang_util(token = "typedef", kind = "reserved keyword")]
1529    TYPEDEF,
1530    /// "template"
1531    #[lang_util(token = "template", kind = "reserved keyword")]
1532    TEMPLATE,
1533    /// "this"
1534    #[lang_util(token = "this", kind = "reserved keyword")]
1535    THIS,
1536    /// "resource"
1537    #[lang_util(token = "resource", kind = "reserved keyword")]
1538    RESOURCE,
1539    /// "goto"
1540    #[lang_util(token = "goto", kind = "reserved keyword")]
1541    GOTO,
1542    /// "inline"
1543    #[lang_util(token = "inline", kind = "reserved keyword")]
1544    INLINE,
1545    /// "noinline"
1546    #[lang_util(token = "noinline", kind = "reserved keyword")]
1547    NOINLINE,
1548    /// "public"
1549    #[lang_util(token = "public", kind = "reserved keyword")]
1550    PUBLIC,
1551    /// "static"
1552    #[lang_util(token = "static", kind = "reserved keyword")]
1553    STATIC,
1554    /// "extern"
1555    #[lang_util(token = "extern", kind = "reserved keyword")]
1556    EXTERN,
1557    /// "external"
1558    #[lang_util(token = "external", kind = "reserved keyword")]
1559    EXTERNAL,
1560    /// "interface"
1561    #[lang_util(token = "interface", kind = "reserved keyword")]
1562    INTERFACE,
1563    /// "long"
1564    #[lang_util(token = "long", kind = "reserved keyword")]
1565    LONG,
1566    /// "short"
1567    #[lang_util(token = "short", kind = "reserved keyword")]
1568    SHORT,
1569    /// "half"
1570    #[lang_util(token = "half", kind = "reserved keyword")]
1571    HALF,
1572    /// "fixed"
1573    #[lang_util(token = "fixed", kind = "reserved keyword")]
1574    FIXED,
1575    /// "unsigned"
1576    #[lang_util(token = "unsigned", kind = "reserved keyword")]
1577    UNSIGNED,
1578    /// "superp"
1579    #[lang_util(token = "superp", kind = "reserved keyword")]
1580    SUPERP,
1581    /// "input"
1582    #[lang_util(token = "input", kind = "reserved keyword")]
1583    INPUT,
1584    /// "output"
1585    #[lang_util(token = "output", kind = "reserved keyword")]
1586    OUTPUT,
1587    /// "filter"
1588    #[lang_util(token = "filter", kind = "reserved keyword")]
1589    FILTER,
1590    /// "sizeof"
1591    #[lang_util(token = "sizeof", kind = "reserved keyword")]
1592    SIZEOF,
1593    /// "cast"
1594    #[lang_util(token = "cast", kind = "reserved keyword")]
1595    CAST,
1596    /// "namespace"
1597    #[lang_util(token = "namespace", kind = "reserved keyword")]
1598    NAMESPACE,
1599    /// "using"
1600    #[lang_util(token = "using", kind = "reserved keyword")]
1601    USING,
1602    // Other
1603    /// Whitespaace
1604    #[lang_util(display = "<whitespace>", parser(display), kind = "trivia")]
1605    WS,
1606    /// Comment (single-line or multi-line)
1607    #[lang_util(display = "<comment>", parser(display), kind = "trivia")]
1608    COMMENT,
1609    /// Marker for invalid tokens
1610    #[lang_util(display = "<invalid token>", parser(display), kind = "error")]
1611    ERROR(ErrorKind),
1612}
1613
1614#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, derive_more::Display)]
1615pub enum ErrorKind {
1616    #[display("invalid token")]
1617    InvalidToken,
1618    #[display("invalid int literal")]
1619    InvalidIntLiteral,
1620    #[display("invalid uint literal")]
1621    InvalidUIntLiteral,
1622    #[display("invalid float literal")]
1623    InvalidFloatLiteral,
1624    #[display("invalid double literal")]
1625    InvalidDoubleLiteral,
1626}
1627
1628impl Token {
1629    pub fn from_token(
1630        token: lexer::TextToken,
1631        source: &str,
1632        version: u16,
1633        target_vulkan: bool,
1634        is_type_name: impl Fn(&TypeNameAtom) -> TypeNameState,
1635    ) -> (Token, Option<TypeNameState>) {
1636        use Token::*;
1637        let kind = &*token;
1638
1639        match kind {
1640            lexer::Token::IDENT_KW | lexer::Token::DIGITS => {}
1641            lexer::Token::PERIOD => {
1642                return (PERIOD, None);
1643            }
1644            lexer::Token::PLUS => {
1645                return (PLUS, None);
1646            }
1647            lexer::Token::DASH => {
1648                return (DASH, None);
1649            }
1650            lexer::Token::SLASH => {
1651                return (SLASH, None);
1652            }
1653            lexer::Token::ASTERISK => {
1654                return (ASTERISK, None);
1655            }
1656            lexer::Token::PERCENT => {
1657                return (PERCENT, None);
1658            }
1659            lexer::Token::LANGLE => {
1660                return (LANGLE, None);
1661            }
1662            lexer::Token::RANGLE => {
1663                return (RANGLE, None);
1664            }
1665            lexer::Token::LBRACKET => {
1666                return (LBRACKET, None);
1667            }
1668            lexer::Token::RBRACKET => {
1669                return (RBRACKET, None);
1670            }
1671            lexer::Token::LPAREN => {
1672                return (LPAREN, None);
1673            }
1674            lexer::Token::RPAREN => {
1675                return (RPAREN, None);
1676            }
1677            lexer::Token::LBRACE => {
1678                return (LBRACE, None);
1679            }
1680            lexer::Token::RBRACE => {
1681                return (RBRACE, None);
1682            }
1683            lexer::Token::CARET => {
1684                return (CARET, None);
1685            }
1686            lexer::Token::BAR => {
1687                return (BAR, None);
1688            }
1689            lexer::Token::AMPERSAND => {
1690                return (AMPERSAND, None);
1691            }
1692            lexer::Token::TILDE => {
1693                return (TILDE, None);
1694            }
1695            lexer::Token::EQUAL => {
1696                return (EQUAL, None);
1697            }
1698            lexer::Token::BANG => {
1699                return (BANG, None);
1700            }
1701            lexer::Token::COLON => {
1702                return (COLON, None);
1703            }
1704            lexer::Token::SEMICOLON => {
1705                return (SEMICOLON, None);
1706            }
1707            lexer::Token::COMMA => {
1708                return (COMMA, None);
1709            }
1710            lexer::Token::QUESTION => {
1711                return (QUESTION, None);
1712            }
1713            lexer::Token::HASH => {
1714                return (HASH, None);
1715            }
1716            lexer::Token::COMMENT => {
1717                return (COMMENT, None);
1718            }
1719            lexer::Token::LEFT_OP => {
1720                return (LEFT_OP, None);
1721            }
1722            lexer::Token::RIGHT_OP => {
1723                return (RIGHT_OP, None);
1724            }
1725            lexer::Token::INC_OP => {
1726                return (INC_OP, None);
1727            }
1728            lexer::Token::DEC_OP => {
1729                return (DEC_OP, None);
1730            }
1731            lexer::Token::LE_OP => {
1732                return (LE_OP, None);
1733            }
1734            lexer::Token::GE_OP => {
1735                return (GE_OP, None);
1736            }
1737            lexer::Token::EQ_OP => {
1738                return (EQ_OP, None);
1739            }
1740            lexer::Token::NE_OP => {
1741                return (NE_OP, None);
1742            }
1743            lexer::Token::AND_OP => {
1744                return (AND_OP, None);
1745            }
1746            lexer::Token::OR_OP => {
1747                return (OR_OP, None);
1748            }
1749            lexer::Token::XOR_OP => {
1750                return (XOR_OP, None);
1751            }
1752            lexer::Token::MUL_ASSIGN => {
1753                return (MUL_ASSIGN, None);
1754            }
1755            lexer::Token::DIV_ASSIGN => {
1756                return (DIV_ASSIGN, None);
1757            }
1758            lexer::Token::ADD_ASSIGN => {
1759                return (ADD_ASSIGN, None);
1760            }
1761            lexer::Token::MOD_ASSIGN => {
1762                return (MOD_ASSIGN, None);
1763            }
1764            lexer::Token::LEFT_ASSIGN => {
1765                return (LEFT_ASSIGN, None);
1766            }
1767            lexer::Token::RIGHT_ASSIGN => {
1768                return (RIGHT_ASSIGN, None);
1769            }
1770            lexer::Token::AND_ASSIGN => {
1771                return (AND_ASSIGN, None);
1772            }
1773            lexer::Token::XOR_ASSIGN => {
1774                return (XOR_ASSIGN, None);
1775            }
1776            lexer::Token::OR_ASSIGN => {
1777                return (OR_ASSIGN, None);
1778            }
1779            lexer::Token::SUB_ASSIGN => {
1780                return (SUB_ASSIGN, None);
1781            }
1782            lexer::Token::DEFINED
1783            | lexer::Token::LINECONT
1784            | lexer::Token::NEWLINE
1785            | lexer::Token::WS => {
1786                return (WS, None);
1787            }
1788            lexer::Token::QUOTE_STRING
1789            | lexer::Token::ANGLE_STRING
1790            | lexer::Token::BACKSLASH
1791            | lexer::Token::ERROR
1792            | lexer::Token::PP_CONCAT => {
1793                return (ERROR(ErrorKind::InvalidToken), None);
1794            }
1795        }
1796
1797        // Either IDENT_KW or DIGITS, we need to examine the text to know more
1798        let text = Unescaped::new(token.raw(source)).to_string();
1799        if *kind == lexer::Token::IDENT_KW {
1800            // Is this a keyword?
1801            let keyword_atom = KeywordAtom::from(text.as_ref());
1802
1803            if let Some(keyword) = Token::parse_kw(&keyword_atom) {
1804                return (keyword, None);
1805            }
1806
1807            // Else it might be a built-in type name
1808            if let Some((type_name, state)) =
1809                TypeName::parse(text.as_ref(), version, target_vulkan, is_type_name)
1810            {
1811                return (TYPE_NAME(type_name), state);
1812            }
1813
1814            // Nothing matched, it's actually an ident
1815            (IDENT(text.into()), None)
1816        } else if *kind == lexer::Token::DIGITS {
1817            (Token::parse_digits(&text), None)
1818        } else {
1819            unreachable!()
1820        }
1821    }
1822
1823    pub(crate) fn parse_kw(keyword_atom: &KeywordAtom) -> Option<Self> {
1824        use Token::*;
1825
1826        // Keywords
1827        // TODO: Only return keywords according to versions and extensions
1828        if *keyword_atom == keyword!("const") {
1829            Some(CONST)
1830        } else if *keyword_atom == keyword!("uniform") {
1831            Some(UNIFORM)
1832        } else if *keyword_atom == keyword!("buffer") {
1833            Some(BUFFER)
1834        } else if *keyword_atom == keyword!("shared") {
1835            Some(SHARED)
1836        } else if *keyword_atom == keyword!("attribute") {
1837            Some(ATTRIBUTE)
1838        } else if *keyword_atom == keyword!("varying") {
1839            Some(VARYING)
1840        } else if *keyword_atom == keyword!("coherent") {
1841            Some(COHERENT)
1842        } else if *keyword_atom == keyword!("volatile") {
1843            Some(VOLATILE)
1844        } else if *keyword_atom == keyword!("restrict") {
1845            Some(RESTRICT)
1846        } else if *keyword_atom == keyword!("readonly") {
1847            Some(READONLY)
1848        } else if *keyword_atom == keyword!("writeonly") {
1849            Some(WRITEONLY)
1850        } else if *keyword_atom == keyword!("layout") {
1851            Some(LAYOUT)
1852        } else if *keyword_atom == keyword!("centroid") {
1853            Some(CENTROID)
1854        } else if *keyword_atom == keyword!("flat") {
1855            Some(FLAT)
1856        } else if *keyword_atom == keyword!("smooth") {
1857            Some(SMOOTH)
1858        } else if *keyword_atom == keyword!("noperspective") {
1859            Some(NOPERSPECTIVE)
1860        } else if *keyword_atom == keyword!("patch") {
1861            Some(PATCH)
1862        } else if *keyword_atom == keyword!("sample") {
1863            Some(SAMPLE)
1864        } else if *keyword_atom == keyword!("invariant") {
1865            Some(INVARIANT)
1866        } else if *keyword_atom == keyword!("precise") {
1867            Some(PRECISE)
1868        } else if *keyword_atom == keyword!("break") {
1869            Some(BREAK)
1870        } else if *keyword_atom == keyword!("continue") {
1871            Some(CONTINUE)
1872        } else if *keyword_atom == keyword!("do") {
1873            Some(DO)
1874        } else if *keyword_atom == keyword!("for") {
1875            Some(FOR)
1876        } else if *keyword_atom == keyword!("while") {
1877            Some(WHILE)
1878        } else if *keyword_atom == keyword!("switch") {
1879            Some(SWITCH)
1880        } else if *keyword_atom == keyword!("case") {
1881            Some(CASE)
1882        } else if *keyword_atom == keyword!("default") {
1883            Some(DEFAULT)
1884        } else if *keyword_atom == keyword!("if") {
1885            Some(IF)
1886        } else if *keyword_atom == keyword!("else") {
1887            Some(ELSE)
1888        } else if *keyword_atom == keyword!("subroutine") {
1889            Some(SUBROUTINE)
1890        } else if *keyword_atom == keyword!("in") {
1891            Some(IN)
1892        } else if *keyword_atom == keyword!("out") {
1893            Some(OUT)
1894        } else if *keyword_atom == keyword!("inout") {
1895            Some(INOUT)
1896        } else if *keyword_atom == keyword!("true") {
1897            Some(BOOL_CONST(true))
1898        } else if *keyword_atom == keyword!("false") {
1899            Some(BOOL_CONST(false))
1900        } else if *keyword_atom == keyword!("discard") {
1901            Some(DISCARD)
1902        } else if *keyword_atom == keyword!("return") {
1903            Some(RETURN)
1904        } else if *keyword_atom == keyword!("lowp") {
1905            Some(LOWP)
1906        } else if *keyword_atom == keyword!("mediump") {
1907            Some(MEDIUMP)
1908        } else if *keyword_atom == keyword!("highp") {
1909            Some(HIGHP)
1910        } else if *keyword_atom == keyword!("precision") {
1911            Some(PRECISION)
1912        } else if *keyword_atom == keyword!("struct") {
1913            Some(STRUCT)
1914        }
1915        // Reserved for future use
1916        else if *keyword_atom == keyword!("common") {
1917            Some(COMMON)
1918        } else if *keyword_atom == keyword!("partition") {
1919            Some(PARTITION)
1920        } else if *keyword_atom == keyword!("active") {
1921            Some(ACTIVE)
1922        } else if *keyword_atom == keyword!("asm") {
1923            Some(ASM)
1924        } else if *keyword_atom == keyword!("class") {
1925            Some(CLASS)
1926        } else if *keyword_atom == keyword!("union") {
1927            Some(UNION)
1928        } else if *keyword_atom == keyword!("enum") {
1929            Some(ENUM)
1930        } else if *keyword_atom == keyword!("typedef") {
1931            Some(TYPEDEF)
1932        } else if *keyword_atom == keyword!("template") {
1933            Some(TEMPLATE)
1934        } else if *keyword_atom == keyword!("this") {
1935            Some(THIS)
1936        } else if *keyword_atom == keyword!("resource") {
1937            Some(RESOURCE)
1938        } else if *keyword_atom == keyword!("goto") {
1939            Some(GOTO)
1940        } else if *keyword_atom == keyword!("inline") {
1941            Some(INLINE)
1942        } else if *keyword_atom == keyword!("noinline") {
1943            Some(NOINLINE)
1944        } else if *keyword_atom == keyword!("public") {
1945            Some(PUBLIC)
1946        } else if *keyword_atom == keyword!("static") {
1947            Some(STATIC)
1948        } else if *keyword_atom == keyword!("extern") {
1949            Some(EXTERN)
1950        } else if *keyword_atom == keyword!("external") {
1951            Some(EXTERNAL)
1952        } else if *keyword_atom == keyword!("interface") {
1953            Some(INTERFACE)
1954        } else if *keyword_atom == keyword!("long") {
1955            Some(LONG)
1956        } else if *keyword_atom == keyword!("short") {
1957            Some(SHORT)
1958        } else if *keyword_atom == keyword!("half") {
1959            Some(HALF)
1960        } else if *keyword_atom == keyword!("fixed") {
1961            Some(FIXED)
1962        } else if *keyword_atom == keyword!("unsigned") {
1963            Some(UNSIGNED)
1964        } else if *keyword_atom == keyword!("superp") {
1965            Some(SUPERP)
1966        } else if *keyword_atom == keyword!("input") {
1967            Some(INPUT)
1968        } else if *keyword_atom == keyword!("output") {
1969            Some(OUTPUT)
1970        } else if *keyword_atom == keyword!("filter") {
1971            Some(FILTER)
1972        } else if *keyword_atom == keyword!("sizeof") {
1973            Some(SIZEOF)
1974        } else if *keyword_atom == keyword!("cast") {
1975            Some(CAST)
1976        } else if *keyword_atom == keyword!("namespace") {
1977            Some(NAMESPACE)
1978        } else if *keyword_atom == keyword!("using") {
1979            Some(USING)
1980        } else {
1981            None
1982        }
1983    }
1984
1985    fn strip_suffix(text: &str) -> (bool, &str) {
1986        if let Some(stripped) = text.strip_suffix(['u', 'U']) {
1987            (true, stripped)
1988        } else {
1989            (false, text)
1990        }
1991    }
1992
1993    fn parse_int(text: &str, radix: u32) -> Result<Self, ErrorKind> {
1994        use Token::*;
1995
1996        let (unsigned, text) = Self::strip_suffix(text);
1997
1998        // Hexadecimal constant
1999        if unsigned {
2000            if radix == 8 && text.is_empty() {
2001                Ok(UINT_CONST(0))
2002            } else {
2003                u32::from_str_radix(text, radix)
2004                    .map(UINT_CONST)
2005                    .map_err(|_| ErrorKind::InvalidUIntLiteral)
2006            }
2007        } else {
2008            i32::from_str_radix(text, radix)
2009                .map(INT_CONST)
2010                .map_err(|_| ErrorKind::InvalidIntLiteral)
2011        }
2012    }
2013
2014    pub(crate) fn parse_digits(text: &str) -> Self {
2015        use Token::*;
2016
2017        let hex_prefix = text.strip_prefix("0x").or_else(|| text.strip_prefix("0X"));
2018
2019        let result = if (text.ends_with('f')
2020            || text.ends_with('F')
2021            || text.contains('.')
2022            || (text.contains(['e', 'E'])))
2023            && hex_prefix.is_none()
2024        {
2025            // Floating-point constant
2026
2027            if let Some(double) = text.strip_suffix("lf").or_else(|| text.strip_suffix("LF")) {
2028                double
2029                    .parse()
2030                    .map(DOUBLE_CONST)
2031                    .map_err(|_| ErrorKind::InvalidDoubleLiteral)
2032            } else if let Some(float) = text.strip_suffix(['f', 'F']).or(Some(text)) {
2033                float
2034                    .parse()
2035                    .map(FLOAT_CONST)
2036                    .map_err(|_| ErrorKind::InvalidFloatLiteral)
2037            } else {
2038                Err(ErrorKind::InvalidFloatLiteral)
2039            }
2040        } else {
2041            // Integer constant
2042            if let Some(text) = hex_prefix {
2043                // Hexadecimal constant
2044                Self::parse_int(text, 16)
2045            } else if let Some(text) = text.strip_prefix('0') {
2046                if text.is_empty() {
2047                    if Self::strip_suffix(text).0 {
2048                        Ok(UINT_CONST(0))
2049                    } else {
2050                        Ok(INT_CONST(0))
2051                    }
2052                } else {
2053                    // Octal constant
2054                    Self::parse_int(text, 8)
2055                }
2056            } else {
2057                // Decimal constant
2058                Self::parse_int(text, 10)
2059            }
2060        };
2061
2062        match result {
2063            Ok(res) => res,
2064            Err(err) => ERROR(err),
2065        }
2066    }
2067}
2068
2069#[cfg(test)]
2070mod tests {
2071    use super::Token::{self, *};
2072
2073    #[test]
2074    fn test_parse_float_constant() {
2075        assert_eq!(Token::parse_digits("0."), FLOAT_CONST(0.));
2076        assert_eq!(Token::parse_digits(".0"), FLOAT_CONST(0.));
2077        assert_eq!(Token::parse_digits(".035"), FLOAT_CONST(0.035));
2078        assert_eq!(Token::parse_digits("0."), FLOAT_CONST(0.));
2079        assert_eq!(Token::parse_digits("0.035"), FLOAT_CONST(0.035));
2080        assert_eq!(Token::parse_digits(".035f"), FLOAT_CONST(0.035));
2081        assert_eq!(Token::parse_digits("0.f"), FLOAT_CONST(0.));
2082        assert_eq!(Token::parse_digits("314.f"), FLOAT_CONST(314.));
2083        assert_eq!(Token::parse_digits("0.035f"), FLOAT_CONST(0.035));
2084        assert_eq!(Token::parse_digits(".035F"), FLOAT_CONST(0.035));
2085        assert_eq!(Token::parse_digits("0.F"), FLOAT_CONST(0.));
2086        assert_eq!(Token::parse_digits("0.035F"), FLOAT_CONST(0.035));
2087        assert_eq!(Token::parse_digits("1.03e+34"), FLOAT_CONST(1.03e+34));
2088        assert_eq!(Token::parse_digits("1.03E+34"), FLOAT_CONST(1.03E+34));
2089        assert_eq!(Token::parse_digits("1.03e-34"), FLOAT_CONST(1.03e-34));
2090        assert_eq!(Token::parse_digits("1.03E-34"), FLOAT_CONST(1.03E-34));
2091        assert_eq!(Token::parse_digits("1.03e+34f"), FLOAT_CONST(1.03e+34));
2092        assert_eq!(Token::parse_digits("1.03E+34f"), FLOAT_CONST(1.03E+34));
2093        assert_eq!(Token::parse_digits("1.03e-34f"), FLOAT_CONST(1.03e-34));
2094        assert_eq!(Token::parse_digits("1.03E-34f"), FLOAT_CONST(1.03E-34));
2095        assert_eq!(Token::parse_digits("1.03e+34F"), FLOAT_CONST(1.03e+34));
2096        assert_eq!(Token::parse_digits("1.03E+34F"), FLOAT_CONST(1.03E+34));
2097        assert_eq!(Token::parse_digits("1.03e-34F"), FLOAT_CONST(1.03e-34));
2098        assert_eq!(Token::parse_digits("1.03E-34F"), FLOAT_CONST(1.03E-34));
2099
2100        assert_eq!(Token::parse_digits("1e-34"), FLOAT_CONST(1E-34));
2101        assert_eq!(Token::parse_digits("1e-34f"), FLOAT_CONST(1E-34));
2102        assert_eq!(Token::parse_digits("1E-34f"), FLOAT_CONST(1E-34));
2103        assert_eq!(Token::parse_digits("1e-34F"), FLOAT_CONST(1E-34));
2104        assert_eq!(Token::parse_digits("1E-34F"), FLOAT_CONST(1E-34));
2105    }
2106
2107    #[test]
2108    fn test_parse_double_constant() {
2109        assert_eq!(Token::parse_digits("0.lf"), DOUBLE_CONST(0.));
2110        assert_eq!(Token::parse_digits("0.035lf"), DOUBLE_CONST(0.035));
2111        assert_eq!(Token::parse_digits(".035lf"), DOUBLE_CONST(0.035));
2112        assert_eq!(Token::parse_digits(".035LF"), DOUBLE_CONST(0.035));
2113        assert_eq!(Token::parse_digits("0.LF"), DOUBLE_CONST(0.));
2114        assert_eq!(Token::parse_digits("0.035LF"), DOUBLE_CONST(0.035));
2115        assert_eq!(Token::parse_digits("1.03e+34lf"), DOUBLE_CONST(1.03e+34));
2116        assert_eq!(Token::parse_digits("1.03E+34lf"), DOUBLE_CONST(1.03E+34));
2117        assert_eq!(Token::parse_digits("1.03e-34lf"), DOUBLE_CONST(1.03e-34));
2118        assert_eq!(Token::parse_digits("1.03E-34lf"), DOUBLE_CONST(1.03E-34));
2119        assert_eq!(Token::parse_digits("1.03e+34LF"), DOUBLE_CONST(1.03e+34));
2120        assert_eq!(Token::parse_digits("1.03E+34LF"), DOUBLE_CONST(1.03E+34));
2121        assert_eq!(Token::parse_digits("1.03e-34LF"), DOUBLE_CONST(1.03e-34));
2122        assert_eq!(Token::parse_digits("1.03E-34LF"), DOUBLE_CONST(1.03E-34));
2123    }
2124
2125    #[test]
2126    fn test_parse_int_constant() {
2127        assert_eq!(Token::parse_digits("0"), INT_CONST(0));
2128        assert_eq!(Token::parse_digits("012"), INT_CONST(0o12));
2129        assert_eq!(Token::parse_digits("03"), INT_CONST(0o3));
2130        assert_eq!(Token::parse_digits("07654321"), INT_CONST(0o7654321));
2131        assert_eq!(Token::parse_digits("076556"), INT_CONST(0o76556));
2132        assert_eq!(Token::parse_digits("0x0123789"), INT_CONST(0x0123789));
2133        assert_eq!(Token::parse_digits("0x3"), INT_CONST(0x3));
2134        assert_eq!(Token::parse_digits("0x9ABCDEF"), INT_CONST(0x9ABCDEF));
2135        assert_eq!(Token::parse_digits("0x9abcdef"), INT_CONST(0x9abcdef));
2136        assert_eq!(Token::parse_digits("0xABCDEF"), INT_CONST(0xabcdef));
2137        assert_eq!(Token::parse_digits("0xabcdef"), INT_CONST(0xabcdef));
2138        assert_eq!(Token::parse_digits("123456"), INT_CONST(123456));
2139        assert_eq!(Token::parse_digits("13"), INT_CONST(13));
2140        assert_eq!(Token::parse_digits("3"), INT_CONST(3));
2141        assert_eq!(Token::parse_digits("42"), INT_CONST(42));
2142    }
2143
2144    #[test]
2145    fn test_parse_uint_constant() {
2146        assert_eq!(Token::parse_digits("0u"), UINT_CONST(0));
2147        assert_eq!(Token::parse_digits("1u"), UINT_CONST(1));
2148        assert_eq!(
2149            Token::parse_digits("0xffffffffU"),
2150            UINT_CONST(0xffffffffu32)
2151        );
2152    }
2153}