1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4  *
5  * Large chunks of this file are derived from the glsl crate which is:
6  * Copyright (c) 2018, Dimitri Sabadie <dimitri.sabadie@gmail.com>
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  *   * Redistributions of source code must retain the above copyright
14  *     notice, this list of conditions and the following disclaimer.
15  *
16  *   * Redistributions in binary form must reproduce the above
17  *     copyright notice, this list of conditions and the following
18  *     disclaimer in the documentation and/or other materials provided
19  *     with the distribution.
20  *
21  *   * Neither the name of Dimitri Sabadie <dimitri.sabadie@gmail.com> nor the names of other
22  *     contributors may be used to endorse or promote products derived
23  *     from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 
37 use glsl::syntax;
38 use glsl::syntax::{ArrayedIdentifier, ArraySpecifier, AssignmentOp, BinaryOp, Identifier};
39 use glsl::syntax::{NonEmpty, PrecisionQualifier, StructFieldSpecifier, StructSpecifier};
40 use glsl::syntax::{TypeSpecifier, TypeSpecifierNonArray, UnaryOp};
41 use std::cell::{Cell, Ref, RefCell};
42 use std::collections::HashMap;
43 use std::iter::FromIterator;
44 use std::mem;
45 use std::ops::{Deref, DerefMut};
46 use std::rc::Rc;
47 
48 trait LiftFrom<S> {
lift(state: &mut State, s: S) -> Self49     fn lift(state: &mut State, s: S) -> Self;
50 }
51 
lift<S, T: LiftFrom<S>>(state: &mut State, s: S) -> T52 fn lift<S, T: LiftFrom<S>>(state: &mut State, s: S) -> T {
53     LiftFrom::lift(state, s)
54 }
55 
56 #[derive(Debug)]
57 pub struct Symbol {
58     pub name: String,
59     pub decl: SymDecl,
60 }
61 
62 #[derive(Debug, Clone, PartialEq)]
63 pub struct FunctionSignature {
64     ret: Type,
65     params: Vec<Type>,
66 }
67 
68 #[derive(Debug, Clone, PartialEq)]
69 pub struct FunctionType {
70     signatures: NonEmpty<FunctionSignature>,
71 }
72 
73 #[derive(Clone, Copy, Debug, PartialEq)]
74 pub enum SamplerFormat {
75     Unknown,
76     RGBA8,
77     RGBA32F,
78     RGBA32I,
79     R8,
80     RG8,
81 }
82 
83 impl SamplerFormat {
type_suffix(self) -> Option<&'static str>84     pub fn type_suffix(self) -> Option<&'static str> {
85         match self {
86             SamplerFormat::Unknown => None,
87             SamplerFormat::RGBA8 => Some("RGBA8"),
88             SamplerFormat::RGBA32F => Some("RGBA32F"),
89             SamplerFormat::RGBA32I => Some("RGBA32I"),
90             SamplerFormat::R8 => Some("R8"),
91             SamplerFormat::RG8 => Some("RG8"),
92         }
93     }
94 }
95 
96 #[derive(Clone, Copy, Debug, PartialEq)]
97 pub enum StorageClass {
98     None,
99     Const,
100     In,
101     Out,
102     Uniform,
103     Sampler(SamplerFormat),
104     FragColor(i32),
105 }
106 
107 #[derive(Clone, Debug, PartialEq)]
108 pub struct ArraySizes {
109     pub sizes: Vec<Expr>,
110 }
111 
112 impl LiftFrom<&ArraySpecifier> for ArraySizes {
lift(state: &mut State, a: &ArraySpecifier) -> Self113     fn lift(state: &mut State, a: &ArraySpecifier) -> Self {
114         ArraySizes {
115             sizes: vec![match a {
116                 ArraySpecifier::Unsized => panic!(),
117                 ArraySpecifier::ExplicitlySized(expr) => translate_expression(state, expr),
118             }],
119         }
120     }
121 }
122 
123 #[derive(Copy, Clone, Debug, PartialEq)]
124 pub enum TypeKind {
125     Void,
126     Bool,
127     Int,
128     UInt,
129     Float,
130     Double,
131     Vec2,
132     Vec3,
133     Vec4,
134     DVec2,
135     DVec3,
136     DVec4,
137     BVec2,
138     BVec3,
139     BVec4,
140     IVec2,
141     IVec3,
142     IVec4,
143     UVec2,
144     UVec3,
145     UVec4,
146     Mat2,
147     Mat3,
148     Mat4,
149     Mat23,
150     Mat24,
151     Mat32,
152     Mat34,
153     Mat42,
154     Mat43,
155     DMat2,
156     DMat3,
157     DMat4,
158     DMat23,
159     DMat24,
160     DMat32,
161     DMat34,
162     DMat42,
163     DMat43,
164     // floating point opaque types
165     Sampler1D,
166     Image1D,
167     Sampler2D,
168     Image2D,
169     Sampler3D,
170     Image3D,
171     SamplerCube,
172     ImageCube,
173     Sampler2DRect,
174     Image2DRect,
175     Sampler1DArray,
176     Image1DArray,
177     Sampler2DArray,
178     Image2DArray,
179     SamplerBuffer,
180     ImageBuffer,
181     Sampler2DMS,
182     Image2DMS,
183     Sampler2DMSArray,
184     Image2DMSArray,
185     SamplerCubeArray,
186     ImageCubeArray,
187     Sampler1DShadow,
188     Sampler2DShadow,
189     Sampler2DRectShadow,
190     Sampler1DArrayShadow,
191     Sampler2DArrayShadow,
192     SamplerCubeShadow,
193     SamplerCubeArrayShadow,
194     // signed integer opaque types
195     ISampler1D,
196     IImage1D,
197     ISampler2D,
198     IImage2D,
199     ISampler3D,
200     IImage3D,
201     ISamplerCube,
202     IImageCube,
203     ISampler2DRect,
204     IImage2DRect,
205     ISampler1DArray,
206     IImage1DArray,
207     ISampler2DArray,
208     IImage2DArray,
209     ISamplerBuffer,
210     IImageBuffer,
211     ISampler2DMS,
212     IImage2DMS,
213     ISampler2DMSArray,
214     IImage2DMSArray,
215     ISamplerCubeArray,
216     IImageCubeArray,
217     // unsigned integer opaque types
218     AtomicUInt,
219     USampler1D,
220     UImage1D,
221     USampler2D,
222     UImage2D,
223     USampler3D,
224     UImage3D,
225     USamplerCube,
226     UImageCube,
227     USampler2DRect,
228     UImage2DRect,
229     USampler1DArray,
230     UImage1DArray,
231     USampler2DArray,
232     UImage2DArray,
233     USamplerBuffer,
234     UImageBuffer,
235     USampler2DMS,
236     UImage2DMS,
237     USampler2DMSArray,
238     UImage2DMSArray,
239     USamplerCubeArray,
240     UImageCubeArray,
241     Struct(SymRef),
242 }
243 
244 impl TypeKind {
is_sampler(&self) -> bool245     pub fn is_sampler(&self) -> bool {
246         use TypeKind::*;
247         match self {
248             Sampler1D
249             | Image1D
250             | Sampler2D
251             | Image2D
252             | Sampler3D
253             | Image3D
254             | SamplerCube
255             | ImageCube
256             | Sampler2DRect
257             | Image2DRect
258             | Sampler1DArray
259             | Image1DArray
260             | Sampler2DArray
261             | Image2DArray
262             | SamplerBuffer
263             | ImageBuffer
264             | Sampler2DMS
265             | Image2DMS
266             | Sampler2DMSArray
267             | Image2DMSArray
268             | SamplerCubeArray
269             | ImageCubeArray
270             | Sampler1DShadow
271             | Sampler2DShadow
272             | Sampler2DRectShadow
273             | Sampler1DArrayShadow
274             | Sampler2DArrayShadow
275             | SamplerCubeShadow
276             | SamplerCubeArrayShadow
277             | ISampler1D
278             | IImage1D
279             | ISampler2D
280             | IImage2D
281             | ISampler3D
282             | IImage3D
283             | ISamplerCube
284             | IImageCube
285             | ISampler2DRect
286             | IImage2DRect
287             | ISampler1DArray
288             | IImage1DArray
289             | ISampler2DArray
290             | IImage2DArray
291             | ISamplerBuffer
292             | IImageBuffer
293             | ISampler2DMS
294             | IImage2DMS
295             | ISampler2DMSArray
296             | IImage2DMSArray
297             | ISamplerCubeArray
298             | IImageCubeArray
299             | USampler1D
300             | UImage1D
301             | USampler2D
302             | UImage2D
303             | USampler3D
304             | UImage3D
305             | USamplerCube
306             | UImageCube
307             | USampler2DRect
308             | UImage2DRect
309             | USampler1DArray
310             | UImage1DArray
311             | USampler2DArray
312             | UImage2DArray
313             | USamplerBuffer
314             | UImageBuffer
315             | USampler2DMS
316             | UImage2DMS
317             | USampler2DMSArray
318             | UImage2DMSArray
319             | USamplerCubeArray
320             | UImageCubeArray => true,
321             _ => false,
322         }
323     }
324 
is_bool(&self) -> bool325     pub fn is_bool(&self) -> bool {
326         use TypeKind::*;
327         match self {
328             Bool | BVec2 | BVec3 | BVec4 => true,
329             _ => false,
330         }
331     }
332 
to_bool(&self) -> Self333     pub fn to_bool(&self) -> Self {
334         use TypeKind::*;
335         match self {
336             Int | UInt | Float | Double => Bool,
337             IVec2 | UVec2 | Vec2 | DVec2 => BVec2,
338             IVec3 | UVec3 | Vec3 | DVec3 => BVec3,
339             IVec4 | UVec4 | Vec4 | DVec4 => BVec4,
340             _ => *self,
341         }
342     }
343 
to_int(&self) -> Self344     pub fn to_int(&self) -> Self {
345         use TypeKind::*;
346         match self {
347             Bool | UInt | Float | Double => Int,
348             BVec2 | UVec2 | Vec2 | DVec2 => IVec2,
349             BVec3 | UVec3 | Vec3 | DVec3 => IVec3,
350             BVec4 | UVec4 | Vec4 | DVec4 => IVec4,
351             _ => *self,
352         }
353     }
354 
to_scalar(&self) -> Self355     pub fn to_scalar(&self) -> Self {
356         use TypeKind::*;
357         match self {
358             IVec2 | IVec3 | IVec4 => Int,
359             UVec2 | UVec3 | UVec4 => UInt,
360             Vec2 | Vec3 | Vec4 => Float,
361             DVec2 | DVec3 | DVec4 => Double,
362             BVec2 | BVec3 | BVec4 => Bool,
363             _ => *self,
364         }
365     }
366 
glsl_primitive_type_name(&self) -> Option<&'static str>367     pub fn glsl_primitive_type_name(&self) -> Option<&'static str> {
368         use TypeKind::*;
369         Some(match self {
370             Void => "void",
371             Bool => "bool",
372             Int => "int",
373             UInt => "uint",
374             Float => "float",
375             Double => "double",
376             Vec2 => "vec2",
377             Vec3 => "vec3",
378             Vec4 => "vec4",
379             DVec2 => "dvec2",
380             DVec3 => "dvec3",
381             DVec4 => "dvec4",
382             BVec2 => "bvec2",
383             BVec3 => "bvec3",
384             BVec4 => "bvec4",
385             IVec2 => "ivec2",
386             IVec3 => "ivec3",
387             IVec4 => "ivec4",
388             UVec2 => "uvec2",
389             UVec3 => "uvec3",
390             UVec4 => "uvec4",
391             Mat2 => "mat2",
392             Mat3 => "mat3",
393             Mat4 => "mat4",
394             Mat23 => "mat23",
395             Mat24 => "mat24",
396             Mat32 => "mat32",
397             Mat34 => "mat34",
398             Mat42 => "mat42",
399             Mat43 => "mat43",
400             DMat2 => "dmat2",
401             DMat3 => "dmat3",
402             DMat4 => "dmat4",
403             DMat23 => "dmat23",
404             DMat24 => "dmat24",
405             DMat32 => "dmat32",
406             DMat34 => "dmat34",
407             DMat42 => "dmat42",
408             DMat43 => "dmat43",
409             Sampler1D => "sampler1D",
410             Image1D => "image1D",
411             Sampler2D => "sampler2D",
412             Image2D => "image2D",
413             Sampler3D => "sampler3D",
414             Image3D => "image3D",
415             SamplerCube => "samplerCube",
416             ImageCube => "imageCube",
417             Sampler2DRect => "sampler2DRect",
418             Image2DRect => "image2DRect",
419             Sampler1DArray => "sampler1DArray",
420             Image1DArray => "image1DArray",
421             Sampler2DArray => "sampler2DArray",
422             Image2DArray => "image2DArray",
423             SamplerBuffer => "samplerBuffer",
424             ImageBuffer => "imageBuffer",
425             Sampler2DMS => "sampler2DMS",
426             Image2DMS => "image2DMS",
427             Sampler2DMSArray => "sampler2DMSArray",
428             Image2DMSArray => "image2DMSArray",
429             SamplerCubeArray => "samplerCubeArray",
430             ImageCubeArray => "imageCubeArray",
431             Sampler1DShadow => "sampler1DShadow",
432             Sampler2DShadow => "sampler2DShadow",
433             Sampler2DRectShadow => "sampler2DRectShadow",
434             Sampler1DArrayShadow => "sampler1DArrayShadow",
435             Sampler2DArrayShadow => "sampler2DArrayShadow",
436             SamplerCubeShadow => "samplerCubeShadow",
437             SamplerCubeArrayShadow => "samplerCubeArrayShadow",
438             ISampler1D => "isampler1D",
439             IImage1D => "iimage1D",
440             ISampler2D => "isampler2D",
441             IImage2D => "iimage2D",
442             ISampler3D => "isampler3D",
443             IImage3D => "iimage3D",
444             ISamplerCube => "isamplerCube",
445             IImageCube => "iimageCube",
446             ISampler2DRect => "isampler2DRect",
447             IImage2DRect => "iimage2DRect",
448             ISampler1DArray => "isampler1DArray",
449             IImage1DArray => "iimage1DArray",
450             ISampler2DArray => "isampler2DArray",
451             IImage2DArray => "iimage2DArray",
452             ISamplerBuffer => "isamplerBuffer",
453             IImageBuffer => "iimageBuffer",
454             ISampler2DMS => "isampler2MS",
455             IImage2DMS => "iimage2DMS",
456             ISampler2DMSArray => "isampler2DMSArray",
457             IImage2DMSArray => "iimage2DMSArray",
458             ISamplerCubeArray => "isamplerCubeArray",
459             IImageCubeArray => "iimageCubeArray",
460             AtomicUInt => "atomic_uint",
461             USampler1D => "usampler1D",
462             UImage1D => "uimage1D",
463             USampler2D => "usampler2D",
464             UImage2D => "uimage2D",
465             USampler3D => "usampler3D",
466             UImage3D => "uimage3D",
467             USamplerCube => "usamplerCube",
468             UImageCube => "uimageCube",
469             USampler2DRect => "usampler2DRect",
470             UImage2DRect => "uimage2DRect",
471             USampler1DArray => "usampler1DArray",
472             UImage1DArray => "uimage1DArray",
473             USampler2DArray => "usampler2DArray",
474             UImage2DArray => "uimage2DArray",
475             USamplerBuffer => "usamplerBuffer",
476             UImageBuffer => "uimageBuffer",
477             USampler2DMS => "usampler2DMS",
478             UImage2DMS => "uimage2DMS",
479             USampler2DMSArray => "usamplerDMSArray",
480             UImage2DMSArray => "uimage2DMSArray",
481             USamplerCubeArray => "usamplerCubeArray",
482             UImageCubeArray => "uimageCubeArray",
483             Struct(..) => return None,
484         })
485     }
486 
cxx_primitive_type_name(&self) -> Option<&'static str>487     pub fn cxx_primitive_type_name(&self) -> Option<&'static str> {
488         use TypeKind::*;
489         match self {
490             Bool => Some("Bool"),
491             Int => Some("I32"),
492             UInt => Some("U32"),
493             Float => Some("Float"),
494             Double => Some("Double"),
495             _ => self.glsl_primitive_type_name(),
496         }
497     }
498 
cxx_primitive_scalar_type_name(&self) -> Option<&'static str>499     pub fn cxx_primitive_scalar_type_name(&self) -> Option<&'static str> {
500         use TypeKind::*;
501         match self {
502             Void => Some("void"),
503             Bool => Some("bool"),
504             Int => Some("int32_t"),
505             UInt => Some("uint32_t"),
506             Float => Some("float"),
507             Double => Some("double"),
508             _ => {
509                 if self.is_sampler() {
510                     self.cxx_primitive_type_name()
511                 } else {
512                     None
513                 }
514             }
515         }
516     }
517 
from_glsl_primitive_type_name(name: &str) -> Option<TypeKind>518     pub fn from_glsl_primitive_type_name(name: &str) -> Option<TypeKind> {
519         use TypeKind::*;
520         Some(match name {
521             "void" => Void,
522             "bool" => Bool,
523             "int" => Int,
524             "uint" => UInt,
525             "float" => Float,
526             "double" => Double,
527             "vec2" => Vec2,
528             "vec3" => Vec3,
529             "vec4" => Vec4,
530             "dvec2" => DVec2,
531             "dvec3" => DVec3,
532             "dvec4" => DVec4,
533             "bvec2" => BVec2,
534             "bvec3" => BVec3,
535             "bvec4" => BVec4,
536             "ivec2" => IVec2,
537             "ivec3" => IVec3,
538             "ivec4" => IVec4,
539             "uvec2" => UVec2,
540             "uvec3" => UVec3,
541             "uvec4" => UVec4,
542             "mat2" => Mat2,
543             "mat3" => Mat3,
544             "mat4" => Mat4,
545             "mat23" => Mat23,
546             "mat24" => Mat24,
547             "mat32" => Mat32,
548             "mat34" => Mat34,
549             "mat42" => Mat42,
550             "mat43" => Mat43,
551             "dmat2" => DMat2,
552             "dmat3" => DMat3,
553             "dmat4" => DMat4,
554             "dmat23" => DMat23,
555             "dmat24" => DMat24,
556             "dmat32" => DMat32,
557             "dmat34" => DMat34,
558             "dmat42" => DMat42,
559             "dmat43" => DMat43,
560             "sampler1D" => Sampler1D,
561             "image1D" => Image1D,
562             "sampler2D" => Sampler2D,
563             "image2D" => Image2D,
564             "sampler3D" => Sampler3D,
565             "image3D" => Image3D,
566             "samplerCube" => SamplerCube,
567             "imageCube" => ImageCube,
568             "sampler2DRect" => Sampler2DRect,
569             "image2DRect" => Image2DRect,
570             "sampler1DArray" => Sampler1DArray,
571             "image1DArray" => Image1DArray,
572             "sampler2DArray" => Sampler2DArray,
573             "image2DArray" => Image2DArray,
574             "samplerBuffer" => SamplerBuffer,
575             "imageBuffer" => ImageBuffer,
576             "sampler2DMS" => Sampler2DMS,
577             "image2DMS" => Image2DMS,
578             "sampler2DMSArray" => Sampler2DMSArray,
579             "image2DMSArray" => Image2DMSArray,
580             "samplerCubeArray" => SamplerCubeArray,
581             "imageCubeArray" => ImageCubeArray,
582             "sampler1DShadow" => Sampler1DShadow,
583             "sampler2DShadow" => Sampler2DShadow,
584             "sampler2DRectShadow" => Sampler2DRectShadow,
585             "sampler1DArrayShadow" => Sampler1DArrayShadow,
586             "sampler2DArrayShadow" => Sampler2DArrayShadow,
587             "samplerCubeShadow" => SamplerCubeShadow,
588             "samplerCubeArrayShadow" => SamplerCubeArrayShadow,
589             "isampler1D" => ISampler1D,
590             "iimage1D" => IImage1D,
591             "isampler2D" => ISampler2D,
592             "iimage2D" => IImage2D,
593             "isampler3D" => ISampler3D,
594             "iimage3D" => IImage3D,
595             "isamplerCube" => ISamplerCube,
596             "iimageCube" => IImageCube,
597             "isampler2DRect" => ISampler2DRect,
598             "iimage2DRect" => IImage2DRect,
599             "isampler1DArray" => ISampler1DArray,
600             "iimage1DArray" => IImage1DArray,
601             "isampler2DArray" => ISampler2DArray,
602             "iimage2DArray" => IImage2DArray,
603             "isamplerBuffer" => ISamplerBuffer,
604             "iimageBuffer" => IImageBuffer,
605             "isampler2MS" => ISampler2DMS,
606             "iimage2DMS" => IImage2DMS,
607             "isampler2DMSArray" => ISampler2DMSArray,
608             "iimage2DMSArray" => IImage2DMSArray,
609             "isamplerCubeArray" => ISamplerCubeArray,
610             "iimageCubeArray" => IImageCubeArray,
611             "atomic_uint" => AtomicUInt,
612             "usampler1D" => USampler1D,
613             "uimage1D" => UImage1D,
614             "usampler2D" => USampler2D,
615             "uimage2D" => UImage2D,
616             "usampler3D" => USampler3D,
617             "uimage3D" => UImage3D,
618             "usamplerCube" => USamplerCube,
619             "uimageCube" => UImageCube,
620             "usampler2DRect" => USampler2DRect,
621             "uimage2DRect" => UImage2DRect,
622             "usampler1DArray" => USampler1DArray,
623             "uimage1DArray" => UImage1DArray,
624             "usampler2DArray" => USampler2DArray,
625             "uimage2DArray" => UImage2DArray,
626             "usamplerBuffer" => USamplerBuffer,
627             "uimageBuffer" => UImageBuffer,
628             "usampler2DMS" => USampler2DMS,
629             "uimage2DMS" => UImage2DMS,
630             "usamplerDMSArray" => USampler2DMSArray,
631             "uimage2DMSArray" => UImage2DMSArray,
632             "usamplerCubeArray" => USamplerCubeArray,
633             "uimageCubeArray" => UImageCubeArray,
634             _ => return None,
635         })
636     }
637 
from_primitive_type_specifier(spec: &syntax::TypeSpecifierNonArray) -> Option<TypeKind>638     pub fn from_primitive_type_specifier(spec: &syntax::TypeSpecifierNonArray) -> Option<TypeKind> {
639         use TypeKind::*;
640         Some(match spec {
641             TypeSpecifierNonArray::Void => Void,
642             TypeSpecifierNonArray::Bool => Bool,
643             TypeSpecifierNonArray::Int => Int,
644             TypeSpecifierNonArray::UInt => UInt,
645             TypeSpecifierNonArray::Float => Float,
646             TypeSpecifierNonArray::Double => Double,
647             TypeSpecifierNonArray::Vec2 => Vec2,
648             TypeSpecifierNonArray::Vec3 => Vec3,
649             TypeSpecifierNonArray::Vec4 => Vec4,
650             TypeSpecifierNonArray::DVec2 => DVec2,
651             TypeSpecifierNonArray::DVec3 => DVec3,
652             TypeSpecifierNonArray::DVec4 => DVec4,
653             TypeSpecifierNonArray::BVec2 => BVec2,
654             TypeSpecifierNonArray::BVec3 => BVec3,
655             TypeSpecifierNonArray::BVec4 => BVec4,
656             TypeSpecifierNonArray::IVec2 => IVec2,
657             TypeSpecifierNonArray::IVec3 => IVec3,
658             TypeSpecifierNonArray::IVec4 => IVec4,
659             TypeSpecifierNonArray::UVec2 => UVec2,
660             TypeSpecifierNonArray::UVec3 => UVec3,
661             TypeSpecifierNonArray::UVec4 => UVec4,
662             TypeSpecifierNonArray::Mat2 => Mat2,
663             TypeSpecifierNonArray::Mat3 => Mat3,
664             TypeSpecifierNonArray::Mat4 => Mat4,
665             TypeSpecifierNonArray::Mat23 => Mat23,
666             TypeSpecifierNonArray::Mat24 => Mat24,
667             TypeSpecifierNonArray::Mat32 => Mat32,
668             TypeSpecifierNonArray::Mat34 => Mat34,
669             TypeSpecifierNonArray::Mat42 => Mat42,
670             TypeSpecifierNonArray::Mat43 => Mat43,
671             TypeSpecifierNonArray::DMat2 => DMat2,
672             TypeSpecifierNonArray::DMat3 => DMat3,
673             TypeSpecifierNonArray::DMat4 => DMat4,
674             TypeSpecifierNonArray::DMat23 => DMat23,
675             TypeSpecifierNonArray::DMat24 => DMat24,
676             TypeSpecifierNonArray::DMat32 => DMat32,
677             TypeSpecifierNonArray::DMat34 => DMat34,
678             TypeSpecifierNonArray::DMat42 => DMat42,
679             TypeSpecifierNonArray::DMat43 => DMat43,
680             TypeSpecifierNonArray::Sampler1D => Sampler1D,
681             TypeSpecifierNonArray::Image1D => Image1D,
682             TypeSpecifierNonArray::Sampler2D => Sampler2D,
683             TypeSpecifierNonArray::Image2D => Image2D,
684             TypeSpecifierNonArray::Sampler3D => Sampler3D,
685             TypeSpecifierNonArray::Image3D => Image3D,
686             TypeSpecifierNonArray::SamplerCube => SamplerCube,
687             TypeSpecifierNonArray::ImageCube => ImageCube,
688             TypeSpecifierNonArray::Sampler2DRect => Sampler2DRect,
689             TypeSpecifierNonArray::Image2DRect => Image2DRect,
690             TypeSpecifierNonArray::Sampler1DArray => Sampler1DArray,
691             TypeSpecifierNonArray::Image1DArray => Image1DArray,
692             TypeSpecifierNonArray::Sampler2DArray => Sampler2DArray,
693             TypeSpecifierNonArray::Image2DArray => Image2DArray,
694             TypeSpecifierNonArray::SamplerBuffer => SamplerBuffer,
695             TypeSpecifierNonArray::ImageBuffer => ImageBuffer,
696             TypeSpecifierNonArray::Sampler2DMS => Sampler2DMS,
697             TypeSpecifierNonArray::Image2DMS => Image2DMS,
698             TypeSpecifierNonArray::Sampler2DMSArray => Sampler2DMSArray,
699             TypeSpecifierNonArray::Image2DMSArray => Image2DMSArray,
700             TypeSpecifierNonArray::SamplerCubeArray => SamplerCubeArray,
701             TypeSpecifierNonArray::ImageCubeArray => ImageCubeArray,
702             TypeSpecifierNonArray::Sampler1DShadow => Sampler1DShadow,
703             TypeSpecifierNonArray::Sampler2DShadow => Sampler2DShadow,
704             TypeSpecifierNonArray::Sampler2DRectShadow => Sampler2DRectShadow,
705             TypeSpecifierNonArray::Sampler1DArrayShadow => Sampler1DArrayShadow,
706             TypeSpecifierNonArray::Sampler2DArrayShadow => Sampler2DArrayShadow,
707             TypeSpecifierNonArray::SamplerCubeShadow => SamplerCubeShadow,
708             TypeSpecifierNonArray::SamplerCubeArrayShadow => SamplerCubeArrayShadow,
709             TypeSpecifierNonArray::ISampler1D => ISampler1D,
710             TypeSpecifierNonArray::IImage1D => IImage1D,
711             TypeSpecifierNonArray::ISampler2D => ISampler2D,
712             TypeSpecifierNonArray::IImage2D => IImage2D,
713             TypeSpecifierNonArray::ISampler3D => ISampler3D,
714             TypeSpecifierNonArray::IImage3D => IImage3D,
715             TypeSpecifierNonArray::ISamplerCube => ISamplerCube,
716             TypeSpecifierNonArray::IImageCube => IImageCube,
717             TypeSpecifierNonArray::ISampler2DRect => ISampler2DRect,
718             TypeSpecifierNonArray::IImage2DRect => IImage2DRect,
719             TypeSpecifierNonArray::ISampler1DArray => ISampler1DArray,
720             TypeSpecifierNonArray::IImage1DArray => IImage1DArray,
721             TypeSpecifierNonArray::ISampler2DArray => ISampler2DArray,
722             TypeSpecifierNonArray::IImage2DArray => IImage2DArray,
723             TypeSpecifierNonArray::ISamplerBuffer => ISamplerBuffer,
724             TypeSpecifierNonArray::IImageBuffer => IImageBuffer,
725             TypeSpecifierNonArray::ISampler2DMS => ISampler2DMS,
726             TypeSpecifierNonArray::IImage2DMS => IImage2DMS,
727             TypeSpecifierNonArray::ISampler2DMSArray => ISampler2DMSArray,
728             TypeSpecifierNonArray::IImage2DMSArray => IImage2DMSArray,
729             TypeSpecifierNonArray::ISamplerCubeArray => ISamplerCubeArray,
730             TypeSpecifierNonArray::IImageCubeArray => IImageCubeArray,
731             TypeSpecifierNonArray::AtomicUInt => AtomicUInt,
732             TypeSpecifierNonArray::USampler1D => USampler1D,
733             TypeSpecifierNonArray::UImage1D => UImage1D,
734             TypeSpecifierNonArray::USampler2D => USampler2D,
735             TypeSpecifierNonArray::UImage2D => UImage2D,
736             TypeSpecifierNonArray::USampler3D => USampler3D,
737             TypeSpecifierNonArray::UImage3D => UImage3D,
738             TypeSpecifierNonArray::USamplerCube => USamplerCube,
739             TypeSpecifierNonArray::UImageCube => UImageCube,
740             TypeSpecifierNonArray::USampler2DRect => USampler2DRect,
741             TypeSpecifierNonArray::UImage2DRect => UImage2DRect,
742             TypeSpecifierNonArray::USampler1DArray => USampler1DArray,
743             TypeSpecifierNonArray::UImage1DArray => UImage1DArray,
744             TypeSpecifierNonArray::USampler2DArray => USampler2DArray,
745             TypeSpecifierNonArray::UImage2DArray => UImage2DArray,
746             TypeSpecifierNonArray::USamplerBuffer => USamplerBuffer,
747             TypeSpecifierNonArray::UImageBuffer => UImageBuffer,
748             TypeSpecifierNonArray::USampler2DMS => USampler2DMS,
749             TypeSpecifierNonArray::UImage2DMS => UImage2DMS,
750             TypeSpecifierNonArray::USampler2DMSArray => USampler2DMSArray,
751             TypeSpecifierNonArray::UImage2DMSArray => UImage2DMSArray,
752             TypeSpecifierNonArray::USamplerCubeArray => USamplerCubeArray,
753             TypeSpecifierNonArray::UImageCubeArray => UImageCubeArray,
754             TypeSpecifierNonArray::Struct(..) | TypeSpecifierNonArray::TypeName(..) => return None,
755         })
756     }
757 }
758 
759 impl LiftFrom<&syntax::TypeSpecifierNonArray> for TypeKind {
lift(state: &mut State, spec: &syntax::TypeSpecifierNonArray) -> Self760     fn lift(state: &mut State, spec: &syntax::TypeSpecifierNonArray) -> Self {
761         use TypeKind::*;
762         if let Some(kind) = TypeKind::from_primitive_type_specifier(spec) {
763             kind
764         } else {
765             match spec {
766                 TypeSpecifierNonArray::Struct(s) => {
767                     Struct(state.lookup(s.name.as_ref().unwrap().as_str()).unwrap())
768                 }
769                 TypeSpecifierNonArray::TypeName(s) => Struct(state.lookup(&s.0).unwrap()),
770                 _ => unreachable!(),
771             }
772         }
773     }
774 }
775 
776 #[derive(Clone, Debug, PartialEq)]
777 pub struct Type {
778     pub kind: TypeKind,
779     pub precision: Option<PrecisionQualifier>,
780     pub array_sizes: Option<Box<ArraySizes>>,
781 }
782 
783 impl Type {
new(kind: TypeKind) -> Self784     pub fn new(kind: TypeKind) -> Self {
785         Type {
786             kind,
787             precision: None,
788             array_sizes: None,
789         }
790     }
791 
new_array(kind: TypeKind, size: i32) -> Self792     pub fn new_array(kind: TypeKind, size: i32) -> Self {
793         Type {
794             kind,
795             precision: None,
796             array_sizes: Some(Box::new(ArraySizes { sizes: vec![make_const(TypeKind::Int, size)] })),
797         }
798     }
799 }
800 
801 impl LiftFrom<&syntax::FullySpecifiedType> for Type {
lift(state: &mut State, ty: &syntax::FullySpecifiedType) -> Self802     fn lift(state: &mut State, ty: &syntax::FullySpecifiedType) -> Self {
803         let kind = lift(state, &ty.ty.ty);
804         let array_sizes = match ty.ty.array_specifier.as_ref() {
805             Some(x) => Some(Box::new(lift(state, x))),
806             None => None,
807         };
808         let precision = get_precision(&ty.qualifier);
809         Type {
810             kind,
811             precision,
812             array_sizes,
813         }
814     }
815 }
816 
817 impl LiftFrom<&syntax::TypeSpecifier> for Type {
lift(state: &mut State, ty: &syntax::TypeSpecifier) -> Self818     fn lift(state: &mut State, ty: &syntax::TypeSpecifier) -> Self {
819         let kind = lift(state, &ty.ty);
820         let array_sizes = ty
821             .array_specifier
822             .as_ref()
823             .map(|x| Box::new(lift(state, x)));
824         Type {
825             kind,
826             precision: None,
827             array_sizes,
828         }
829     }
830 }
831 
832 #[derive(Debug, Clone, PartialEq)]
833 pub struct StructField {
834     pub ty: Type,
835     pub name: syntax::Identifier,
836 }
837 
get_precision(qualifiers: &Option<syntax::TypeQualifier>) -> Option<PrecisionQualifier>838 fn get_precision(qualifiers: &Option<syntax::TypeQualifier>) -> Option<PrecisionQualifier> {
839     let mut precision = None;
840     for qual in qualifiers.iter().flat_map(|x| x.qualifiers.0.iter()) {
841         match qual {
842             syntax::TypeQualifierSpec::Precision(p) => {
843                 if precision.is_some() {
844                     panic!("Multiple precisions");
845                 }
846                 precision = Some(p.clone());
847             }
848             _ => {}
849         }
850     }
851     precision
852 }
853 
854 impl LiftFrom<&StructFieldSpecifier> for StructField {
lift(state: &mut State, f: &StructFieldSpecifier) -> Self855     fn lift(state: &mut State, f: &StructFieldSpecifier) -> Self {
856         let mut ty: Type = lift(state, &f.ty);
857         match &f.identifiers.0[..] {
858             [ident] => {
859                 if let Some(a) = &ident.array_spec {
860                     ty.array_sizes = Some(Box::new(lift(state, a)));
861                 }
862                 StructField {
863                     ty,
864                     name: ident.ident.clone(),
865                 }
866             }
867             _ => panic!("bad number of identifiers"),
868         }
869     }
870 }
871 
872 #[derive(Debug, Clone, PartialEq)]
873 pub struct StructFields {
874     pub fields: Vec<StructField>,
875 }
876 
877 impl LiftFrom<&StructSpecifier> for StructFields {
lift(state: &mut State, s: &StructSpecifier) -> Self878     fn lift(state: &mut State, s: &StructSpecifier) -> Self {
879         let fields = s.fields.0.iter().map(|field| lift(state, field)).collect();
880         Self { fields }
881     }
882 }
883 
884 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
885 pub enum RunClass {
886     Unknown,
887     Scalar,
888     Vector,
889     Dependent(u32),
890 }
891 
892 impl RunClass {
merge(self, run_class: RunClass) -> RunClass893     pub fn merge(self, run_class: RunClass) -> RunClass {
894         match (self, run_class) {
895             (RunClass::Vector, _) | (_, RunClass::Vector) => RunClass::Vector,
896             (RunClass::Dependent(x), RunClass::Dependent(y)) => RunClass::Dependent(x | y),
897             (RunClass::Unknown, _) | (_, RunClass::Dependent(..)) => run_class,
898             _ => self,
899         }
900     }
901 }
902 
903 #[derive(Debug, Clone, PartialEq)]
904 pub enum SymDecl {
905     NativeFunction(FunctionType, Option<&'static str>, RunClass),
906     UserFunction(Rc<FunctionDefinition>, RunClass),
907     Local(StorageClass, Type, RunClass),
908     Global(
909         StorageClass,
910         Option<syntax::InterpolationQualifier>,
911         Type,
912         RunClass,
913     ),
914     Struct(StructFields),
915 }
916 
917 #[derive(Clone, Debug, PartialEq, Copy, Eq, Hash)]
918 pub struct SymRef(u32);
919 
920 #[derive(Debug)]
921 struct Scope {
922     name: String,
923     names: HashMap<String, SymRef>,
924 }
925 impl Scope {
new(name: String) -> Self926     fn new(name: String) -> Self {
927         Scope {
928             name,
929             names: HashMap::new(),
930         }
931     }
932 }
933 
934 #[derive(Clone, Debug, PartialEq)]
935 pub struct TexelFetchOffsets {
936     pub min_x: i32,
937     pub max_x: i32,
938     pub min_y: i32,
939     pub max_y: i32,
940 }
941 
942 impl TexelFetchOffsets {
new(x: i32, y: i32) -> Self943     fn new(x: i32, y: i32) -> Self {
944         TexelFetchOffsets {
945             min_x: x,
946             max_x: x,
947             min_y: y,
948             max_y: y,
949         }
950     }
951 
add_offset(&mut self, x: i32, y: i32)952     fn add_offset(&mut self, x: i32, y: i32) {
953         self.min_x = self.min_x.min(x);
954         self.max_x = self.max_x.max(x);
955         self.min_y = self.min_y.min(y);
956         self.max_y = self.max_y.max(y);
957     }
958 }
959 
960 #[derive(Debug)]
961 pub struct State {
962     scopes: Vec<Scope>,
963     syms: Vec<RefCell<Symbol>>,
964     in_function: Option<SymRef>,
965     run_class_changed: Cell<bool>,
966     last_declaration: SymRef,
967     branch_run_class: RunClass,
968     branch_declaration: SymRef,
969     modified_globals: RefCell<Vec<SymRef>>,
970     pub used_globals: RefCell<Vec<SymRef>>,
971     pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>,
972     clip_dist_sym: SymRef,
973     pub used_clip_dist: u32,
974 }
975 
976 impl State {
new() -> Self977     pub fn new() -> Self {
978         State {
979             scopes: Vec::new(),
980             syms: Vec::new(),
981             in_function: None,
982             run_class_changed: Cell::new(false),
983             last_declaration: SymRef(0),
984             branch_run_class: RunClass::Unknown,
985             branch_declaration: SymRef(0),
986             modified_globals: RefCell::new(Vec::new()),
987             used_globals: RefCell::new(Vec::new()),
988             texel_fetches: HashMap::new(),
989             clip_dist_sym: SymRef(0),
990             used_clip_dist: 0,
991         }
992     }
993 
lookup(&self, name: &str) -> Option<SymRef>994     pub fn lookup(&self, name: &str) -> Option<SymRef> {
995         for s in self.scopes.iter().rev() {
996             if let Some(sym) = s.names.get(name) {
997                 return Some(*sym);
998             }
999         }
1000         return None;
1001     }
1002 
declare(&mut self, name: &str, decl: SymDecl) -> SymRef1003     fn declare(&mut self, name: &str, decl: SymDecl) -> SymRef {
1004         let s = SymRef(self.syms.len() as u32);
1005         self.syms.push(RefCell::new(Symbol {
1006             name: name.into(),
1007             decl,
1008         }));
1009         self.scopes.last_mut().unwrap().names.insert(name.into(), s);
1010         s
1011     }
1012 
sym(&self, sym: SymRef) -> Ref<Symbol>1013     pub fn sym(&self, sym: SymRef) -> Ref<Symbol> {
1014         self.syms[sym.0 as usize].borrow()
1015     }
1016 
sym_mut(&mut self, sym: SymRef) -> &mut Symbol1017     pub fn sym_mut(&mut self, sym: SymRef) -> &mut Symbol {
1018         self.syms[sym.0 as usize].get_mut()
1019     }
1020 
lookup_sym_mut(&mut self, name: &str) -> Option<&mut Symbol>1021     pub fn lookup_sym_mut(&mut self, name: &str) -> Option<&mut Symbol> {
1022         self.lookup(name)
1023             .map(move |x| self.syms[x.0 as usize].get_mut())
1024     }
1025 
push_scope(&mut self, name: String)1026     fn push_scope(&mut self, name: String) {
1027         self.scopes.push(Scope::new(name));
1028     }
pop_scope(&mut self)1029     fn pop_scope(&mut self) {
1030         self.scopes.pop();
1031     }
1032 
return_run_class(&self, mut new_run_class: RunClass)1033     fn return_run_class(&self, mut new_run_class: RunClass) {
1034         new_run_class = self.branch_run_class.merge(new_run_class);
1035         if let Some(sym) = self.in_function {
1036             let mut b = self.syms[sym.0 as usize].borrow_mut();
1037             if let SymDecl::UserFunction(_, ref mut run_class) = b.decl {
1038                 *run_class = run_class.merge(new_run_class);
1039             }
1040         }
1041     }
1042 
function_definition(&self, name: SymRef) -> Option<(Rc<FunctionDefinition>, RunClass)>1043     pub fn function_definition(&self, name: SymRef) -> Option<(Rc<FunctionDefinition>, RunClass)> {
1044         if let SymDecl::UserFunction(ref fd, ref run_class) = &self.sym(name).decl {
1045             Some((fd.clone(), *run_class))
1046         } else {
1047             None
1048         }
1049     }
1050 
merge_run_class(&self, sym: SymRef, mut new_run_class: RunClass) -> RunClass1051     fn merge_run_class(&self, sym: SymRef, mut new_run_class: RunClass) -> RunClass {
1052         if sym.0 <= self.branch_declaration.0 {
1053             new_run_class = self.branch_run_class.merge(new_run_class);
1054         }
1055         let mut b = self.syms[sym.0 as usize].borrow_mut();
1056         let mut old_run_class = new_run_class;
1057         if let SymDecl::Local(_, _, ref mut run_class) = b.decl {
1058             old_run_class = *run_class;
1059             new_run_class = old_run_class.merge(new_run_class);
1060             *run_class = new_run_class;
1061         }
1062         if old_run_class != RunClass::Unknown && old_run_class != new_run_class {
1063             self.run_class_changed.set(true);
1064         }
1065         new_run_class
1066     }
1067 }
1068 
1069 /// A declaration.
1070 #[derive(Clone, Debug, PartialEq)]
1071 pub enum Declaration {
1072     FunctionPrototype(FunctionPrototype),
1073     StructDefinition(SymRef),
1074     InitDeclaratorList(InitDeclaratorList),
1075     Precision(PrecisionQualifier, TypeSpecifier),
1076     Block(Block),
1077     Global(TypeQualifier, Vec<Identifier>),
1078 }
1079 
1080 /// A general purpose block, containing fields and possibly a list of declared identifiers. Semantic
1081 /// is given with the storage qualifier.
1082 #[derive(Clone, Debug, PartialEq)]
1083 pub struct Block {
1084     pub qualifier: TypeQualifier,
1085     pub name: Identifier,
1086     pub fields: Vec<StructFieldSpecifier>,
1087     pub identifier: Option<ArrayedIdentifier>,
1088 }
1089 
1090 /// Function identifier.
1091 #[derive(Clone, Debug, PartialEq)]
1092 pub enum FunIdentifier {
1093     Identifier(SymRef),
1094     Constructor(Type),
1095 }
1096 
1097 /// Function prototype.
1098 #[derive(Clone, Debug, PartialEq)]
1099 pub struct FunctionPrototype {
1100     pub ty: Type,
1101     pub name: Identifier,
1102     pub parameters: Vec<FunctionParameterDeclaration>,
1103 }
1104 
1105 impl FunctionPrototype {
has_parameter(&self, sym: SymRef) -> bool1106     pub fn has_parameter(&self, sym: SymRef) -> bool {
1107         for param in &self.parameters {
1108             match param {
1109                 FunctionParameterDeclaration::Named(_, ref d) => {
1110                     if d.sym == sym {
1111                         return true;
1112                     }
1113                 }
1114                 _ => {}
1115             }
1116         }
1117         false
1118     }
1119 }
1120 
1121 /// Function parameter declaration.
1122 #[derive(Clone, Debug, PartialEq)]
1123 pub enum FunctionParameterDeclaration {
1124     Named(Option<ParameterQualifier>, FunctionParameterDeclarator),
1125     Unnamed(Option<ParameterQualifier>, TypeSpecifier),
1126 }
1127 
1128 /// Function parameter declarator.
1129 #[derive(Clone, Debug, PartialEq)]
1130 pub struct FunctionParameterDeclarator {
1131     pub ty: Type,
1132     pub name: Identifier,
1133     pub sym: SymRef,
1134 }
1135 
1136 /// Init declarator list.
1137 #[derive(Clone, Debug, PartialEq)]
1138 pub struct InitDeclaratorList {
1139     // XXX it feels like separating out the type and the names is better than
1140     // head and tail
1141     // Also, it might be nice to separate out type definitions from name definitions
1142     pub head: SingleDeclaration,
1143     pub tail: Vec<SingleDeclarationNoType>,
1144 }
1145 
1146 /// Type qualifier.
1147 #[derive(Clone, Debug, PartialEq)]
1148 pub struct TypeQualifier {
1149     pub qualifiers: NonEmpty<TypeQualifierSpec>,
1150 }
1151 
lift_type_qualifier_for_declaration( _state: &mut State, q: &Option<syntax::TypeQualifier>, ) -> Option<TypeQualifier>1152 fn lift_type_qualifier_for_declaration(
1153     _state: &mut State,
1154     q: &Option<syntax::TypeQualifier>,
1155 ) -> Option<TypeQualifier> {
1156     q.as_ref().and_then(|x| {
1157         NonEmpty::from_non_empty_iter(x.qualifiers.0.iter().flat_map(|x| match x {
1158             syntax::TypeQualifierSpec::Precision(_) => None,
1159             syntax::TypeQualifierSpec::Interpolation(_) => None,
1160             syntax::TypeQualifierSpec::Invariant => Some(TypeQualifierSpec::Invariant),
1161             syntax::TypeQualifierSpec::Layout(l) => Some(TypeQualifierSpec::Layout(l.clone())),
1162             syntax::TypeQualifierSpec::Precise => Some(TypeQualifierSpec::Precise),
1163             syntax::TypeQualifierSpec::Storage(_) => None,
1164         }))
1165         .map(|x| TypeQualifier { qualifiers: x })
1166     })
1167 }
1168 
lift_type_qualifier_for_parameter( _state: &mut State, q: &Option<syntax::TypeQualifier>, ) -> Option<ParameterQualifier>1169 fn lift_type_qualifier_for_parameter(
1170     _state: &mut State,
1171     q: &Option<syntax::TypeQualifier>,
1172 ) -> Option<ParameterQualifier> {
1173     let mut qp: Option<ParameterQualifier> = None;
1174     if let Some(q) = q {
1175         for x in &q.qualifiers.0 {
1176             match (&qp, x) {
1177                 (None, syntax::TypeQualifierSpec::Storage(s)) => match s {
1178                     syntax::StorageQualifier::Const => qp = Some(ParameterQualifier::Const),
1179                     syntax::StorageQualifier::In => qp = Some(ParameterQualifier::In),
1180                     syntax::StorageQualifier::Out => qp = Some(ParameterQualifier::Out),
1181                     syntax::StorageQualifier::InOut => qp = Some(ParameterQualifier::InOut),
1182                     _ => panic!("Bad storage qualifier for parameter"),
1183                 },
1184                 (_, syntax::TypeQualifierSpec::Precision(_)) => {}
1185                 _ => panic!("Bad parameter qualifier {:?}", x),
1186             }
1187         }
1188     }
1189     qp
1190 }
1191 
1192 #[derive(Clone, Debug, PartialEq)]
1193 pub enum ParameterQualifier {
1194     Const,
1195     In,
1196     InOut,
1197     Out,
1198 }
1199 
1200 #[derive(Clone, Debug, PartialEq)]
1201 pub enum MemoryQualifier {
1202     Coherent,
1203     Volatile,
1204     Restrict,
1205     ReadOnly,
1206     WriteOnly,
1207 }
1208 
1209 /// Type qualifier spec.
1210 #[derive(Clone, Debug, PartialEq)]
1211 pub enum TypeQualifierSpec {
1212     Layout(syntax::LayoutQualifier),
1213     Invariant,
1214     Parameter(ParameterQualifier),
1215     Memory(MemoryQualifier),
1216     Precise,
1217 }
1218 
1219 /// Single declaration.
1220 #[derive(Clone, Debug, PartialEq)]
1221 pub struct SingleDeclaration {
1222     pub ty: Type,
1223     pub ty_def: Option<SymRef>,
1224     pub qualifier: Option<TypeQualifier>,
1225     pub name: SymRef,
1226     pub initializer: Option<Initializer>,
1227 }
1228 
1229 /// A single declaration with implicit, already-defined type.
1230 #[derive(Clone, Debug, PartialEq)]
1231 pub struct SingleDeclarationNoType {
1232     pub ident: ArrayedIdentifier,
1233     pub initializer: Option<Initializer>,
1234 }
1235 
1236 /// Initializer.
1237 #[derive(Clone, Debug, PartialEq)]
1238 pub enum Initializer {
1239     Simple(Box<Expr>),
1240     List(NonEmpty<Initializer>),
1241 }
1242 
1243 impl From<Expr> for Initializer {
from(e: Expr) -> Self1244     fn from(e: Expr) -> Self {
1245         Initializer::Simple(Box::new(e))
1246     }
1247 }
1248 
1249 #[derive(Clone, Debug, PartialEq)]
1250 pub struct Expr {
1251     pub kind: ExprKind,
1252     pub ty: Type,
1253 }
1254 
1255 #[derive(Clone, Debug, PartialEq)]
1256 pub enum FieldSet {
1257     Rgba,
1258     Xyzw,
1259     Stpq,
1260 }
1261 
1262 #[derive(Clone, Debug, PartialEq)]
1263 pub struct SwizzleSelector {
1264     pub field_set: FieldSet,
1265     pub components: Vec<i8>,
1266 }
1267 
1268 impl SwizzleSelector {
parse(s: &str) -> Self1269     fn parse(s: &str) -> Self {
1270         let mut components = Vec::new();
1271         let mut field_set = Vec::new();
1272 
1273         for c in s.chars() {
1274             match c {
1275                 'r' => {
1276                     components.push(0);
1277                     field_set.push(FieldSet::Rgba);
1278                 }
1279                 'x' => {
1280                     components.push(0);
1281                     field_set.push(FieldSet::Xyzw);
1282                 }
1283                 's' => {
1284                     components.push(0);
1285                     field_set.push(FieldSet::Stpq);
1286                 }
1287 
1288                 'g' => {
1289                     components.push(1);
1290                     field_set.push(FieldSet::Rgba);
1291                 }
1292                 'y' => {
1293                     components.push(1);
1294                     field_set.push(FieldSet::Xyzw);
1295                 }
1296                 't' => {
1297                     components.push(1);
1298                     field_set.push(FieldSet::Stpq);
1299                 }
1300 
1301                 'b' => {
1302                     components.push(2);
1303                     field_set.push(FieldSet::Rgba);
1304                 }
1305                 'z' => {
1306                     components.push(2);
1307                     field_set.push(FieldSet::Xyzw);
1308                 }
1309                 'p' => {
1310                     components.push(2);
1311                     field_set.push(FieldSet::Stpq);
1312                 }
1313 
1314                 'a' => {
1315                     components.push(3);
1316                     field_set.push(FieldSet::Rgba);
1317                 }
1318                 'w' => {
1319                     components.push(3);
1320                     field_set.push(FieldSet::Xyzw);
1321                 }
1322                 'q' => {
1323                     components.push(3);
1324                     field_set.push(FieldSet::Stpq);
1325                 }
1326                 _ => panic!("bad selector"),
1327             }
1328         }
1329 
1330         let first = &field_set[0];
1331         assert!(field_set.iter().all(|item| item == first));
1332         assert!(components.len() <= 4);
1333         SwizzleSelector {
1334             field_set: first.clone(),
1335             components,
1336         }
1337     }
1338 
to_string(&self) -> String1339     pub fn to_string(&self) -> String {
1340         let mut s = String::new();
1341         let fs = match self.field_set {
1342             FieldSet::Rgba => ['r', 'g', 'b', 'a'],
1343             FieldSet::Xyzw => ['x', 'y', 'z', 'w'],
1344             FieldSet::Stpq => ['s', 't', 'p', 'q'],
1345         };
1346         for i in &self.components {
1347             s.push(fs[*i as usize])
1348         }
1349         s
1350     }
1351 }
1352 
1353 /// The most general form of an expression. As you can see if you read the variant list, in GLSL, an
1354 /// assignment is an expression. This is a bit silly but think of an assignment as a statement first
1355 /// then an expression which evaluates to what the statement “returns”.
1356 ///
1357 /// An expression is either an assignment or a list (comma) of assignments.
1358 #[derive(Clone, Debug, PartialEq)]
1359 pub enum ExprKind {
1360     /// A variable expression, using an identifier.
1361     Variable(SymRef),
1362     /// Integral constant expression.
1363     IntConst(i32),
1364     /// Unsigned integral constant expression.
1365     UIntConst(u32),
1366     /// Boolean constant expression.
1367     BoolConst(bool),
1368     /// Single precision floating expression.
1369     FloatConst(f32),
1370     /// Double precision floating expression.
1371     DoubleConst(f64),
1372     /// A unary expression, gathering a single expression and a unary operator.
1373     Unary(UnaryOp, Box<Expr>),
1374     /// A binary expression, gathering two expressions and a binary operator.
1375     Binary(BinaryOp, Box<Expr>, Box<Expr>),
1376     /// A ternary conditional expression, gathering three expressions.
1377     Ternary(Box<Expr>, Box<Expr>, Box<Expr>),
1378     /// An assignment is also an expression. Gathers an expression that defines what to assign to, an
1379     /// assignment operator and the value to associate with.
1380     Assignment(Box<Expr>, AssignmentOp, Box<Expr>),
1381     /// Add an array specifier to an expression.
1382     Bracket(Box<Expr>, Box<Expr>),
1383     /// A functional call. It has a function identifier and a list of expressions (arguments).
1384     FunCall(FunIdentifier, Vec<Expr>),
1385     /// An expression associated with a field selection (struct).
1386     Dot(Box<Expr>, Identifier),
1387     /// An expression associated with a component selection
1388     SwizzleSelector(Box<Expr>, SwizzleSelector),
1389     /// Post-incrementation of an expression.
1390     PostInc(Box<Expr>),
1391     /// Post-decrementation of an expression.
1392     PostDec(Box<Expr>),
1393     /// An expression that contains several, separated with comma.
1394     Comma(Box<Expr>, Box<Expr>),
1395     /// A temporary condition variable
1396     Cond(usize, Box<Expr>),
1397     CondMask,
1398 }
1399 
1400 /*
1401 impl From<i32> for Expr {
1402     fn from(x: i32) -> Expr {
1403         ExprKind::IntConst(x)
1404     }
1405 }
1406 
1407 impl From<u32> for Expr {
1408     fn from(x: u32) -> Expr {
1409         Expr::UIntConst(x)
1410     }
1411 }
1412 
1413 impl From<bool> for Expr {
1414     fn from(x: bool) -> Expr {
1415         Expr::BoolConst(x)
1416     }
1417 }
1418 
1419 impl From<f32> for Expr {
1420     fn from(x: f32) -> Expr {
1421         Expr::FloatConst(x)
1422     }
1423 }
1424 
1425 impl From<f64> for Expr {
1426     fn from(x: f64) -> Expr {
1427         Expr::DoubleConst(x)
1428     }
1429 }
1430 */
1431 /// Starting rule.
1432 #[derive(Clone, Debug, PartialEq)]
1433 pub struct TranslationUnit(pub NonEmpty<ExternalDeclaration>);
1434 
1435 impl TranslationUnit {
1436     /// Construct a translation unit from an iterator.
1437     ///
1438     /// # Errors
1439     ///
1440     /// `None` if the iterator yields no value.
from_iter<I>(iter: I) -> Option<Self> where I: IntoIterator<Item = ExternalDeclaration>,1441     pub fn from_iter<I>(iter: I) -> Option<Self>
1442     where
1443         I: IntoIterator<Item = ExternalDeclaration>,
1444     {
1445         NonEmpty::from_non_empty_iter(iter).map(TranslationUnit)
1446     }
1447 }
1448 
1449 impl Deref for TranslationUnit {
1450     type Target = NonEmpty<ExternalDeclaration>;
1451 
deref(&self) -> &Self::Target1452     fn deref(&self) -> &Self::Target {
1453         &self.0
1454     }
1455 }
1456 
1457 impl DerefMut for TranslationUnit {
deref_mut(&mut self) -> &mut Self::Target1458     fn deref_mut(&mut self) -> &mut Self::Target {
1459         &mut self.0
1460     }
1461 }
1462 
1463 impl IntoIterator for TranslationUnit {
1464     type IntoIter = <NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1465     type Item = ExternalDeclaration;
1466 
into_iter(self) -> Self::IntoIter1467     fn into_iter(self) -> Self::IntoIter {
1468         self.0.into_iter()
1469     }
1470 }
1471 
1472 impl<'a> IntoIterator for &'a TranslationUnit {
1473     type IntoIter = <&'a NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1474     type Item = &'a ExternalDeclaration;
1475 
into_iter(self) -> Self::IntoIter1476     fn into_iter(self) -> Self::IntoIter {
1477         (&self.0).into_iter()
1478     }
1479 }
1480 
1481 impl<'a> IntoIterator for &'a mut TranslationUnit {
1482     type IntoIter = <&'a mut NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1483     type Item = &'a mut ExternalDeclaration;
1484 
into_iter(self) -> Self::IntoIter1485     fn into_iter(self) -> Self::IntoIter {
1486         (&mut self.0).into_iter()
1487     }
1488 }
1489 
1490 /// External declaration.
1491 #[derive(Clone, Debug, PartialEq)]
1492 pub enum ExternalDeclaration {
1493     Preprocessor(syntax::Preprocessor),
1494     FunctionDefinition(Rc<FunctionDefinition>),
1495     Declaration(Declaration),
1496 }
1497 
1498 /// Function definition.
1499 #[derive(Clone, Debug, PartialEq)]
1500 pub struct FunctionDefinition {
1501     pub prototype: FunctionPrototype,
1502     pub body: CompoundStatement,
1503     pub globals: Vec<SymRef>,
1504     pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>,
1505 }
1506 
1507 /// Compound statement (with no new scope).
1508 #[derive(Clone, Debug, PartialEq)]
1509 pub struct CompoundStatement {
1510     pub statement_list: Vec<Statement>,
1511 }
1512 
1513 impl CompoundStatement {
new() -> Self1514     pub fn new() -> Self {
1515         CompoundStatement {
1516             statement_list: Vec::new(),
1517         }
1518     }
1519 }
1520 
1521 impl FromIterator<Statement> for CompoundStatement {
from_iter<T>(iter: T) -> Self where T: IntoIterator<Item = Statement>,1522     fn from_iter<T>(iter: T) -> Self
1523     where
1524         T: IntoIterator<Item = Statement>,
1525     {
1526         CompoundStatement {
1527             statement_list: iter.into_iter().collect(),
1528         }
1529     }
1530 }
1531 
1532 /// Statement.
1533 #[derive(Clone, Debug, PartialEq)]
1534 pub enum Statement {
1535     Compound(Box<CompoundStatement>),
1536     Simple(Box<SimpleStatement>),
1537 }
1538 
1539 /// Simple statement.
1540 #[derive(Clone, Debug, PartialEq)]
1541 pub enum SimpleStatement {
1542     Declaration(Declaration),
1543     Expression(ExprStatement),
1544     Selection(SelectionStatement),
1545     Switch(SwitchStatement),
1546     Iteration(IterationStatement),
1547     Jump(JumpStatement),
1548 }
1549 
1550 impl SimpleStatement {
1551     /// Create a new expression statement.
new_expr<E>(expr: E) -> Self where E: Into<Expr>,1552     pub fn new_expr<E>(expr: E) -> Self
1553     where
1554         E: Into<Expr>,
1555     {
1556         SimpleStatement::Expression(Some(expr.into()))
1557     }
1558 
1559     /// Create a new selection statement (if / else).
new_if_else<If, True, False>(ife: If, truee: True, falsee: False) -> Self where If: Into<Expr>, True: Into<Statement>, False: Into<Statement>,1560     pub fn new_if_else<If, True, False>(ife: If, truee: True, falsee: False) -> Self
1561     where
1562         If: Into<Expr>,
1563         True: Into<Statement>,
1564         False: Into<Statement>,
1565     {
1566         SimpleStatement::Selection(SelectionStatement {
1567             cond: Box::new(ife.into()),
1568             body: Box::new(truee.into()),
1569             else_stmt: Some(Box::new(falsee.into())),
1570         })
1571     }
1572 
1573     /// Create a new while statement.
new_while<C, S>(cond: C, body: S) -> Self where C: Into<Condition>, S: Into<Statement>,1574     pub fn new_while<C, S>(cond: C, body: S) -> Self
1575     where
1576         C: Into<Condition>,
1577         S: Into<Statement>,
1578     {
1579         SimpleStatement::Iteration(IterationStatement::While(
1580             cond.into(),
1581             Box::new(body.into()),
1582         ))
1583     }
1584 
1585     /// Create a new do-while statement.
new_do_while<C, S>(body: S, cond: C) -> Self where S: Into<Statement>, C: Into<Expr>,1586     pub fn new_do_while<C, S>(body: S, cond: C) -> Self
1587     where
1588         S: Into<Statement>,
1589         C: Into<Expr>,
1590     {
1591         SimpleStatement::Iteration(IterationStatement::DoWhile(
1592             Box::new(body.into()),
1593             Box::new(cond.into()),
1594         ))
1595     }
1596 }
1597 
1598 /// Expression statement.
1599 pub type ExprStatement = Option<Expr>;
1600 
1601 /// Selection statement.
1602 #[derive(Clone, Debug, PartialEq)]
1603 pub struct SelectionStatement {
1604     pub cond: Box<Expr>,
1605     pub body: Box<Statement>,
1606     // the else branch
1607     pub else_stmt: Option<Box<Statement>>,
1608 }
1609 
1610 /// Condition.
1611 #[derive(Clone, Debug, PartialEq)]
1612 pub enum Condition {
1613     Expr(Box<Expr>),
1614 }
1615 
1616 impl From<Expr> for Condition {
from(expr: Expr) -> Self1617     fn from(expr: Expr) -> Self {
1618         Condition::Expr(Box::new(expr))
1619     }
1620 }
1621 
1622 /// Switch statement.
1623 #[derive(Clone, Debug, PartialEq)]
1624 pub struct SwitchStatement {
1625     pub head: Box<Expr>,
1626     pub cases: Vec<Case>,
1627 }
1628 
1629 /// Case label statement.
1630 #[derive(Clone, Debug, PartialEq)]
1631 pub enum CaseLabel {
1632     Case(Box<Expr>),
1633     Def,
1634 }
1635 
1636 /// An individual case
1637 #[derive(Clone, Debug, PartialEq)]
1638 pub struct Case {
1639     pub label: CaseLabel,
1640     pub stmts: Vec<Statement>,
1641 }
1642 
1643 /// Iteration statement.
1644 #[derive(Clone, Debug, PartialEq)]
1645 pub enum IterationStatement {
1646     While(Condition, Box<Statement>),
1647     DoWhile(Box<Statement>, Box<Expr>),
1648     For(ForInitStatement, ForRestStatement, Box<Statement>),
1649 }
1650 
1651 /// For init statement.
1652 #[derive(Clone, Debug, PartialEq)]
1653 pub enum ForInitStatement {
1654     Expression(Option<Expr>),
1655     Declaration(Box<Declaration>),
1656 }
1657 
1658 /// For init statement.
1659 #[derive(Clone, Debug, PartialEq)]
1660 pub struct ForRestStatement {
1661     pub condition: Option<Condition>,
1662     pub post_expr: Option<Box<Expr>>,
1663 }
1664 
1665 /// Jump statement.
1666 #[derive(Clone, Debug, PartialEq)]
1667 pub enum JumpStatement {
1668     Continue,
1669     Break,
1670     Return(Option<Box<Expr>>),
1671     Discard,
1672 }
1673 
1674 trait NonEmptyExt<T> {
map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>1675     fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>;
new(x: T) -> NonEmpty<T>1676     fn new(x: T) -> NonEmpty<T>;
1677 }
1678 
1679 impl<T> NonEmptyExt<T> for NonEmpty<T> {
map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, mut f: F) -> NonEmpty<U>1680     fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, mut f: F) -> NonEmpty<U> {
1681         NonEmpty::from_non_empty_iter(self.into_iter().map(|x| f(s, &x))).unwrap()
1682     }
new(x: T) -> NonEmpty<T>1683     fn new(x: T) -> NonEmpty<T> {
1684         NonEmpty::from_non_empty_iter(vec![x].into_iter()).unwrap()
1685     }
1686 }
1687 
translate_initializater(state: &mut State, i: &syntax::Initializer) -> Initializer1688 fn translate_initializater(state: &mut State, i: &syntax::Initializer) -> Initializer {
1689     match i {
1690         syntax::Initializer::Simple(i) => {
1691             Initializer::Simple(Box::new(translate_expression(state, i)))
1692         }
1693         _ => panic!(),
1694     }
1695 }
1696 
translate_struct_declaration(state: &mut State, d: &syntax::SingleDeclaration) -> Declaration1697 fn translate_struct_declaration(state: &mut State, d: &syntax::SingleDeclaration) -> Declaration {
1698     let ty = d.ty.clone();
1699     let ty_def = match &ty.ty.ty {
1700         TypeSpecifierNonArray::Struct(s) => {
1701             let decl = SymDecl::Struct(lift(state, s));
1702             Some(state.declare(s.name.as_ref().unwrap().as_str(), decl))
1703         }
1704         _ => None,
1705     };
1706 
1707     let ty_def = ty_def.expect("Must be type definition");
1708 
1709     Declaration::StructDefinition(ty_def)
1710 }
1711 
get_expr_index(e: &syntax::Expr) -> i321712 fn get_expr_index(e: &syntax::Expr) -> i32 {
1713     match e {
1714         syntax::Expr::IntConst(i) => *i,
1715         syntax::Expr::UIntConst(u) => *u as i32,
1716         syntax::Expr::FloatConst(f) => *f as i32,
1717         syntax::Expr::DoubleConst(f) => *f as i32,
1718         _ => panic!(),
1719     }
1720 }
1721 
translate_variable_declaration( state: &mut State, d: &syntax::InitDeclaratorList, default_run_class: RunClass, ) -> Declaration1722 fn translate_variable_declaration(
1723     state: &mut State,
1724     d: &syntax::InitDeclaratorList,
1725     default_run_class: RunClass,
1726 ) -> Declaration {
1727     let mut ty = d.head.ty.clone();
1728     ty.ty.array_specifier = d.head.array_specifier.clone();
1729     let ty_def = match &ty.ty.ty {
1730         TypeSpecifierNonArray::Struct(s) => {
1731             let decl = SymDecl::Struct(lift(state, s));
1732             Some(state.declare(s.name.as_ref().unwrap().as_str(), decl))
1733         }
1734         _ => None,
1735     };
1736 
1737     let mut ty: Type = lift(state, &d.head.ty);
1738     if let Some(array) = &d.head.array_specifier {
1739         ty.array_sizes = Some(Box::new(lift(state, array)))
1740     }
1741 
1742     let (sym, decl) = match d.head.name.as_ref() {
1743         Some(name) => {
1744             let mut storage = StorageClass::None;
1745             let mut interpolation = None;
1746             for qual in d
1747                 .head
1748                 .ty
1749                 .qualifier
1750                 .iter()
1751                 .flat_map(|x| x.qualifiers.0.iter())
1752             {
1753                 match qual {
1754                     syntax::TypeQualifierSpec::Storage(s) => match (&storage, s) {
1755                         (StorageClass::FragColor(..), syntax::StorageQualifier::Out) => {}
1756                         (StorageClass::Sampler(..), syntax::StorageQualifier::Uniform) => {}
1757                         (StorageClass::None, syntax::StorageQualifier::Out) => {
1758                             storage = StorageClass::Out;
1759                         }
1760                         (StorageClass::None, syntax::StorageQualifier::In) => {
1761                             storage = StorageClass::In;
1762                         }
1763                         (StorageClass::None, syntax::StorageQualifier::Uniform) => {
1764                             if ty.kind.is_sampler() {
1765                                 storage = StorageClass::Sampler(SamplerFormat::Unknown);
1766                             } else {
1767                                 storage = StorageClass::Uniform;
1768                             }
1769                         }
1770                         (StorageClass::None, syntax::StorageQualifier::Const) => {
1771                             storage = StorageClass::Const;
1772                         }
1773                         _ => panic!("bad storage {:?}", (storage, s)),
1774                     },
1775                     syntax::TypeQualifierSpec::Interpolation(i) => match (&interpolation, i) {
1776                         (None, i) => interpolation = Some(i.clone()),
1777                         _ => panic!("multiple interpolation"),
1778                     },
1779                     syntax::TypeQualifierSpec::Layout(l) => {
1780                         let mut loc = -1;
1781                         let mut index = -1;
1782                         for id in &l.ids {
1783                             match id {
1784                                 syntax::LayoutQualifierSpec::Identifier(ref key, None) => {
1785                                     match key.as_str() {
1786                                         "rgba8" => {
1787                                             storage = StorageClass::Sampler(SamplerFormat::RGBA8);
1788                                         }
1789                                         "rgba32f" => {
1790                                             storage = StorageClass::Sampler(SamplerFormat::RGBA32F);
1791                                         }
1792                                         "rgba32i" => {
1793                                             storage = StorageClass::Sampler(SamplerFormat::RGBA32I);
1794                                         }
1795                                         "r8" => {
1796                                             storage = StorageClass::Sampler(SamplerFormat::R8);
1797                                         }
1798                                         "rg8" => {
1799                                             storage = StorageClass::Sampler(SamplerFormat::RG8);
1800                                         }
1801                                         _ => {}
1802                                     }
1803                                 }
1804                                 syntax::LayoutQualifierSpec::Identifier(ref key, Some(ref e)) => {
1805                                     match key.as_str() {
1806                                         "location" => {
1807                                             loc = get_expr_index(e);
1808                                         }
1809                                         "index" => {
1810                                             index = get_expr_index(e);
1811                                         }
1812                                         _ => {}
1813                                     }
1814                                 }
1815                                 _ => {}
1816                             }
1817                         }
1818                         if index >= 0 {
1819                             assert!(loc == 0);
1820                             assert!(index <= 1);
1821                             assert!(storage == StorageClass::None);
1822                             storage = StorageClass::FragColor(index);
1823                         }
1824                     }
1825                     _ => {}
1826                 }
1827             }
1828             let decl = if state.in_function.is_some() {
1829                 let run_class = match storage {
1830                     StorageClass::Const => RunClass::Scalar,
1831                     StorageClass::None => default_run_class,
1832                     _ => panic!("bad local storage {:?}", storage),
1833                 };
1834                 SymDecl::Local(storage, ty.clone(), run_class)
1835             } else {
1836                 let run_class = match storage {
1837                     StorageClass::Const | StorageClass::Uniform | StorageClass::Sampler(..) => {
1838                         RunClass::Scalar
1839                     }
1840                     StorageClass::In | StorageClass::Out | StorageClass::FragColor(..)
1841                         if interpolation == Some(syntax::InterpolationQualifier::Flat) =>
1842                     {
1843                         RunClass::Scalar
1844                     }
1845                     _ => RunClass::Vector,
1846                 };
1847                 SymDecl::Global(storage, interpolation, ty.clone(), run_class)
1848             };
1849             (state.declare(name.as_str(), decl.clone()), decl)
1850         }
1851         None => panic!(),
1852     };
1853 
1854     let head = SingleDeclaration {
1855         qualifier: lift_type_qualifier_for_declaration(state, &d.head.ty.qualifier),
1856         name: sym,
1857         ty,
1858         ty_def,
1859         initializer: d
1860             .head
1861             .initializer
1862             .as_ref()
1863             .map(|x| translate_initializater(state, x)),
1864     };
1865 
1866     let tail = d
1867         .tail
1868         .iter()
1869         .map(|d| {
1870             if let Some(_array) = &d.ident.array_spec {
1871                 panic!("unhandled array")
1872             }
1873             state.declare(d.ident.ident.as_str(), decl.clone());
1874             SingleDeclarationNoType {
1875                 ident: d.ident.clone(),
1876                 initializer: d
1877                     .initializer
1878                     .as_ref()
1879                     .map(|x| translate_initializater(state, x)),
1880             }
1881         })
1882         .collect();
1883     Declaration::InitDeclaratorList(InitDeclaratorList { head, tail })
1884 }
1885 
translate_init_declarator_list( state: &mut State, l: &syntax::InitDeclaratorList, default_run_class: RunClass, ) -> Declaration1886 fn translate_init_declarator_list(
1887     state: &mut State,
1888     l: &syntax::InitDeclaratorList,
1889     default_run_class: RunClass,
1890 ) -> Declaration {
1891     match &l.head.name {
1892         Some(_name) => translate_variable_declaration(state, l, default_run_class),
1893         None => translate_struct_declaration(state, &l.head),
1894     }
1895 }
1896 
translate_declaration( state: &mut State, d: &syntax::Declaration, default_run_class: RunClass, ) -> Declaration1897 fn translate_declaration(
1898     state: &mut State,
1899     d: &syntax::Declaration,
1900     default_run_class: RunClass,
1901 ) -> Declaration {
1902     match d {
1903         syntax::Declaration::Block(_) => panic!(), //Declaration::Block(..),
1904         syntax::Declaration::FunctionPrototype(p) => {
1905             Declaration::FunctionPrototype(translate_function_prototype(state, p))
1906         }
1907         syntax::Declaration::Global(ty, ids) => {
1908             // glsl non-es supports requalifying variables, but we don't yet.
1909             // However, we still want to allow global layout qualifiers for
1910             // KHR_advanced_blend_equation.
1911             if !ids.is_empty() {
1912                 panic!();
1913             }
1914             let _ = for qual in &ty.qualifiers {
1915                 match qual {
1916                     syntax::TypeQualifierSpec::Layout(l) => {
1917                         for id in &l.ids {
1918                             match id {
1919                                 syntax::LayoutQualifierSpec::Identifier(key, _) => {
1920                                     match key.as_str() {
1921                                         "blend_support_all_equations" => (),
1922                                         _ => panic!(),
1923                                     }
1924                                 }
1925                                 _ => panic!(),
1926                             }
1927                         }
1928                     }
1929                     syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Out) => (),
1930                     _ => panic!(),
1931                 }
1932             };
1933             Declaration::Global(lift_type_qualifier_for_declaration(state, &Some(ty.clone())).unwrap(), ids.clone())
1934         }
1935         syntax::Declaration::InitDeclaratorList(dl) => {
1936             translate_init_declarator_list(state, dl, default_run_class)
1937         }
1938         syntax::Declaration::Precision(p, ts) => Declaration::Precision(p.clone(), ts.clone()),
1939     }
1940 }
1941 
is_vector(ty: &Type) -> bool1942 fn is_vector(ty: &Type) -> bool {
1943     match ty.kind {
1944         TypeKind::Vec2
1945         | TypeKind::Vec3
1946         | TypeKind::Vec4
1947         | TypeKind::BVec2
1948         | TypeKind::BVec3
1949         | TypeKind::BVec4
1950         | TypeKind::IVec2
1951         | TypeKind::IVec3
1952         | TypeKind::IVec4 => ty.array_sizes == None,
1953         _ => false,
1954     }
1955 }
1956 
index_vector(ty: &Type) -> Option<TypeKind>1957 fn index_vector(ty: &Type) -> Option<TypeKind> {
1958     use TypeKind::*;
1959     if ty.array_sizes != None {
1960         return None;
1961     }
1962     Some(match ty.kind {
1963         Vec2 => Float,
1964         Vec3 => Float,
1965         Vec4 => Float,
1966         DVec2 => Double,
1967         DVec3 => Double,
1968         DVec4 => Double,
1969         BVec2 => Bool,
1970         BVec3 => Bool,
1971         BVec4 => Bool,
1972         IVec2 => Int,
1973         IVec3 => Int,
1974         IVec4 => Int,
1975         UVec2 => UInt,
1976         UVec3 => UInt,
1977         UVec4 => UInt,
1978         _ => return None,
1979     })
1980 
1981 }
1982 
index_matrix(ty: &Type) -> Option<TypeKind>1983 fn index_matrix(ty: &Type) -> Option<TypeKind> {
1984     use TypeKind::*;
1985     if ty.array_sizes != None {
1986         return None;
1987     }
1988     Some(match ty.kind {
1989         Mat2 => Vec2,
1990         Mat3 => Vec3,
1991         Mat4 => Vec4,
1992         Mat23 => Vec3,
1993         Mat24 => Vec4,
1994         Mat32 => Vec2,
1995         Mat34 => Vec4,
1996         Mat42 => Vec2,
1997         Mat43 => Vec3,
1998         DMat2 => DVec2,
1999         DMat3 => DVec3,
2000         DMat4 => DVec4,
2001         DMat23 => DVec3,
2002         DMat24 => DVec4,
2003         DMat32 => DVec2,
2004         DMat34 => DVec4,
2005         DMat42 => DVec2,
2006         DMat43 => DVec3,
2007         _ => return None,
2008     })
2009 }
2010 
is_ivec(ty: &Type) -> bool2011 fn is_ivec(ty: &Type) -> bool {
2012     match ty.kind {
2013         TypeKind::IVec2 | TypeKind::IVec3 | TypeKind::IVec4 => ty.array_sizes == None,
2014         _ => false,
2015     }
2016 }
2017 
can_implicitly_convert_to(src: &Type, dst: &Type) -> bool2018 fn can_implicitly_convert_to(src: &Type, dst: &Type) -> bool {
2019     // XXX: use an underlying type helper
2020     if src == &Type::new(TypeKind::Double) && dst == &Type::new(TypeKind::Float) {
2021         // We're not supposed to implicitly convert from double to float but glsl 4 has a bug
2022         // where it parses unannotated float constants as double.
2023         true
2024     } else if dst == &Type::new(TypeKind::Double) && src == &Type::new(TypeKind::Float) {
2025         true
2026     } else if (dst == &Type::new(TypeKind::Float) || dst == &Type::new(TypeKind::Double)) &&
2027         src == &Type::new(TypeKind::Int)
2028     {
2029         true
2030     } else if (dst == &Type::new(TypeKind::Vec2) || dst == &Type::new(TypeKind::DVec2)) &&
2031         src == &Type::new(TypeKind::IVec2)
2032     {
2033         true
2034     } else if dst == &Type::new(TypeKind::IVec2) &&
2035         (src == &Type::new(TypeKind::Vec2) || src == &Type::new(TypeKind::DVec2))
2036     {
2037         true
2038     } else {
2039         src.kind == dst.kind && src.array_sizes == dst.array_sizes
2040     }
2041 }
2042 
promoted_type(lhs: &Type, rhs: &Type) -> Type2043 fn promoted_type(lhs: &Type, rhs: &Type) -> Type {
2044     if lhs == &Type::new(TypeKind::Double) && rhs == &Type::new(TypeKind::Float) {
2045         Type::new(TypeKind::Double)
2046     } else if lhs == &Type::new(TypeKind::Float) && rhs == &Type::new(TypeKind::Double) {
2047         Type::new(TypeKind::Double)
2048     } else if lhs == &Type::new(TypeKind::Int) && rhs == &Type::new(TypeKind::Double) {
2049         Type::new(TypeKind::Double)
2050     } else if is_vector(&lhs) &&
2051         (rhs == &Type::new(TypeKind::Float) ||
2052          rhs == &Type::new(TypeKind::Double) ||
2053          rhs == &Type::new(TypeKind::Int))
2054     {
2055         // scalars promote to vectors
2056         lhs.clone()
2057     } else if is_vector(&rhs) &&
2058         (lhs == &Type::new(TypeKind::Float) ||
2059          lhs == &Type::new(TypeKind::Double) ||
2060          lhs == &Type::new(TypeKind::Int))
2061     {
2062         // scalars promote to vectors
2063         rhs.clone()
2064     } else if lhs == rhs {
2065         lhs.clone()
2066     } else if lhs.kind == rhs.kind {
2067         if lhs.array_sizes == rhs.array_sizes {
2068             // XXX: we need to be able to query the default precision here
2069             match (&lhs.precision, &rhs.precision) {
2070                 (Some(PrecisionQualifier::High), _) => lhs.clone(),
2071                 (_, Some(PrecisionQualifier::High)) => rhs.clone(),
2072                 (None, _) => lhs.clone(),
2073                 (_, None) => rhs.clone(),
2074                 _ => panic!("precision mismatch {:?} {:?}", lhs.precision, rhs.precision),
2075             }
2076         } else {
2077             panic!("array size mismatch")
2078         }
2079     } else {
2080         assert_eq!(lhs, rhs);
2081         lhs.clone()
2082     }
2083 }
2084 
is_output(expr: &Expr, state: &State) -> Option<SymRef>2085 pub fn is_output(expr: &Expr, state: &State) -> Option<SymRef> {
2086     match &expr.kind {
2087         ExprKind::Variable(i) => match state.sym(*i).decl {
2088             SymDecl::Global(storage, ..) => match storage {
2089                 StorageClass::In | StorageClass::Out => return Some(*i),
2090                 _ => {}
2091             },
2092             SymDecl::Local(..) => {}
2093             _ => panic!("should be variable"),
2094         },
2095         ExprKind::SwizzleSelector(e, ..) => {
2096             return is_output(e, state);
2097         }
2098         ExprKind::Bracket(e, ..) => {
2099             return is_output(e, state);
2100         }
2101         ExprKind::Dot(e, ..) => {
2102             return is_output(e, state);
2103         }
2104         _ => {}
2105     };
2106     None
2107 }
2108 
get_texel_fetch_offset( state: &State, sampler_expr: &Expr, uv_expr: &Expr, offset_expr: &Expr, ) -> Option<(SymRef, SymRef, i32, i32)>2109 pub fn get_texel_fetch_offset(
2110     state: &State,
2111     sampler_expr: &Expr,
2112     uv_expr: &Expr,
2113     offset_expr: &Expr,
2114 ) -> Option<(SymRef, SymRef, i32, i32)> {
2115     if let ExprKind::Variable(ref sampler) = &sampler_expr.kind {
2116         //if let ExprKind::Binary(BinaryOp::Add, ref lhs, ref rhs) = &uv_expr.kind {
2117         if let ExprKind::Variable(ref base) = &uv_expr.kind {
2118             if let ExprKind::FunCall(ref fun, ref args) = &offset_expr.kind {
2119                 if let FunIdentifier::Identifier(ref offset) = fun {
2120                     if state.sym(*offset).name == "ivec2" {
2121                         if let ExprKind::IntConst(ref x) = &args[0].kind {
2122                             if let ExprKind::IntConst(ref y) = &args[1].kind {
2123                                 return Some((*sampler, *base, *x, *y));
2124                             }
2125                         }
2126                     }
2127                 }
2128             }
2129         }
2130         //}
2131     }
2132     None
2133 }
2134 
make_const(t: TypeKind, v: i32) -> Expr2135 fn make_const(t: TypeKind, v: i32) -> Expr {
2136     Expr {
2137         kind: match t {
2138             TypeKind::Int => ExprKind::IntConst(v as _),
2139             TypeKind::UInt => ExprKind::UIntConst(v as _),
2140             TypeKind::Bool => ExprKind::BoolConst(v != 0),
2141             TypeKind::Float => ExprKind::FloatConst(v as _),
2142             TypeKind::Double => ExprKind::DoubleConst(v as _),
2143             _ => panic!("bad constant type"),
2144         },
2145         ty: Type::new(t),
2146     }
2147 }
2148 
2149 // Any parameters needing to convert to bool should just compare via != 0.
2150 // This ensures they get the proper all-1s pattern for C++ OpenCL vectors.
force_params_to_bool(_state: &mut State, params: &mut Vec<Expr>)2151 fn force_params_to_bool(_state: &mut State, params: &mut Vec<Expr>) {
2152     for e in params {
2153         if !e.ty.kind.is_bool() {
2154             let k = e.ty.kind;
2155             *e = Expr {
2156                 kind: ExprKind::Binary(
2157                     BinaryOp::NonEqual,
2158                     Box::new(e.clone()),
2159                     Box::new(make_const(k.to_scalar(), 0)),
2160                 ),
2161                 ty: Type::new(k.to_bool()),
2162             };
2163         }
2164     }
2165 }
2166 
2167 // Transform bool params to int, then mask off the low bit so they become 0 or 1.
2168 // C++ OpenCL vectors represent bool as all-1s patterns, which will erroneously
2169 // convert to -1 otherwise.
force_params_from_bool(state: &mut State, params: &mut Vec<Expr>)2170 fn force_params_from_bool(state: &mut State, params: &mut Vec<Expr>) {
2171     for e in params {
2172         if e.ty.kind.is_bool() {
2173             let k = e.ty.kind.to_int();
2174             let sym = state.lookup(k.glsl_primitive_type_name().unwrap()).unwrap();
2175             *e = Expr {
2176                 kind: ExprKind::Binary(
2177                     BinaryOp::BitAnd,
2178                     Box::new(Expr {
2179                         kind: ExprKind::FunCall(
2180                             FunIdentifier::Identifier(sym),
2181                             vec![e.clone()],
2182                         ),
2183                         ty: Type::new(k),
2184                     }),
2185                     Box::new(make_const(TypeKind::Int, 1)),
2186                 ),
2187                 ty: Type::new(k),
2188             };
2189         }
2190     }
2191 }
2192 
translate_expression(state: &mut State, e: &syntax::Expr) -> Expr2193 fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
2194     match e {
2195         syntax::Expr::Variable(i) => {
2196             let sym = match state.lookup(i.as_str()) {
2197                 Some(sym) => sym,
2198                 None => panic!("missing declaration {}", i.as_str()),
2199             };
2200             let ty = match &state.sym(sym).decl {
2201                 SymDecl::Global(_, _, ty, _) => {
2202                     let mut globals = state.used_globals.borrow_mut();
2203                     if !globals.contains(&sym) {
2204                         globals.push(sym);
2205                     }
2206                     ty.clone()
2207                 }
2208                 SymDecl::Local(_, ty, _) => ty.clone(),
2209                 _ => panic!("bad variable type"),
2210             };
2211             Expr {
2212                 kind: ExprKind::Variable(sym),
2213                 ty,
2214             }
2215         }
2216         syntax::Expr::Assignment(lhs, op, rhs) => {
2217             let lhs = Box::new(translate_expression(state, lhs));
2218             let rhs = Box::new(translate_expression(state, rhs));
2219             let ty = if op == &AssignmentOp::Mult {
2220                 if lhs.ty.kind == TypeKind::Vec4 && rhs.ty.kind == TypeKind::Float {
2221                     lhs.ty.clone()
2222                 } else {
2223                     promoted_type(&lhs.ty, &rhs.ty)
2224                 }
2225             } else {
2226                 promoted_type(&lhs.ty, &rhs.ty)
2227             };
2228             if let Some(global) = is_output(&lhs, state) {
2229                 let mut globals = state.modified_globals.borrow_mut();
2230                 if !globals.contains(&global) {
2231                     globals.push(global);
2232                 }
2233                 if global == state.clip_dist_sym {
2234                     if let ExprKind::Bracket(_, idx) = &lhs.kind {
2235                         // Get the constant array index used for gl_ClipDistance and add it to the used mask.
2236                         let idx = match idx.kind {
2237                             ExprKind::IntConst(idx) => idx,
2238                             ExprKind::UIntConst(idx) => idx as i32,
2239                             _ => panic!("bad index for gl_ClipDistance"),
2240                         };
2241                         assert!(idx >= 0 && idx < 4);
2242                         state.used_clip_dist |= 1 << idx;
2243                     }
2244                 }
2245             }
2246             Expr {
2247                 kind: ExprKind::Assignment(lhs, op.clone(), rhs),
2248                 ty,
2249             }
2250         }
2251         syntax::Expr::Binary(op, lhs, rhs) => {
2252             let lhs = Box::new(translate_expression(state, lhs));
2253             let rhs = Box::new(translate_expression(state, rhs));
2254             let ty = match op {
2255                 BinaryOp::Equal | BinaryOp::NonEqual | BinaryOp::GT | BinaryOp::GTE | BinaryOp::LT | BinaryOp::LTE => {
2256                     // comparison operators have a bool result
2257                     Type::new(TypeKind::Bool)
2258                 }
2259                 BinaryOp::Mult => {
2260                     match (lhs.ty.kind, rhs.ty.kind) {
2261                         (TypeKind::Mat2, TypeKind::Vec2) |
2262                         (TypeKind::Mat3, TypeKind::Vec3) |
2263                         (TypeKind::Mat3, TypeKind::Mat3) |
2264                         (TypeKind::Mat3, TypeKind::Mat43) |
2265                         (TypeKind::Mat4, TypeKind::Vec4) => rhs.ty.clone(),
2266                         (TypeKind::Mat43, TypeKind::Vec4) => Type::new(TypeKind::Vec3),
2267                         (TypeKind::Mat2, TypeKind::Float) |
2268                         (TypeKind::Mat3, TypeKind::Float) |
2269                         (TypeKind::Mat4, TypeKind::Float) => lhs.ty.clone(),
2270                         _ => promoted_type(&lhs.ty, &rhs.ty),
2271                     }
2272                 }
2273                 _ => promoted_type(&lhs.ty, &rhs.ty),
2274             };
2275 
2276             Expr {
2277                 kind: ExprKind::Binary(op.clone(), lhs, rhs),
2278                 ty,
2279             }
2280         }
2281         syntax::Expr::Unary(op, e) => {
2282             let e = Box::new(translate_expression(state, e));
2283             let ty = e.ty.clone();
2284             Expr {
2285                 kind: ExprKind::Unary(op.clone(), e),
2286                 ty,
2287             }
2288         }
2289         syntax::Expr::BoolConst(b) => Expr {
2290             kind: ExprKind::BoolConst(*b),
2291             ty: Type::new(TypeKind::Bool),
2292         },
2293         syntax::Expr::Comma(lhs, rhs) => {
2294             let lhs = Box::new(translate_expression(state, lhs));
2295             let rhs = Box::new(translate_expression(state, rhs));
2296             assert_eq!(lhs.ty, rhs.ty);
2297             let ty = lhs.ty.clone();
2298             Expr {
2299                 kind: ExprKind::Comma(lhs, rhs),
2300                 ty,
2301             }
2302         }
2303         syntax::Expr::DoubleConst(d) => Expr {
2304             kind: ExprKind::DoubleConst(*d),
2305             ty: Type::new(TypeKind::Double),
2306         },
2307         syntax::Expr::FloatConst(f) => Expr {
2308             kind: ExprKind::FloatConst(*f),
2309             ty: Type::new(TypeKind::Float),
2310         },
2311         syntax::Expr::FunCall(fun, params) => {
2312             let ret_ty: Type;
2313             let mut params: Vec<Expr> = params
2314                 .iter()
2315                 .map(|x| translate_expression(state, x))
2316                 .collect();
2317             Expr {
2318                 kind: ExprKind::FunCall(
2319                     match fun {
2320                         syntax::FunIdentifier::Identifier(i) => {
2321                             let name = i.as_str();
2322                             if name == "texelFetchOffset" && params.len() >= 4 {
2323                                 if let Some((sampler, base, x, y)) = get_texel_fetch_offset(
2324                                     state, &params[0], &params[1], &params[3],
2325                                 ) {
2326                                     if let Some(offsets) =
2327                                         state.texel_fetches.get_mut(&(sampler, base))
2328                                     {
2329                                         offsets.add_offset(x, y);
2330                                     } else {
2331                                         state
2332                                             .texel_fetches
2333                                             .insert((sampler, base), TexelFetchOffsets::new(x, y));
2334                                     }
2335                                 }
2336                             } else if name == "swgl_stepInterp" {
2337                                 let mut globals = state.modified_globals.borrow_mut();
2338                                 for (i, sym) in state.syms.iter().enumerate() {
2339                                     match &sym.borrow().decl {
2340                                         SymDecl::Global(StorageClass::In, _, _, RunClass::Vector) => {
2341                                             let symref = SymRef(i as u32);
2342                                             if !globals.contains(&symref) {
2343                                                 globals.push(symref);
2344                                             }
2345                                         }
2346                                         _ => {}
2347                                     }
2348                                 }
2349                             }
2350                             let sym = match state.lookup(name) {
2351                                 Some(s) => s,
2352                                 None => panic!("missing symbol {}", name),
2353                             };
2354                             // Force any boolean basic type constructors to generate correct
2355                             // bit patterns.
2356                             if let Some(t) = TypeKind::from_glsl_primitive_type_name(name) {
2357                                 if t.is_bool() {
2358                                     force_params_to_bool(state, &mut params);
2359                                 } else {
2360                                     force_params_from_bool(state, &mut params);
2361                                 }
2362                             }
2363                             match &state.sym(sym).decl {
2364                                 SymDecl::NativeFunction(fn_ty, _, _) => {
2365                                     // Search for a signature where all parameter types are
2366                                     // compatible. If there are many compatible signatures,
2367                                     // then choose the one with the most exact matches.
2368                                     // This is an approximation of the algorith described in
2369                                     // the "Function Definitions" section of the spec.
2370                                     let mut ret = None;
2371                                     let mut best_score = 0;
2372                                     'next_sig: for sig in &fn_ty.signatures {
2373                                         let mut score = 0;
2374                                         for (e, p) in params.iter().zip(sig.params.iter()) {
2375                                             if e.ty == *p {
2376                                                 score += 1;
2377                                             } else if !can_implicitly_convert_to(&e.ty, p) {
2378                                                 continue 'next_sig;
2379                                             }
2380                                         }
2381                                         if score >= best_score {
2382                                             ret = Some(sig.ret.clone());
2383                                             best_score = score;
2384                                             // If all parameters match exactly, then there
2385                                             // is no need to search for other matches.
2386                                             if best_score >= params.len() {
2387                                                 break;
2388                                             }
2389                                         }
2390                                     }
2391                                     ret_ty = match ret {
2392                                         Some(t) => t,
2393                                         None => {
2394                                             dbg!(&fn_ty.signatures);
2395                                             dbg!(params.iter().map(|p| p).collect::<Vec<_>>());
2396                                             panic!("no matching func {}", i.as_str())
2397                                         }
2398                                     };
2399                                 }
2400                                 SymDecl::UserFunction(fd, _) => {
2401                                     let mut globals = state.modified_globals.borrow_mut();
2402                                     for global in &fd.globals {
2403                                         if !globals.contains(global) {
2404                                             globals.push(*global);
2405                                         }
2406                                     }
2407                                     let mut matching = true;
2408                                     for (e, p) in params.iter().zip(fd.prototype.parameters.iter())
2409                                     {
2410                                         matching &= match p {
2411                                             FunctionParameterDeclaration::Named(q, d) => {
2412                                                 match q {
2413                                                     Some(ParameterQualifier::InOut)
2414                                                     | Some(ParameterQualifier::Out) => {
2415                                                         if let Some(global) = is_output(e, state) {
2416                                                             if !globals.contains(&global) {
2417                                                                 globals.push(global);
2418                                                             }
2419                                                         }
2420                                                     }
2421                                                     _ => {}
2422                                                 }
2423                                                 can_implicitly_convert_to(&e.ty, &d.ty)
2424                                             }
2425                                             FunctionParameterDeclaration::Unnamed(..) => panic!(),
2426                                         };
2427                                     }
2428                                     assert!(matching);
2429                                     ret_ty = fd.prototype.ty.clone();
2430                                 }
2431                                 SymDecl::Struct(_) => ret_ty = Type::new(TypeKind::Struct(sym)),
2432                                 _ => panic!("can only call functions"),
2433                             };
2434                             FunIdentifier::Identifier(sym)
2435                         }
2436                         // array constructor
2437                         syntax::FunIdentifier::Expr(e) => {
2438                             let ty = match &**e {
2439                                 syntax::Expr::Bracket(i, array) => {
2440                                     let kind = match &**i {
2441                                         syntax::Expr::Variable(i) => match i.as_str() {
2442                                             "vec4" => TypeKind::Vec4,
2443                                             "vec2" => TypeKind::Vec2,
2444                                             "int" => TypeKind::Int,
2445                                             _ => panic!("unexpected type constructor {:?}", i),
2446                                         },
2447                                         _ => panic!(),
2448                                     };
2449 
2450                                     Type {
2451                                         kind,
2452                                         precision: None,
2453                                         array_sizes: Some(Box::new(lift(state, array))),
2454                                     }
2455                                 }
2456                                 _ => panic!(),
2457                             };
2458                             ret_ty = ty.clone();
2459 
2460                             FunIdentifier::Constructor(ty)
2461                         }
2462                     },
2463                     params,
2464                 ),
2465                 ty: ret_ty,
2466             }
2467         }
2468         syntax::Expr::IntConst(i) => Expr {
2469             kind: ExprKind::IntConst(*i),
2470             ty: Type::new(TypeKind::Int),
2471         },
2472         syntax::Expr::UIntConst(u) => Expr {
2473             kind: ExprKind::UIntConst(*u),
2474             ty: Type::new(TypeKind::UInt),
2475         },
2476         syntax::Expr::PostDec(e) => {
2477             let e = Box::new(translate_expression(state, e));
2478             let ty = e.ty.clone();
2479             Expr {
2480                 kind: ExprKind::PostDec(e),
2481                 ty,
2482             }
2483         }
2484         syntax::Expr::PostInc(e) => {
2485             let e = Box::new(translate_expression(state, e));
2486             let ty = e.ty.clone();
2487             Expr {
2488                 kind: ExprKind::PostInc(e),
2489                 ty,
2490             }
2491         }
2492         syntax::Expr::Ternary(cond, lhs, rhs) => {
2493             let cond = Box::new(translate_expression(state, cond));
2494             let lhs = Box::new(translate_expression(state, lhs));
2495             let rhs = Box::new(translate_expression(state, rhs));
2496             let ty = promoted_type(&lhs.ty, &rhs.ty);
2497             Expr {
2498                 kind: ExprKind::Ternary(cond, lhs, rhs),
2499                 ty,
2500             }
2501         }
2502         syntax::Expr::Dot(e, i) => {
2503             let e = Box::new(translate_expression(state, e));
2504             let ty = e.ty.clone();
2505             let ivec = is_ivec(&ty);
2506             if is_vector(&ty) {
2507                 let ty = Type::new(match i.as_str().len() {
2508                     1 => {
2509                         if ivec {
2510                             TypeKind::Int
2511                         } else {
2512                             TypeKind::Float
2513                         }
2514                     }
2515                     2 => {
2516                         if ivec {
2517                             TypeKind::IVec2
2518                         } else {
2519                             TypeKind::Vec2
2520                         }
2521                     }
2522                     3 => {
2523                         if ivec {
2524                             TypeKind::IVec3
2525                         } else {
2526                             TypeKind::Vec3
2527                         }
2528                     }
2529                     4 => {
2530                         if ivec {
2531                             TypeKind::IVec4
2532                         } else {
2533                             TypeKind::Vec4
2534                         }
2535                     }
2536                     _ => panic!(),
2537                 });
2538 
2539                 let sel = SwizzleSelector::parse(i.as_str());
2540 
2541                 Expr {
2542                     kind: ExprKind::SwizzleSelector(e, sel),
2543                     ty,
2544                 }
2545             } else {
2546                 match ty.kind {
2547                     TypeKind::Struct(s) => {
2548                         let sym = state.sym(s);
2549                         let fields = match &sym.decl {
2550                             SymDecl::Struct(fields) => fields,
2551                             _ => panic!("expected struct"),
2552                         };
2553                         let field = fields
2554                             .fields
2555                             .iter()
2556                             .find(|x| &x.name == i)
2557                             .expect(&format!("missing field `{}` in `{}`", i, sym.name));
2558                         Expr {
2559                             kind: ExprKind::Dot(e, i.clone()),
2560                             ty: field.ty.clone(),
2561                         }
2562                     }
2563                     _ => panic!("expected struct found {:#?} {:#?}", e, ty),
2564                 }
2565             }
2566         }
2567         syntax::Expr::Bracket(e, specifier) => {
2568             let e = Box::new(translate_expression(state, e));
2569             let ty = if let Some(ty) = index_vector(&e.ty) {
2570                 Type::new(ty)
2571             } else if let Some(ty) = index_matrix(&e.ty) {
2572                 Type::new(ty)
2573             } else {
2574                 let a = match &e.ty.array_sizes {
2575                     Some(a) => {
2576                         let mut a = *a.clone();
2577                         a.sizes.pop();
2578                         if a.sizes.len() == 0 {
2579                             None
2580                         } else {
2581                             Some(Box::new(a))
2582                         }
2583                     }
2584                     _ => panic!("{:#?}", e),
2585                 };
2586                 Type {
2587                     kind: e.ty.kind.clone(),
2588                     precision: e.ty.precision.clone(),
2589                     array_sizes: a,
2590                 }
2591             };
2592             let indx = match specifier {
2593                 ArraySpecifier::Unsized => panic!("need expression"),
2594                 ArraySpecifier::ExplicitlySized(e) => translate_expression(state, e),
2595             };
2596             Expr {
2597                 kind: ExprKind::Bracket(e, Box::new(indx)),
2598                 ty,
2599             }
2600         }
2601     }
2602 }
2603 
translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement2604 fn translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement {
2605     let mut cases = Vec::new();
2606 
2607     let mut case = None;
2608     for stmt in &s.body {
2609         match stmt {
2610             syntax::Statement::Simple(s) => match &**s {
2611                 syntax::SimpleStatement::CaseLabel(label) => {
2612                     match case.take() {
2613                         Some(case) => cases.push(case),
2614                         _ => {}
2615                     }
2616                     case = Some(Case {
2617                         label: translate_case(state, &label),
2618                         stmts: Vec::new(),
2619                     })
2620                 }
2621                 _ => match case {
2622                     Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
2623                     _ => panic!("switch must start with case"),
2624                 },
2625             },
2626             _ => match case {
2627                 Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
2628                 _ => panic!("switch must start with case"),
2629             },
2630         }
2631     }
2632     match case.take() {
2633         Some(case) => cases.push(case),
2634         _ => {}
2635     }
2636     SwitchStatement {
2637         head: Box::new(translate_expression(state, &s.head)),
2638         cases,
2639     }
2640 }
2641 
translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement2642 fn translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement {
2643     match s {
2644         syntax::JumpStatement::Break => JumpStatement::Break,
2645         syntax::JumpStatement::Continue => JumpStatement::Continue,
2646         syntax::JumpStatement::Discard => JumpStatement::Discard,
2647         syntax::JumpStatement::Return(e) => {
2648             JumpStatement::Return(e.as_ref().map(|e| Box::new(translate_expression(state, e))))
2649         }
2650     }
2651 }
2652 
translate_condition(state: &mut State, c: &syntax::Condition) -> Condition2653 fn translate_condition(state: &mut State, c: &syntax::Condition) -> Condition {
2654     match c {
2655         syntax::Condition::Expr(e) => Condition::Expr(Box::new(translate_expression(state, e))),
2656         _ => panic!(),
2657     }
2658 }
2659 
translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement2660 fn translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement {
2661     match s {
2662         syntax::ForInitStatement::Expression(e) => {
2663             ForInitStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
2664         }
2665         syntax::ForInitStatement::Declaration(d) => ForInitStatement::Declaration(Box::new(
2666             translate_declaration(state, d, RunClass::Scalar),
2667         )),
2668     }
2669 }
2670 
translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement2671 fn translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement {
2672     ForRestStatement {
2673         condition: s.condition.as_ref().map(|c| translate_condition(state, c)),
2674         post_expr: s
2675             .post_expr
2676             .as_ref()
2677             .map(|e| Box::new(translate_expression(state, e))),
2678     }
2679 }
2680 
translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement2681 fn translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement {
2682     match s {
2683         syntax::IterationStatement::While(cond, s) => IterationStatement::While(
2684             translate_condition(state, cond),
2685             Box::new(translate_statement(state, s)),
2686         ),
2687         syntax::IterationStatement::For(init, rest, s) => IterationStatement::For(
2688             translate_for_init(state, init),
2689             translate_for_rest(state, rest),
2690             Box::new(translate_statement(state, s)),
2691         ),
2692         syntax::IterationStatement::DoWhile(s, e) => IterationStatement::DoWhile(
2693             Box::new(translate_statement(state, s)),
2694             Box::new(translate_expression(state, e)),
2695         ),
2696     }
2697 }
2698 
translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel2699 fn translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel {
2700     match c {
2701         syntax::CaseLabel::Def => CaseLabel::Def,
2702         syntax::CaseLabel::Case(e) => CaseLabel::Case(Box::new(translate_expression(state, e))),
2703     }
2704 }
2705 
translate_selection_rest( state: &mut State, s: &syntax::SelectionRestStatement, ) -> (Box<Statement>, Option<Box<Statement>>)2706 fn translate_selection_rest(
2707     state: &mut State,
2708     s: &syntax::SelectionRestStatement,
2709 ) -> (Box<Statement>, Option<Box<Statement>>) {
2710     match s {
2711         syntax::SelectionRestStatement::Statement(s) => {
2712             (Box::new(translate_statement(state, s)), None)
2713         }
2714         syntax::SelectionRestStatement::Else(if_body, rest) => (
2715             Box::new(translate_statement(state, if_body)),
2716             Some(Box::new(translate_statement(state, rest))),
2717         ),
2718     }
2719 }
2720 
translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement2721 fn translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement {
2722     let cond = Box::new(translate_expression(state, &s.cond));
2723     let (body, else_stmt) = translate_selection_rest(state, &s.rest);
2724     SelectionStatement {
2725         cond,
2726         body,
2727         else_stmt,
2728     }
2729 }
2730 
translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement2731 fn translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement {
2732     match s {
2733         syntax::SimpleStatement::Declaration(d) => {
2734             SimpleStatement::Declaration(translate_declaration(state, d, RunClass::Unknown))
2735         }
2736         syntax::SimpleStatement::Expression(e) => {
2737             SimpleStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
2738         }
2739         syntax::SimpleStatement::Iteration(i) => {
2740             SimpleStatement::Iteration(translate_iteration(state, i))
2741         }
2742         syntax::SimpleStatement::Selection(s) => {
2743             SimpleStatement::Selection(translate_selection(state, s))
2744         }
2745         syntax::SimpleStatement::Jump(j) => SimpleStatement::Jump(translate_jump(state, j)),
2746         syntax::SimpleStatement::Switch(s) => SimpleStatement::Switch(translate_switch(state, s)),
2747         syntax::SimpleStatement::CaseLabel(_) => panic!("should be handled by translate_switch"),
2748     }
2749 }
2750 
translate_statement(state: &mut State, s: &syntax::Statement) -> Statement2751 fn translate_statement(state: &mut State, s: &syntax::Statement) -> Statement {
2752     match s {
2753         syntax::Statement::Compound(s) => {
2754             Statement::Compound(Box::new(translate_compound_statement(state, s)))
2755         }
2756         syntax::Statement::Simple(s) => {
2757             Statement::Simple(Box::new(translate_simple_statement(state, s)))
2758         }
2759     }
2760 }
2761 
translate_compound_statement( state: &mut State, cs: &syntax::CompoundStatement, ) -> CompoundStatement2762 fn translate_compound_statement(
2763     state: &mut State,
2764     cs: &syntax::CompoundStatement,
2765 ) -> CompoundStatement {
2766     CompoundStatement {
2767         statement_list: cs
2768             .statement_list
2769             .iter()
2770             .map(|x| translate_statement(state, x))
2771             .collect(),
2772     }
2773 }
2774 
translate_function_parameter_declaration( state: &mut State, p: &syntax::FunctionParameterDeclaration, index: usize, ) -> FunctionParameterDeclaration2775 fn translate_function_parameter_declaration(
2776     state: &mut State,
2777     p: &syntax::FunctionParameterDeclaration,
2778     index: usize,
2779 ) -> FunctionParameterDeclaration {
2780     match p {
2781         syntax::FunctionParameterDeclaration::Named(qual, p) => {
2782             let mut ty: Type = lift(state, &p.ty);
2783             if let Some(a) = &p.ident.array_spec {
2784                 ty.array_sizes = Some(Box::new(lift(state, a)));
2785             }
2786 
2787             ty.precision = get_precision(qual);
2788 
2789             let decl = SymDecl::Local(
2790                 StorageClass::None,
2791                 ty.clone(),
2792                 RunClass::Dependent(1 << index),
2793             );
2794             let d = FunctionParameterDeclarator {
2795                 ty,
2796                 name: p.ident.ident.clone(),
2797                 sym: state.declare(p.ident.ident.as_str(), decl),
2798             };
2799             FunctionParameterDeclaration::Named(lift_type_qualifier_for_parameter(state, qual), d)
2800         }
2801         syntax::FunctionParameterDeclaration::Unnamed(qual, p) => {
2802             FunctionParameterDeclaration::Unnamed(
2803                 lift_type_qualifier_for_parameter(state, qual),
2804                 p.clone(),
2805             )
2806         }
2807     }
2808 }
2809 
translate_prototype( state: &mut State, cs: &syntax::FunctionPrototype, ) -> (FunctionPrototype, SymRef)2810 fn translate_prototype(
2811     state: &mut State,
2812     cs: &syntax::FunctionPrototype,
2813 ) -> (FunctionPrototype, SymRef) {
2814     let prototype = FunctionPrototype {
2815         ty: lift(state, &cs.ty),
2816         name: cs.name.clone(),
2817         parameters: cs
2818             .parameters
2819             .iter()
2820             .enumerate()
2821             .map(|(i, x)| translate_function_parameter_declaration(state, x, i))
2822             .collect(),
2823     };
2824     let sym = if let Some(sym) = state.lookup(prototype.name.as_str()) {
2825         match &state.sym(sym).decl {
2826             SymDecl::UserFunction(..) => {}
2827             _ => panic!(
2828                 "prototype conflicts with existing symbol: {}",
2829                 prototype.name.as_str()
2830             ),
2831         }
2832         sym
2833     } else {
2834         let pfd = Rc::new(FunctionDefinition {
2835             prototype: prototype.clone(),
2836             body: CompoundStatement::new(),
2837             globals: Vec::new(),
2838             texel_fetches: HashMap::new(),
2839         });
2840         state.declare(
2841             prototype.name.as_str(),
2842             SymDecl::UserFunction(pfd, RunClass::Unknown),
2843         )
2844     };
2845     (prototype, sym)
2846 }
2847 
translate_function_prototype( state: &mut State, prototype: &syntax::FunctionPrototype, ) -> FunctionPrototype2848 fn translate_function_prototype(
2849     state: &mut State,
2850     prototype: &syntax::FunctionPrototype,
2851 ) -> FunctionPrototype {
2852     let (prototype, _) = translate_prototype(state, prototype);
2853     prototype
2854 }
2855 
translate_function_definition( state: &mut State, sfd: &syntax::FunctionDefinition, ) -> Rc<FunctionDefinition>2856 fn translate_function_definition(
2857     state: &mut State,
2858     sfd: &syntax::FunctionDefinition,
2859 ) -> Rc<FunctionDefinition> {
2860     let (prototype, sym) = translate_prototype(state, &sfd.prototype);
2861 
2862     state.push_scope(prototype.name.as_str().into());
2863     state.in_function = Some(sym);
2864     state.modified_globals.get_mut().clear();
2865     state.texel_fetches.clear();
2866     let body = translate_compound_statement(state, &sfd.statement);
2867     let mut globals = Vec::new();
2868     mem::swap(&mut globals, state.modified_globals.get_mut());
2869     let mut texel_fetches = HashMap::new();
2870     mem::swap(&mut texel_fetches, &mut state.texel_fetches);
2871     state.in_function = None;
2872     state.pop_scope();
2873 
2874     let fd = Rc::new(FunctionDefinition {
2875         prototype,
2876         body,
2877         globals,
2878         texel_fetches,
2879     });
2880     state.sym_mut(sym).decl = SymDecl::UserFunction(fd.clone(), RunClass::Unknown);
2881     fd
2882 }
2883 
translate_external_declaration( state: &mut State, ed: &syntax::ExternalDeclaration, ) -> ExternalDeclaration2884 fn translate_external_declaration(
2885     state: &mut State,
2886     ed: &syntax::ExternalDeclaration,
2887 ) -> ExternalDeclaration {
2888     match ed {
2889         syntax::ExternalDeclaration::Declaration(d) => {
2890             ExternalDeclaration::Declaration(translate_declaration(state, d, RunClass::Unknown))
2891         }
2892         syntax::ExternalDeclaration::FunctionDefinition(fd) => {
2893             ExternalDeclaration::FunctionDefinition(translate_function_definition(state, fd))
2894         }
2895         syntax::ExternalDeclaration::Preprocessor(p) => {
2896             ExternalDeclaration::Preprocessor(p.clone())
2897         }
2898     }
2899 }
2900 
declare_function_ext( state: &mut State, name: &str, cxx_name: Option<&'static str>, ret: Type, params: Vec<Type>, run_class: RunClass, )2901 fn declare_function_ext(
2902     state: &mut State,
2903     name: &str,
2904     cxx_name: Option<&'static str>,
2905     ret: Type,
2906     params: Vec<Type>,
2907     run_class: RunClass,
2908 ) {
2909     let sig = FunctionSignature { ret, params };
2910     match state.lookup_sym_mut(name) {
2911         Some(Symbol {
2912             decl: SymDecl::NativeFunction(f, ..),
2913             ..
2914         }) => f.signatures.push(sig),
2915         None => {
2916             state.declare(
2917                 name,
2918                 SymDecl::NativeFunction(
2919                     FunctionType {
2920                         signatures: NonEmpty::new(sig),
2921                     },
2922                     cxx_name,
2923                     run_class,
2924                 ),
2925             );
2926         }
2927         _ => panic!("overloaded function name {}", name),
2928     }
2929     //state.declare(name, Type::Function(FunctionType{ v}))
2930 }
2931 
declare_function( state: &mut State, name: &str, cxx_name: Option<&'static str>, ret: Type, params: Vec<Type>, )2932 fn declare_function(
2933     state: &mut State,
2934     name: &str,
2935     cxx_name: Option<&'static str>,
2936     ret: Type,
2937     params: Vec<Type>,
2938 ) {
2939     declare_function_ext(state, name, cxx_name, ret, params, RunClass::Unknown)
2940 }
2941 
ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit2942 pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit {
2943     // global scope
2944     state.push_scope("global".into());
2945     use TypeKind::*;
2946     declare_function(
2947         state,
2948         "vec2",
2949         Some("make_vec2"),
2950         Type::new(Vec2),
2951         vec![Type::new(Float)],
2952     );
2953     declare_function(
2954         state,
2955         "vec2",
2956         Some("make_vec2"),
2957         Type::new(Vec2),
2958         vec![Type::new(Float), Type::new(Float)],
2959     );
2960     declare_function(
2961         state,
2962         "vec2",
2963         Some("make_vec2"),
2964         Type::new(Vec2),
2965         vec![Type::new(IVec2)],
2966     );
2967     declare_function(
2968         state,
2969         "vec2",
2970         Some("make_vec2"),
2971         Type::new(Vec2),
2972         vec![Type::new(IVec3)],
2973     );
2974     declare_function(
2975         state,
2976         "vec3",
2977         Some("make_vec3"),
2978         Type::new(Vec3),
2979         vec![Type::new(Float), Type::new(Float), Type::new(Float)],
2980     );
2981     declare_function(
2982         state,
2983         "vec3",
2984         Some("make_vec3"),
2985         Type::new(Vec3),
2986         vec![Type::new(Float)],
2987     );
2988     declare_function(
2989         state,
2990         "vec3",
2991         Some("make_vec3"),
2992         Type::new(Vec3),
2993         vec![Type::new(Vec2), Type::new(Float)],
2994     );
2995     declare_function(
2996         state,
2997         "vec4",
2998         Some("make_vec4"),
2999         Type::new(Vec4),
3000         vec![Type::new(Float)],
3001     );
3002     declare_function(
3003         state,
3004         "vec4",
3005         Some("make_vec4"),
3006         Type::new(Vec4),
3007         vec![Type::new(Vec3), Type::new(Float)],
3008     );
3009     declare_function(
3010         state,
3011         "vec4",
3012         Some("make_vec4"),
3013         Type::new(Vec4),
3014         vec![
3015             Type::new(Float),
3016             Type::new(Float),
3017             Type::new(Float),
3018             Type::new(Float),
3019         ],
3020     );
3021     declare_function(
3022         state,
3023         "vec4",
3024         Some("make_vec4"),
3025         Type::new(Vec4),
3026         vec![Type::new(Vec2), Type::new(Float), Type::new(Float)],
3027     );
3028     declare_function(
3029         state,
3030         "vec4",
3031         Some("make_vec4"),
3032         Type::new(Vec4),
3033         vec![Type::new(Vec2), Type::new(Vec2)],
3034     );
3035     declare_function(
3036         state,
3037         "vec4",
3038         Some("make_vec4"),
3039         Type::new(Vec4),
3040         vec![Type::new(Float), Type::new(Float), Type::new(Vec2)],
3041     );
3042     declare_function(
3043         state,
3044         "vec4",
3045         Some("make_vec4"),
3046         Type::new(Vec4),
3047         vec![Type::new(Vec4)],
3048     );
3049     declare_function(
3050         state,
3051         "vec4",
3052         Some("make_vec4"),
3053         Type::new(Vec4),
3054         vec![Type::new(IVec4)],
3055     );
3056 
3057     declare_function(
3058         state,
3059         "bvec2",
3060         Some("make_bvec2"),
3061         Type::new(BVec2),
3062         vec![Type::new(Bool)],
3063     );
3064     declare_function(
3065         state,
3066         "bvec3",
3067         Some("make_bvec3"),
3068         Type::new(BVec3),
3069         vec![Type::new(Bool)],
3070     );
3071     declare_function(
3072         state,
3073         "bvec4",
3074         Some("make_bvec4"),
3075         Type::new(BVec4),
3076         vec![Type::new(Bool)],
3077     );
3078     declare_function(
3079         state,
3080         "bvec4",
3081         Some("make_bvec4"),
3082         Type::new(BVec4),
3083         vec![Type::new(BVec2), Type::new(BVec2)],
3084     );
3085     declare_function(
3086         state,
3087         "bvec4",
3088         Some("make_bvec4"),
3089         Type::new(BVec4),
3090         vec![Type::new(Bool), Type::new(Bool), Type::new(Bool), Type::new(Bool)],
3091     );
3092     declare_function(
3093         state,
3094         "int",
3095         Some("make_int"),
3096         Type::new(Int),
3097         vec![Type::new(Float)],
3098     );
3099     declare_function(
3100         state,
3101         "float",
3102         Some("make_float"),
3103         Type::new(Float),
3104         vec![Type::new(Float)],
3105     );
3106     declare_function(
3107         state,
3108         "float",
3109         Some("make_float"),
3110         Type::new(Float),
3111         vec![Type::new(Int)],
3112     );
3113     declare_function(
3114         state,
3115         "int",
3116         Some("make_int"),
3117         Type::new(Int),
3118         vec![Type::new(UInt)],
3119     );
3120     declare_function(
3121         state,
3122         "uint",
3123         Some("make_uint"),
3124         Type::new(UInt),
3125         vec![Type::new(Float)],
3126     );
3127     declare_function(
3128         state,
3129         "uint",
3130         Some("make_uint"),
3131         Type::new(UInt),
3132         vec![Type::new(Int)],
3133     );
3134     declare_function(
3135         state,
3136         "ivec2",
3137         Some("make_ivec2"),
3138         Type::new(IVec2),
3139         vec![Type::new(UInt), Type::new(UInt)],
3140     );
3141     declare_function(
3142         state,
3143         "ivec2",
3144         Some("make_ivec2"),
3145         Type::new(IVec2),
3146         vec![Type::new(Int), Type::new(Int)],
3147     );
3148     declare_function(
3149         state,
3150         "ivec2",
3151         Some("make_ivec2"),
3152         Type::new(IVec2),
3153         vec![Type::new(Vec2)],
3154     );
3155     declare_function(
3156         state,
3157         "ivec3",
3158         Some("make_ivec3"),
3159         Type::new(IVec3),
3160         vec![Type::new(IVec2), Type::new(Int)],
3161     );
3162     declare_function(
3163         state,
3164         "ivec4",
3165         Some("make_ivec4"),
3166         Type::new(IVec4),
3167         vec![
3168             Type::new(Int),
3169             Type::new(Int),
3170             Type::new(Int),
3171             Type::new(Int),
3172         ],
3173     );
3174     declare_function(
3175         state,
3176         "ivec4",
3177         Some("make_ivec4"),
3178         Type::new(IVec4),
3179         vec![Type::new(Vec4)],
3180     );
3181     declare_function(
3182         state,
3183         "ivec4",
3184         Some("make_ivec4"),
3185         Type::new(IVec4),
3186         vec![Type::new(IVec2), Type::new(Int), Type::new(Int)],
3187     );
3188 
3189     declare_function(
3190         state,
3191         "mat2",
3192         Some("make_mat2"),
3193         Type::new(Mat2),
3194         vec![Type::new(Vec2), Type::new(Vec2)],
3195     );
3196     declare_function(
3197         state,
3198         "mat2",
3199         Some("make_mat2"),
3200         Type::new(Mat2),
3201         vec![Type::new(Float)],
3202     );
3203     declare_function(
3204         state,
3205         "mat2",
3206         Some("make_mat2"),
3207         Type::new(Mat2),
3208         vec![Type::new(Mat4)],
3209     );
3210     declare_function(
3211         state,
3212         "mat3",
3213         Some("make_mat3"),
3214         Type::new(Mat3),
3215         vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
3216     );
3217     declare_function(
3218         state,
3219         "mat3",
3220         Some("make_mat3"),
3221         Type::new(Mat3),
3222         vec![Type::new(Mat4)],
3223     );
3224     declare_function(
3225         state,
3226         "mat3",
3227         Some("make_mat3"),
3228         Type::new(Mat3),
3229         vec![
3230             Type::new(Float),
3231             Type::new(Float),
3232             Type::new(Float),
3233             Type::new(Float),
3234             Type::new(Float),
3235             Type::new(Float),
3236             Type::new(Float),
3237             Type::new(Float),
3238             Type::new(Float),
3239         ],
3240     );
3241     declare_function(
3242         state,
3243         "mat3x4",
3244         Some("make_mat3x4"),
3245         Type::new(Mat34),
3246         vec![
3247             Type::new(Float),
3248             Type::new(Float),
3249             Type::new(Float),
3250             Type::new(Float),
3251 
3252             Type::new(Float),
3253             Type::new(Float),
3254             Type::new(Float),
3255             Type::new(Float),
3256 
3257             Type::new(Float),
3258             Type::new(Float),
3259             Type::new(Float),
3260             Type::new(Float),
3261         ],
3262     );
3263     declare_function(
3264         state,
3265         "transpose",
3266         None,
3267         Type::new(Mat43),
3268         vec![Type::new(Mat34)],
3269     );
3270     declare_function(
3271         state,
3272         "mat4",
3273         Some("make_mat4"),
3274         Type::new(Mat4),
3275         vec![
3276             Type::new(Vec4),
3277             Type::new(Vec4),
3278             Type::new(Vec4),
3279             Type::new(Vec4),
3280         ],
3281     );
3282     declare_function(
3283         state,
3284         "mat4",
3285         Some("make_mat4"),
3286         Type::new(Mat4),
3287         vec![
3288             Type::new(Float),
3289             Type::new(Float),
3290             Type::new(Float),
3291             Type::new(Float),
3292             Type::new(Float),
3293             Type::new(Float),
3294             Type::new(Float),
3295             Type::new(Float),
3296             Type::new(Float),
3297             Type::new(Float),
3298             Type::new(Float),
3299             Type::new(Float),
3300             Type::new(Float),
3301             Type::new(Float),
3302             Type::new(Float),
3303             Type::new(Float),
3304         ],
3305     );
3306     declare_function(state, "abs", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3307     declare_function(state, "abs", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3308     declare_function(state, "abs", None, Type::new(Float), vec![Type::new(Float)]);
3309     declare_function(state, "sign", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3310     declare_function(state, "sign", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3311     declare_function(state, "sign", None, Type::new(Float), vec![Type::new(Float)]);
3312     declare_function(
3313         state,
3314         "dot",
3315         None,
3316         Type::new(Float),
3317         vec![Type::new(Vec3), Type::new(Vec3)],
3318     );
3319     declare_function(
3320         state,
3321         "dot",
3322         None,
3323         Type::new(Float),
3324         vec![Type::new(Vec2), Type::new(Vec2)],
3325     );
3326     for t in &[Vec2, Vec3, Vec4] {
3327         declare_function(
3328             state,
3329             "min",
3330             None,
3331             Type::new(*t),
3332             vec![Type::new(*t), Type::new(Float)],
3333         );
3334         declare_function(
3335             state,
3336             "max",
3337             None,
3338             Type::new(*t),
3339             vec![Type::new(*t), Type::new(Float)],
3340         );
3341     }
3342     for t in &[Int, Float, Vec2, Vec3, Vec4] {
3343         declare_function(
3344             state,
3345             "min",
3346             None,
3347             Type::new(*t),
3348             vec![Type::new(*t), Type::new(*t)],
3349         );
3350         declare_function(
3351             state,
3352             "max",
3353             None,
3354             Type::new(*t),
3355             vec![Type::new(*t), Type::new(*t)],
3356         );
3357     }
3358 
3359     declare_function(
3360         state,
3361         "mix",
3362         None,
3363         Type::new(Vec2),
3364         vec![Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
3365     );
3366     declare_function(
3367         state,
3368         "mix",
3369         None,
3370         Type::new(Vec2),
3371         vec![Type::new(Vec2), Type::new(Vec2), Type::new(BVec2)],
3372     );
3373     declare_function(
3374         state,
3375         "mix",
3376         None,
3377         Type::new(Vec2),
3378         vec![Type::new(Vec2), Type::new(Vec2), Type::new(Float)],
3379     );
3380     declare_function(
3381         state,
3382         "mix",
3383         None,
3384         Type::new(Vec3),
3385         vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
3386     );
3387     declare_function(
3388         state,
3389         "mix",
3390         None,
3391         Type::new(Vec4),
3392         vec![Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
3393     );
3394     declare_function(
3395         state,
3396         "mix",
3397         None,
3398         Type::new(Vec4),
3399         vec![Type::new(Vec4), Type::new(Vec4), Type::new(Float)],
3400     );
3401     declare_function(
3402         state,
3403         "mix",
3404         None,
3405         Type::new(Vec3),
3406         vec![Type::new(Vec3), Type::new(Vec3), Type::new(Float)],
3407     );
3408     declare_function(
3409         state,
3410         "mix",
3411         None,
3412         Type::new(Vec3),
3413         vec![Type::new(Vec3), Type::new(Vec3), Type::new(BVec3)],
3414     );
3415     declare_function(
3416         state,
3417         "mix",
3418         None,
3419         Type::new(Float),
3420         vec![Type::new(Float), Type::new(Float), Type::new(Float)],
3421     );
3422     declare_function(
3423         state,
3424         "mix",
3425         None,
3426         Type::new(Vec4),
3427         vec![Type::new(Vec4), Type::new(Vec4), Type::new(BVec4)],
3428     );
3429     declare_function(
3430         state,
3431         "step",
3432         None,
3433         Type::new(Float),
3434         vec![Type::new(Float), Type::new(Float)],
3435     );
3436     declare_function(
3437         state,
3438         "step",
3439         None,
3440         Type::new(Vec2),
3441         vec![Type::new(Vec2), Type::new(Vec2)],
3442     );
3443     declare_function(
3444         state,
3445         "step",
3446         None,
3447         Type::new(Vec2),
3448         vec![Type::new(Float), Type::new(Vec2)],
3449     );
3450     declare_function(
3451         state,
3452         "step",
3453         None,
3454         Type::new(Vec3),
3455         vec![Type::new(Vec3), Type::new(Vec3)],
3456     );
3457     declare_function(
3458         state,
3459         "step",
3460         None,
3461         Type::new(Vec4),
3462         vec![Type::new(Float), Type::new(Vec4)],
3463     );
3464     declare_function(
3465         state,
3466         "notEqual",
3467         None,
3468         Type::new(BVec4),
3469         vec![Type::new(IVec4), Type::new(IVec4)],
3470     );
3471 
3472     declare_function_ext(
3473         state,
3474         "fwidth",
3475         None,
3476         Type::new(Vec2),
3477         vec![Type::new(Vec2)],
3478         RunClass::Scalar,
3479     );
3480     declare_function_ext(
3481         state,
3482         "dFdx",
3483         None,
3484         Type::new(Float),
3485         vec![Type::new(Float)],
3486         RunClass::Scalar,
3487     );
3488     declare_function_ext(
3489         state,
3490         "dFdx",
3491         None,
3492         Type::new(Vec2),
3493         vec![Type::new(Vec2)],
3494         RunClass::Scalar,
3495     );
3496 
3497     declare_function(state, "cos", None, Type::new(Float), vec![Type::new(Float)]);
3498     declare_function(state, "sin", None, Type::new(Float), vec![Type::new(Float)]);
3499     declare_function(state, "tan", None, Type::new(Float), vec![Type::new(Float)]);
3500     declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float)]);
3501     declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float), Type::new(Float)]);
3502     for t in &[Vec2, Vec3, Vec4] {
3503         declare_function(
3504             state,
3505             "clamp",
3506             None,
3507             Type::new(*t),
3508             vec![Type::new(*t), Type::new(Float), Type::new(Float)],
3509         );
3510     }
3511     for t in &[Float, Vec2, Vec3, Vec4] {
3512         declare_function(
3513             state,
3514             "clamp",
3515             None,
3516             Type::new(*t),
3517             vec![Type::new(*t), Type::new(*t), Type::new(*t)],
3518         );
3519     }
3520     declare_function(
3521         state,
3522         "length",
3523         None,
3524         Type::new(Float),
3525         vec![Type::new(Vec2)],
3526     );
3527     declare_function(state, "pow", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3528     declare_function(state, "pow", None, Type::new(Float), vec![Type::new(Float)]);
3529     declare_function(state, "exp", None, Type::new(Float), vec![Type::new(Float)]);
3530     declare_function(state, "exp2", None, Type::new(Float), vec![Type::new(Float)]);
3531     declare_function(state, "log", None, Type::new(Float), vec![Type::new(Float)]);
3532     declare_function(state, "log2", None, Type::new(Float), vec![Type::new(Float)]);
3533     for t in &[Float, Vec2] {
3534         // recip is non-standard
3535         declare_function(
3536             state,
3537             "recip",
3538             None,
3539             Type::new(*t),
3540             vec![Type::new(*t)],
3541         );
3542         declare_function(
3543             state,
3544             "inversesqrt",
3545             None,
3546             Type::new(*t),
3547             vec![Type::new(*t)],
3548         );
3549         declare_function(
3550             state,
3551             "sqrt",
3552             None,
3553             Type::new(*t),
3554             vec![Type::new(*t)],
3555         );
3556     }
3557     declare_function(
3558         state,
3559         "distance",
3560         None,
3561         Type::new(Float),
3562         vec![Type::new(Vec2), Type::new(Vec2)],
3563     );
3564 
3565     declare_function(
3566         state,
3567         "equal",
3568         None,
3569         Type::new(BVec2),
3570         vec![Type::new(Vec2), Type::new(Vec2)],
3571     );
3572     declare_function(
3573         state,
3574         "equal",
3575         None,
3576         Type::new(BVec4),
3577         vec![Type::new(Vec4), Type::new(Vec4)],
3578     );
3579     declare_function(
3580         state,
3581         "notEqual",
3582         None,
3583         Type::new(BVec2),
3584         vec![Type::new(Vec2), Type::new(Vec2)],
3585     );
3586     declare_function(
3587         state,
3588         "notEqual",
3589         None,
3590         Type::new(BVec4),
3591         vec![Type::new(Vec4), Type::new(Vec4)],
3592     );
3593     declare_function(
3594         state,
3595         "lessThanEqual",
3596         None,
3597         Type::new(BVec2),
3598         vec![Type::new(Vec2), Type::new(Vec2)],
3599     );
3600     declare_function(
3601         state,
3602         "lessThanEqual",
3603         None,
3604         Type::new(BVec3),
3605         vec![Type::new(Vec3), Type::new(Vec3)],
3606     );
3607     declare_function(
3608         state,
3609         "lessThanEqual",
3610         None,
3611         Type::new(BVec4),
3612         vec![Type::new(Vec4), Type::new(Vec4)],
3613     );
3614     declare_function(
3615         state,
3616         "lessThan",
3617         None,
3618         Type::new(BVec2),
3619         vec![Type::new(Vec2), Type::new(Vec2)],
3620     );
3621     declare_function(
3622         state,
3623         "lessThan",
3624         None,
3625         Type::new(BVec4),
3626         vec![Type::new(Vec4), Type::new(Vec4)],
3627     );
3628     declare_function(
3629         state,
3630         "greaterThan",
3631         None,
3632         Type::new(BVec2),
3633         vec![Type::new(Vec2), Type::new(Vec2)],
3634     );
3635     declare_function(
3636         state,
3637         "greaterThan",
3638         None,
3639         Type::new(BVec4),
3640         vec![Type::new(Vec4), Type::new(Vec4)],
3641     );
3642     declare_function(
3643         state,
3644         "greaterThanEqual",
3645         None,
3646         Type::new(BVec2),
3647         vec![Type::new(Vec2), Type::new(Vec2)],
3648     );
3649     declare_function(
3650         state,
3651         "greaterThanEqual",
3652         None,
3653         Type::new(BVec4),
3654         vec![Type::new(Vec4), Type::new(Vec4)],
3655     );
3656     declare_function(state, "any", None, Type::new(Bool), vec![Type::new(BVec2)]);
3657     declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec2)]);
3658     declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec4)]);
3659 
3660     declare_function(
3661         state,
3662         "if_then_else",
3663         None,
3664         Type::new(Vec3),
3665         vec![Type::new(BVec3), Type::new(Vec3), Type::new(Vec3)],
3666     );
3667     declare_function(state, "floor", None, Type::new(Vec4), vec![Type::new(Vec4)]);
3668     declare_function(state, "floor", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3669     declare_function(
3670         state,
3671         "floor",
3672         None,
3673         Type::new(Float),
3674         vec![Type::new(Float)],
3675     );
3676     declare_function(
3677         state,
3678         "ceil",
3679         None,
3680         Type::new(Float),
3681         vec![Type::new(Float)],
3682     );
3683     declare_function(
3684         state,
3685         "round",
3686         None,
3687         Type::new(Float),
3688         vec![Type::new(Float)],
3689     );
3690     declare_function(
3691         state,
3692         "fract",
3693         None,
3694         Type::new(Float),
3695         vec![Type::new(Float)],
3696     );
3697     declare_function(
3698         state,
3699         "fract",
3700         None,
3701         Type::new(Vec2),
3702         vec![Type::new(Vec2)],
3703     );
3704     declare_function(state, "mod", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3705     declare_function(state, "mod", None, Type::new(Float), vec![Type::new(Float)]);
3706 
3707     declare_function(
3708         state,
3709         "texelFetch",
3710         None,
3711         Type::new(Vec4),
3712         vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
3713     );
3714     declare_function(
3715         state,
3716         "texelFetch",
3717         None,
3718         Type::new(IVec4),
3719         vec![Type::new(ISampler2D), Type::new(IVec2), Type::new(Int)],
3720     );
3721     declare_function(
3722         state,
3723         "texelFetchOffset",
3724         None,
3725         Type::new(Vec4),
3726         vec![
3727             Type::new(Sampler2D),
3728             Type::new(IVec2),
3729             Type::new(Int),
3730             Type::new(IVec2),
3731         ],
3732     );
3733     declare_function(
3734         state,
3735         "texelFetchOffset",
3736         None,
3737         Type::new(IVec4),
3738         vec![
3739             Type::new(ISampler2D),
3740             Type::new(IVec2),
3741             Type::new(Int),
3742             Type::new(IVec2),
3743         ],
3744     );
3745     declare_function(
3746         state,
3747         "texture",
3748         None,
3749         Type::new(Vec4),
3750         vec![Type::new(Sampler2D), Type::new(Vec2)],
3751     );
3752     declare_function(
3753         state,
3754         "texture",
3755         None,
3756         Type::new(Vec4),
3757         vec![Type::new(Sampler2DRect), Type::new(Vec2)],
3758     );
3759     declare_function(
3760         state,
3761         "textureSize",
3762         None,
3763         Type::new(IVec2),
3764         vec![Type::new(Sampler2D), Type::new(Int)],
3765     );
3766     declare_function(
3767         state,
3768         "textureSize",
3769         None,
3770         Type::new(IVec2),
3771         vec![Type::new(Sampler2DRect), Type::new(Int)],
3772     );
3773 
3774     declare_function(
3775         state,
3776         "inverse",
3777         None,
3778         Type::new(Mat2),
3779         vec![Type::new(Mat2)],
3780     );
3781     declare_function(
3782         state,
3783         "transpose",
3784         None,
3785         Type::new(Mat3),
3786         vec![Type::new(Mat3)],
3787     );
3788     declare_function(
3789         state,
3790         "normalize",
3791         None,
3792         Type::new(Vec2),
3793         vec![Type::new(Vec2)],
3794     );
3795     state.declare(
3796         "gl_FragCoord",
3797         SymDecl::Global(StorageClass::In, None, Type::new(Vec4), RunClass::Vector),
3798     );
3799     state.declare(
3800         "gl_FragColor",
3801         SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
3802     );
3803     state.declare(
3804         "gl_Position",
3805         SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
3806     );
3807     state.clip_dist_sym = state.declare(
3808         "gl_ClipDistance",
3809         SymDecl::Global(StorageClass::Out, None, Type::new_array(Float, 4), RunClass::Vector),
3810     );
3811 
3812     state.declare(
3813         "swgl_SpanLength",
3814         SymDecl::Global(StorageClass::In, None, Type::new(Int), RunClass::Scalar),
3815     );
3816     state.declare(
3817         "swgl_StepSize",
3818         SymDecl::Global(StorageClass::Const, None, Type::new(Int), RunClass::Scalar),
3819     );
3820 
3821     for t in &[Float, Vec2, Vec3, Vec4, Int, IVec2, IVec3, IVec4, Mat3, Mat4] {
3822         declare_function_ext(
3823             state,
3824             "swgl_forceScalar",
3825             None,
3826             Type::new(*t),
3827             vec![Type::new(*t)],
3828             RunClass::Scalar,
3829         );
3830     }
3831 
3832     // GL_ARB_shader_group_vote
3833     for (name, cxx_name) in &[("anyInvocations", "test_any"),
3834                               ("allInvocations", "test_all"),
3835                               ("allInvocationsEqual", "test_equal")] {
3836         declare_function_ext(
3837             state,
3838             name,
3839             Some(cxx_name),
3840             Type::new(Bool),
3841             vec![Type::new(Bool)],
3842             RunClass::Scalar,
3843         );
3844     }
3845 
3846     declare_function(
3847         state,
3848         "swgl_stepInterp",
3849         None,
3850         Type::new(Void),
3851         vec![],
3852     );
3853 
3854     for t in &[Float, Vec2, Vec3, Vec4] {
3855         declare_function_ext(
3856             state,
3857             "swgl_interpStep",
3858             None,
3859             Type::new(*t),
3860             vec![Type::new(*t)],
3861             RunClass::Scalar,
3862         );
3863     }
3864 
3865     declare_function(
3866         state,
3867         "swgl_commitPartialSolidRGBA8",
3868         None,
3869         Type::new(Void),
3870         vec![Type::new(Int), Type::new(Vec4)],
3871     );
3872     declare_function(
3873         state,
3874         "swgl_commitPartialSolidR8",
3875         None,
3876         Type::new(Void),
3877         vec![Type::new(Int), Type::new(Float)],
3878     );
3879     declare_function(
3880         state,
3881         "swgl_commitSolidRGBA8",
3882         None,
3883         Type::new(Void),
3884         vec![Type::new(Vec4)],
3885     );
3886     declare_function(
3887         state,
3888         "swgl_commitSolidR8",
3889         None,
3890         Type::new(Void),
3891         vec![Type::new(Float)],
3892     );
3893     declare_function(
3894         state,
3895         "swgl_commitColorRGBA8",
3896         None,
3897         Type::new(Void),
3898         vec![Type::new(Vec4)],
3899     );
3900     declare_function(
3901         state,
3902         "swgl_commitColorR8",
3903         None,
3904         Type::new(Void),
3905         vec![Type::new(Float)],
3906     );
3907     declare_function(
3908         state,
3909         "swgl_blendDropShadow",
3910         None,
3911         Type::new(Void),
3912         vec![Type::new(Vec4)],
3913     );
3914     declare_function(
3915         state,
3916         "swgl_blendSubpixelText",
3917         None,
3918         Type::new(Void),
3919         vec![Type::new(Vec4)],
3920     );
3921     declare_function(
3922         state,
3923         "swgl_clipMask",
3924         None,
3925         Type::new(Void),
3926         vec![Type::new(Sampler2D), Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
3927     );
3928     declare_function(
3929         state,
3930         "swgl_antiAlias",
3931         None,
3932         Type::new(Void),
3933         vec![Type::new(Int)],
3934     );
3935     declare_function(
3936         state,
3937         "swgl_antiAlias",
3938         None,
3939         Type::new(Void),
3940         vec![Type::new(BVec4)],
3941     );
3942     declare_function_ext(
3943         state,
3944         "swgl_validateGradient",
3945         None,
3946         Type::new(Int),
3947         vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
3948         RunClass::Scalar,
3949     );
3950     declare_function(
3951         state,
3952         "swgl_commitLinearGradientRGBA8",
3953         None,
3954         Type::new(Void),
3955         vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Float)],
3956     );
3957     declare_function(
3958         state,
3959         "swgl_commitRadialGradientRGBA8",
3960         None,
3961         Type::new(Void),
3962         vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2),
3963              Type::new(Float)],
3964     );
3965     declare_function(
3966         state,
3967         "swgl_commitGradientRGBA8",
3968         None,
3969         Type::new(Void),
3970         vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float)],
3971     );
3972     declare_function(
3973         state,
3974         "swgl_commitGradientColorRGBA8",
3975         None,
3976         Type::new(Void),
3977         vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Float)],
3978     );
3979     for s in &[Sampler2D, Sampler2DRect] {
3980         declare_function_ext(
3981             state,
3982             "swgl_isTextureLinear",
3983             None,
3984             Type::new(Bool),
3985             vec![Type::new(*s)],
3986             RunClass::Scalar,
3987         );
3988         declare_function_ext(
3989             state,
3990             "swgl_isTextureRGBA8",
3991             None,
3992             Type::new(Bool),
3993             vec![Type::new(*s)],
3994             RunClass::Scalar,
3995         );
3996         declare_function_ext(
3997             state,
3998             "swgl_isTextureR8",
3999             None,
4000             Type::new(Bool),
4001             vec![Type::new(*s)],
4002             RunClass::Scalar,
4003         );
4004         declare_function(
4005             state,
4006             "swgl_commitTextureLinearRGBA8",
4007             None,
4008             Type::new(Void),
4009             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4010         );
4011         declare_function(
4012             state,
4013             "swgl_commitTextureLinearR8",
4014             None,
4015             Type::new(Void),
4016             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4017         );
4018         declare_function(
4019             state,
4020             "swgl_commitTextureLinearR8ToRGBA8",
4021             None,
4022             Type::new(Void),
4023             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4024         );
4025         declare_function(
4026             state,
4027             "swgl_commitPartialTextureLinearR8",
4028             None,
4029             Type::new(Void),
4030             vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4031         );
4032         declare_function(
4033             state,
4034             "swgl_commitPartialTextureLinearInvertR8",
4035             None,
4036             Type::new(Void),
4037             vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4038         );
4039         declare_function(
4040             state,
4041             "swgl_commitTextureLinearColorRGBA8",
4042             None,
4043             Type::new(Void),
4044             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4045         );
4046         declare_function(
4047             state,
4048             "swgl_commitTextureLinearColorRGBA8",
4049             None,
4050             Type::new(Void),
4051             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
4052         );
4053         declare_function(
4054             state,
4055             "swgl_commitTextureLinearColorR8",
4056             None,
4057             Type::new(Void),
4058             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
4059         );
4060         declare_function(
4061             state,
4062             "swgl_commitTextureLinearColorR8ToRGBA8",
4063             None,
4064             Type::new(Void),
4065             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4066         );
4067 
4068         declare_function(
4069             state,
4070             "swgl_commitTextureLinearRepeatRGBA8",
4071             None,
4072             Type::new(Void),
4073             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4074                  Type::new(Vec4), Type::new(Vec4)],
4075         );
4076         declare_function(
4077             state,
4078             "swgl_commitTextureLinearRepeatColorRGBA8",
4079             None,
4080             Type::new(Void),
4081             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4082                  Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4083         );
4084 
4085         declare_function(
4086             state,
4087             "swgl_commitTextureNearestRGBA8",
4088             None,
4089             Type::new(Void),
4090             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4091         );
4092         declare_function(
4093             state,
4094             "swgl_commitTextureNearestColorRGBA8",
4095             None,
4096             Type::new(Void),
4097             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4098         );
4099         declare_function(
4100             state,
4101             "swgl_commitTextureNearestRepeatRGBA8",
4102             None,
4103             Type::new(Void),
4104             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4105                  Type::new(Vec4), Type::new(Vec4)],
4106         );
4107         declare_function(
4108             state,
4109             "swgl_commitTextureNearestRepeatColorRGBA8",
4110             None,
4111             Type::new(Void),
4112             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4113                  Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4114         );
4115 
4116         declare_function(
4117             state,
4118             "swgl_commitTextureRGBA8",
4119             None,
4120             Type::new(Void),
4121             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4122         );
4123         declare_function(
4124             state,
4125             "swgl_commitTextureColorRGBA8",
4126             None,
4127             Type::new(Void),
4128             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4129         );
4130         declare_function(
4131             state,
4132             "swgl_commitTextureRepeatRGBA8",
4133             None,
4134             Type::new(Void),
4135             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4136                  Type::new(Vec4), Type::new(Vec4)],
4137         );
4138         declare_function(
4139             state,
4140             "swgl_commitTextureRepeatColorRGBA8",
4141             None,
4142             Type::new(Void),
4143             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4144                  Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4145         );
4146 
4147         declare_function(
4148             state,
4149             "swgl_commitGaussianBlurRGBA8",
4150             None,
4151             Type::new(Void),
4152             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
4153                  Type::new(Int), Type::new(Vec2)],
4154         );
4155         declare_function(
4156             state,
4157             "swgl_commitGaussianBlurR8",
4158             None,
4159             Type::new(Void),
4160             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
4161                  Type::new(Int), Type::new(Vec2)],
4162         );
4163         declare_function(
4164             state,
4165             "swgl_commitTextureLinearYUV",
4166             None,
4167             Type::new(Void),
4168             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4169                  Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4170         );
4171         declare_function(
4172             state,
4173             "swgl_commitTextureLinearYUV",
4174             None,
4175             Type::new(Void),
4176             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4177                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4178                  Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4179         );
4180         declare_function(
4181             state,
4182             "swgl_commitTextureLinearYUV",
4183             None,
4184             Type::new(Void),
4185             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4186                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4187                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4188                  Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4189         );
4190         declare_function(
4191             state,
4192             "swgl_commitTextureLinearColorYUV",
4193             None,
4194             Type::new(Void),
4195             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4196                  Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4197                  Type::new(Float)],
4198         );
4199         declare_function(
4200             state,
4201             "swgl_commitTextureLinearColorYUV",
4202             None,
4203             Type::new(Void),
4204             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4205                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4206                  Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4207                  Type::new(Float)],
4208         );
4209         declare_function(
4210             state,
4211             "swgl_commitTextureLinearColorYUV",
4212             None,
4213             Type::new(Void),
4214             vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4215                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4216                  Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4217                  Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4218                  Type::new(Float)],
4219         );
4220     }
4221 
4222     TranslationUnit(tu.0.map(state, translate_external_declaration))
4223 }
4224 
infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass4225 fn infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass {
4226     match expr.kind {
4227         ExprKind::Variable(ref i) => {
4228             *assign = *i;
4229             match &state.sym(*i).decl {
4230                 SymDecl::Local(_, _, ref run_class) => *run_class,
4231                 SymDecl::Global(_, _, _, ref run_class) => *run_class,
4232                 _ => panic!(),
4233             }
4234         }
4235         ExprKind::IntConst(_)
4236         | ExprKind::UIntConst(_)
4237         | ExprKind::BoolConst(_)
4238         | ExprKind::FloatConst(_)
4239         | ExprKind::DoubleConst(_) => RunClass::Scalar,
4240         ExprKind::Unary(_, ref e) => infer_expr(state, e),
4241         ExprKind::Binary(_, ref l, ref r) => infer_expr(state, l).merge(infer_expr(state, r)),
4242         ExprKind::Ternary(ref c, ref s, ref e) => infer_expr(state, c)
4243             .merge(infer_expr(state, s))
4244             .merge(infer_expr(state, e)),
4245         ExprKind::Assignment(ref v, _, ref e) => {
4246             let mut sym = SymRef(!0);
4247             let run_class = infer_expr_inner(state, v, &mut sym).merge(infer_expr(state, e));
4248             assert!(sym != SymRef(!0));
4249             state.merge_run_class(sym, run_class)
4250         }
4251         ExprKind::Bracket(ref e, ref indx) => {
4252             infer_expr_inner(state, e, assign).merge(infer_expr(state, indx))
4253         }
4254         ExprKind::FunCall(ref fun, ref args) => {
4255             let arg_classes: Vec<(RunClass, SymRef)> = args
4256                 .iter()
4257                 .map(|e| {
4258                     let mut assign = SymRef(!0);
4259                     let run_class = infer_expr_inner(state, e, &mut assign);
4260                     (run_class, assign)
4261                 })
4262                 .collect();
4263             let run_class = if args.is_empty() {
4264                 RunClass::Scalar
4265             } else {
4266                 arg_classes
4267                     .iter()
4268                     .fold(RunClass::Unknown, |x, &(y, _)| x.merge(y))
4269             };
4270             match fun {
4271                 FunIdentifier::Identifier(ref sym) => match &state.sym(*sym).decl {
4272                     SymDecl::NativeFunction(_, _, ref ret_class) => {
4273                         if *ret_class != RunClass::Unknown {
4274                             *ret_class
4275                         } else {
4276                             run_class
4277                         }
4278                     }
4279                     SymDecl::UserFunction(ref fd, ref run_class) => {
4280                         for (&(mut arg_class, assign), param) in
4281                             arg_classes.iter().zip(fd.prototype.parameters.iter())
4282                         {
4283                             if let FunctionParameterDeclaration::Named(Some(qual), p) = param {
4284                                 match qual {
4285                                     ParameterQualifier::InOut | ParameterQualifier::Out => {
4286                                         if let SymDecl::Local(_, _, param_class) =
4287                                             &state.sym(p.sym).decl
4288                                         {
4289                                             match param_class {
4290                                                 RunClass::Unknown | RunClass::Vector => {
4291                                                     arg_class = RunClass::Vector;
4292                                                 }
4293                                                 RunClass::Dependent(mask) => {
4294                                                     for i in 0 .. 31 {
4295                                                         if (mask & (1 << i)) != 0 {
4296                                                             arg_class =
4297                                                                 arg_class.merge(arg_classes[i].0);
4298                                                         }
4299                                                     }
4300                                                 }
4301                                                 RunClass::Scalar => {}
4302                                             }
4303                                         }
4304                                         assert!(assign != SymRef(!0));
4305                                         state.merge_run_class(assign, arg_class);
4306                                     }
4307                                     _ => {}
4308                                 }
4309                             }
4310                         }
4311                         if fd.prototype.ty.kind == TypeKind::Void {
4312                             RunClass::Scalar
4313                         } else {
4314                             match *run_class {
4315                                 RunClass::Unknown | RunClass::Vector => RunClass::Vector,
4316                                 RunClass::Dependent(mask) => {
4317                                     let mut ret_class = RunClass::Unknown;
4318                                     for i in 0 .. 31 {
4319                                         if (mask & (1 << i)) != 0 {
4320                                             ret_class = ret_class.merge(arg_classes[i].0);
4321                                         }
4322                                     }
4323                                     ret_class
4324                                 }
4325                                 RunClass::Scalar => RunClass::Scalar,
4326                             }
4327                         }
4328                     }
4329                     SymDecl::Struct(..) => run_class,
4330                     _ => panic!(),
4331                 },
4332                 FunIdentifier::Constructor(..) => run_class,
4333             }
4334         }
4335         ExprKind::Dot(ref e, _) => infer_expr_inner(state, e, assign),
4336         ExprKind::SwizzleSelector(ref e, _) => infer_expr_inner(state, e, assign),
4337         ExprKind::PostInc(ref e) => infer_expr_inner(state, e, assign),
4338         ExprKind::PostDec(ref e) => infer_expr_inner(state, e, assign),
4339         ExprKind::Comma(ref a, ref b) => {
4340             infer_expr(state, a);
4341             infer_expr(state, b)
4342         }
4343         ExprKind::Cond(_, ref e) => infer_expr(state, e),
4344         ExprKind::CondMask => RunClass::Vector,
4345     }
4346 }
4347 
infer_expr(state: &mut State, expr: &Expr) -> RunClass4348 fn infer_expr(state: &mut State, expr: &Expr) -> RunClass {
4349     infer_expr_inner(state, expr, &mut SymRef(!0))
4350 }
4351 
infer_condition(state: &mut State, c: &Condition)4352 fn infer_condition(state: &mut State, c: &Condition) {
4353     match *c {
4354         Condition::Expr(ref e) => {
4355             infer_expr(state, e);
4356         }
4357     }
4358 }
4359 
infer_iteration_statement(state: &mut State, ist: &IterationStatement)4360 fn infer_iteration_statement(state: &mut State, ist: &IterationStatement) {
4361     let changed = state.run_class_changed.replace(true);
4362     match *ist {
4363         IterationStatement::While(ref cond, ref body) => {
4364             while state.run_class_changed.replace(false) {
4365                 infer_condition(state, cond);
4366                 infer_statement(state, body);
4367             }
4368         }
4369         IterationStatement::DoWhile(ref body, ref cond) => {
4370             while state.run_class_changed.replace(false) {
4371                 infer_statement(state, body);
4372                 infer_expr(state, cond);
4373             }
4374         }
4375         IterationStatement::For(ref init, ref rest, ref body) => {
4376             match *init {
4377                 ForInitStatement::Expression(ref expr) => {
4378                     if let Some(ref e) = *expr {
4379                         infer_expr(state, e);
4380                     }
4381                 }
4382                 ForInitStatement::Declaration(ref d) => {
4383                     infer_declaration(state, d);
4384                 }
4385             }
4386             while state.run_class_changed.replace(false) {
4387                 if let Some(ref cond) = rest.condition {
4388                     infer_condition(state, cond);
4389                 }
4390                 if let Some(ref e) = rest.post_expr {
4391                     infer_expr(state, e);
4392                 }
4393                 infer_statement(state, body);
4394             }
4395         }
4396     }
4397     state.run_class_changed.set(changed);
4398 }
4399 
infer_selection_statement(state: &mut State, sst: &SelectionStatement)4400 fn infer_selection_statement(state: &mut State, sst: &SelectionStatement) {
4401     let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.cond));
4402     mem::swap(&mut state.branch_run_class, &mut branch_run_class);
4403     let branch_declaration = state.branch_declaration;
4404     state.branch_declaration = state.last_declaration;
4405     infer_statement(state, &sst.body);
4406     if let Some(ref else_st) = sst.else_stmt {
4407         infer_statement(state, else_st);
4408     }
4409     state.branch_run_class = branch_run_class;
4410     state.branch_declaration = branch_declaration;
4411 }
4412 
infer_expression_statement(state: &mut State, est: &ExprStatement)4413 fn infer_expression_statement(state: &mut State, est: &ExprStatement) {
4414     if let Some(ref e) = *est {
4415         infer_expr(state, e);
4416     }
4417 }
4418 
infer_switch_statement(state: &mut State, sst: &SwitchStatement)4419 fn infer_switch_statement(state: &mut State, sst: &SwitchStatement) {
4420     let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.head));
4421     mem::swap(&mut state.branch_run_class, &mut branch_run_class);
4422     let branch_declaration = state.branch_declaration;
4423     state.branch_declaration = state.last_declaration;
4424     for case in &sst.cases {
4425         for st in &case.stmts {
4426             infer_statement(state, st);
4427         }
4428     }
4429     state.branch_run_class = branch_run_class;
4430     state.branch_declaration = branch_declaration;
4431 }
4432 
infer_jump_statement(state: &mut State, j: &JumpStatement)4433 fn infer_jump_statement(state: &mut State, j: &JumpStatement) {
4434     match *j {
4435         JumpStatement::Continue => {}
4436         JumpStatement::Break => {}
4437         JumpStatement::Discard => {}
4438         JumpStatement::Return(ref e) => {
4439             if let Some(e) = e {
4440                 let run_class = infer_expr(state, e);
4441                 state.return_run_class(run_class);
4442             }
4443         }
4444     }
4445 }
4446 
infer_initializer(state: &mut State, i: &Initializer) -> RunClass4447 fn infer_initializer(state: &mut State, i: &Initializer) -> RunClass {
4448     match *i {
4449         Initializer::Simple(ref e) => infer_expr(state, e),
4450         Initializer::List(ref list) => {
4451             let mut run_class = RunClass::Unknown;
4452             for ini in list.0.iter() {
4453                 run_class = run_class.merge(infer_initializer(state, ini));
4454             }
4455             run_class
4456         }
4457     }
4458 }
4459 
infer_declaration(state: &mut State, d: &Declaration)4460 fn infer_declaration(state: &mut State, d: &Declaration) {
4461     match *d {
4462         Declaration::FunctionPrototype(..) => {}
4463         Declaration::InitDeclaratorList(ref list) => {
4464             state.last_declaration = list.head.name;
4465 
4466             let mut run_class = RunClass::Unknown;
4467             for decl in &list.tail {
4468                 if let Some(ref initializer) = decl.initializer {
4469                     run_class = run_class.merge(infer_initializer(state, initializer));
4470                 }
4471             }
4472             if let Some(ref initializer) = list.head.initializer {
4473                 run_class = run_class.merge(infer_initializer(state, initializer));
4474                 state.merge_run_class(list.head.name, run_class);
4475             }
4476         }
4477         Declaration::Precision(..) => {}
4478         Declaration::Block(..) => {}
4479         Declaration::Global(..) => {}
4480         Declaration::StructDefinition(..) => {}
4481     }
4482 }
4483 
infer_simple_statement(state: &mut State, sst: &SimpleStatement)4484 fn infer_simple_statement(state: &mut State, sst: &SimpleStatement) {
4485     match *sst {
4486         SimpleStatement::Declaration(ref d) => infer_declaration(state, d),
4487         SimpleStatement::Expression(ref e) => infer_expression_statement(state, e),
4488         SimpleStatement::Selection(ref s) => infer_selection_statement(state, s),
4489         SimpleStatement::Switch(ref s) => infer_switch_statement(state, s),
4490         SimpleStatement::Iteration(ref i) => infer_iteration_statement(state, i),
4491         SimpleStatement::Jump(ref j) => infer_jump_statement(state, j),
4492     }
4493 }
4494 
infer_compound_statement(state: &mut State, cst: &CompoundStatement)4495 fn infer_compound_statement(state: &mut State, cst: &CompoundStatement) {
4496     for st in &cst.statement_list {
4497         infer_statement(state, st);
4498     }
4499 }
4500 
infer_statement(state: &mut State, st: &Statement)4501 fn infer_statement(state: &mut State, st: &Statement) {
4502     match *st {
4503         Statement::Compound(ref cst) => infer_compound_statement(state, cst),
4504         Statement::Simple(ref sst) => infer_simple_statement(state, sst),
4505     }
4506 }
4507 
infer_function_definition(state: &mut State, fd: &FunctionDefinition)4508 fn infer_function_definition(state: &mut State, fd: &FunctionDefinition) {
4509     state.in_function = Some(state.lookup(fd.prototype.name.as_str()).unwrap());
4510 
4511     state.run_class_changed.set(true);
4512     while state.run_class_changed.replace(false) {
4513         for st in &fd.body.statement_list {
4514             infer_statement(state, st);
4515         }
4516     }
4517 
4518     state.in_function = None;
4519 }
4520 
infer_external_declaration(state: &mut State, ed: &ExternalDeclaration)4521 fn infer_external_declaration(state: &mut State, ed: &ExternalDeclaration) {
4522     match *ed {
4523         ExternalDeclaration::Preprocessor(_) => {}
4524         ExternalDeclaration::FunctionDefinition(ref fd) => infer_function_definition(state, fd),
4525         ExternalDeclaration::Declaration(_) => {}
4526     }
4527 }
4528 
infer_run_class(state: &mut State, tu: &TranslationUnit)4529 pub fn infer_run_class(state: &mut State, tu: &TranslationUnit) {
4530     for ed in &(tu.0).0 {
4531         infer_external_declaration(state, ed);
4532     }
4533 }
4534