1 //! Front end for consuming [WebGPU Shading Language][wgsl].
2 //!
3 //! [wgsl]: https://gpuweb.github.io/gpuweb/wgsl.html
4 
5 mod conv;
6 mod layout;
7 mod lexer;
8 #[cfg(test)]
9 mod tests;
10 
11 use crate::{
12     arena::{Arena, Handle},
13     proc::{ensure_block_returns, ResolveContext, ResolveError, TypeResolution},
14     FastHashMap,
15 };
16 
17 use self::lexer::Lexer;
18 use codespan_reporting::{
19     diagnostic::{Diagnostic, Label},
20     files::{Files, SimpleFile},
21     term::{
22         self,
23         termcolor::{ColorChoice, ColorSpec, StandardStream, WriteColor},
24     },
25 };
26 use std::{
27     io::{self, Write},
28     iter,
29     num::NonZeroU32,
30     ops,
31 };
32 use thiserror::Error;
33 
34 type Span = ops::Range<usize>;
35 type TokenSpan<'a> = (Token<'a>, Span);
36 
37 #[derive(Copy, Clone, Debug, PartialEq)]
38 pub enum Token<'a> {
39     Separator(char),
40     DoubleColon,
41     Paren(char),
42     DoubleParen(char),
43     Number {
44         value: &'a str,
45         ty: char,
46         width: &'a str,
47     },
48     String(&'a str),
49     Word(&'a str),
50     Operation(char),
51     LogicalOperation(char),
52     ShiftOperation(char),
53     Arrow,
54     Unknown(char),
55     UnterminatedString,
56     Trivia,
57     End,
58 }
59 
60 #[derive(Clone, Debug, Error)]
61 pub enum Error<'a> {
62     #[error("")]
63     Unexpected(TokenSpan<'a>, &'a str),
64     #[error("")]
65     BadInteger(Span),
66     #[error("")]
67     BadFloat(Span),
68     #[error("")]
69     BadScalarWidth(Span, &'a str),
70     #[error("")]
71     BadAccessor(Span),
72     #[error("bad texture {0}`")]
73     BadTexture(&'a str),
74     #[error("bad texture coordinate")]
75     BadCoordinate,
76     #[error("invalid type cast to `{0}`")]
77     BadTypeCast(&'a str),
78     #[error(transparent)]
79     InvalidResolve(ResolveError),
80     #[error("for(;;) initializer is not an assignment or a function call")]
81     InvalidForInitializer,
82     #[error("resource type {0:?} is invalid")]
83     InvalidResourceType(Handle<crate::Type>),
84     #[error("unknown import: `{0}`")]
85     UnknownImport(&'a str),
86     #[error("unknown storage class: `{0}`")]
87     UnknownStorageClass(&'a str),
88     #[error("unknown attribute: `{0}`")]
89     UnknownAttribute(&'a str),
90     #[error("unknown scalar kind: `{0}`")]
91     UnknownScalarKind(&'a str),
92     #[error("unknown builtin: `{0}`")]
93     UnknownBuiltin(&'a str),
94     #[error("unknown access: `{0}`")]
95     UnknownAccess(&'a str),
96     #[error("unknown shader stage: `{0}`")]
97     UnknownShaderStage(&'a str),
98     #[error("unknown identifier: `{0}`")]
99     UnknownIdent(&'a str),
100     #[error("unknown scalar type: `{0}`")]
101     UnknownScalarType(&'a str),
102     #[error("unknown type: `{0}`")]
103     UnknownType(&'a str),
104     #[error("unknown function: `{0}`")]
105     UnknownFunction(&'a str),
106     #[error("unknown storage format: `{0}`")]
107     UnknownStorageFormat(&'a str),
108     #[error("unknown conservative depth: `{0}`")]
109     UnknownConservativeDepth(&'a str),
110     #[error("array stride must not be 0")]
111     ZeroStride,
112     #[error("struct member size or array must not be 0")]
113     ZeroSizeOrAlign,
114     #[error("not a composite type: {0:?}")]
115     NotCompositeType(Handle<crate::Type>),
116     #[error("Input/output binding is not consistent: location {0:?}, built-in {1:?}, interpolation {2:?}, and sampling {3:?}")]
117     InconsistentBinding(
118         Option<u32>,
119         Option<crate::BuiltIn>,
120         Option<crate::Interpolation>,
121         Option<crate::Sampling>,
122     ),
123     #[error("call to local `{0}(..)` can't be resolved")]
124     UnknownLocalFunction(&'a str),
125     #[error("builtin {0:?} is not implemented")]
126     UnimplementedBuiltin(crate::BuiltIn),
127     #[error("expression {0} doesn't match its given type {1:?}")]
128     LetTypeMismatch(&'a str, Handle<crate::Type>),
129     #[error("other error")]
130     Other,
131 }
132 
133 impl<'a> Error<'a> {
as_parse_error(&self, source: &'a str) -> ParseError134     fn as_parse_error(&self, source: &'a str) -> ParseError {
135         match *self {
136             Error::Unexpected((_, ref unexpected_span), expected) => ParseError {
137                 message: format!(
138                     "expected {}, found '{}'",
139                     expected,
140                     &source[unexpected_span.clone()],
141                 ),
142                 labels: vec![(unexpected_span.clone(), format!("expected {}", expected))],
143                 notes: vec![],
144             },
145             Error::BadInteger(ref bad_span) => ParseError {
146                 message: format!(
147                     "expected integer literal, found `{}`",
148                     &source[bad_span.clone()],
149                 ),
150                 labels: vec![(bad_span.clone(), "expected integer".to_string())],
151                 notes: vec![],
152             },
153             Error::BadFloat(ref bad_span) => ParseError {
154                 message: format!(
155                     "expected floating-point literal, found `{}`",
156                     &source[bad_span.clone()],
157                 ),
158                 labels: vec![(
159                     bad_span.clone(),
160                     "expected floating-point literal".to_string(),
161                 )],
162                 notes: vec![],
163             },
164             Error::BadScalarWidth(ref bad_span, width) => ParseError {
165                 message: format!("invalid width of `{}` for literal", width,),
166                 labels: vec![(bad_span.clone(), "invalid width".to_string())],
167                 notes: vec!["valid width is 32".to_string()],
168             },
169             Error::BadAccessor(ref accessor_span) => ParseError {
170                 message: format!(
171                     "invalid field accessor `{}`",
172                     &source[accessor_span.clone()],
173                 ),
174                 labels: vec![(accessor_span.clone(), "invalid accessor".to_string())],
175                 notes: vec![],
176             },
177             ref error => ParseError {
178                 message: error.to_string(),
179                 labels: vec![],
180                 notes: vec![],
181             },
182         }
183     }
184 }
185 
186 trait StringValueLookup<'a> {
187     type Value;
lookup(&self, key: &'a str) -> Result<Self::Value, Error<'a>>188     fn lookup(&self, key: &'a str) -> Result<Self::Value, Error<'a>>;
189 }
190 impl<'a> StringValueLookup<'a> for FastHashMap<&'a str, Handle<crate::Expression>> {
191     type Value = Handle<crate::Expression>;
lookup(&self, key: &'a str) -> Result<Self::Value, Error<'a>>192     fn lookup(&self, key: &'a str) -> Result<Self::Value, Error<'a>> {
193         self.get(key).cloned().ok_or(Error::UnknownIdent(key))
194     }
195 }
196 
197 struct StatementContext<'input, 'temp, 'out> {
198     lookup_ident: &'temp mut FastHashMap<&'input str, Handle<crate::Expression>>,
199     typifier: &'temp mut super::Typifier,
200     variables: &'out mut Arena<crate::LocalVariable>,
201     expressions: &'out mut Arena<crate::Expression>,
202     types: &'out mut Arena<crate::Type>,
203     constants: &'out mut Arena<crate::Constant>,
204     global_vars: &'out Arena<crate::GlobalVariable>,
205     functions: &'out Arena<crate::Function>,
206     arguments: &'out [crate::FunctionArgument],
207 }
208 
209 impl<'a, 'temp> StatementContext<'a, 'temp, '_> {
reborrow(&mut self) -> StatementContext<'a, '_, '_>210     fn reborrow(&mut self) -> StatementContext<'a, '_, '_> {
211         StatementContext {
212             lookup_ident: self.lookup_ident,
213             typifier: self.typifier,
214             variables: self.variables,
215             expressions: self.expressions,
216             types: self.types,
217             constants: self.constants,
218             global_vars: self.global_vars,
219             functions: self.functions,
220             arguments: self.arguments,
221         }
222     }
223 
as_expression<'t>( &'t mut self, block: &'t mut crate::Block, emitter: &'t mut super::Emitter, ) -> ExpressionContext<'a, 't, '_> where 'temp: 't,224     fn as_expression<'t>(
225         &'t mut self,
226         block: &'t mut crate::Block,
227         emitter: &'t mut super::Emitter,
228     ) -> ExpressionContext<'a, 't, '_>
229     where
230         'temp: 't,
231     {
232         ExpressionContext {
233             lookup_ident: self.lookup_ident,
234             typifier: self.typifier,
235             expressions: self.expressions,
236             types: self.types,
237             constants: self.constants,
238             global_vars: self.global_vars,
239             local_vars: self.variables,
240             functions: self.functions,
241             arguments: self.arguments,
242             block,
243             emitter,
244         }
245     }
246 }
247 
248 struct SamplingContext {
249     image: Handle<crate::Expression>,
250     arrayed: bool,
251 }
252 
253 struct ExpressionContext<'input, 'temp, 'out> {
254     lookup_ident: &'temp FastHashMap<&'input str, Handle<crate::Expression>>,
255     typifier: &'temp mut super::Typifier,
256     expressions: &'out mut Arena<crate::Expression>,
257     types: &'out mut Arena<crate::Type>,
258     constants: &'out mut Arena<crate::Constant>,
259     global_vars: &'out Arena<crate::GlobalVariable>,
260     local_vars: &'out Arena<crate::LocalVariable>,
261     arguments: &'out [crate::FunctionArgument],
262     functions: &'out Arena<crate::Function>,
263     block: &'temp mut crate::Block,
264     emitter: &'temp mut super::Emitter,
265 }
266 
267 impl<'a> ExpressionContext<'a, '_, '_> {
reborrow(&mut self) -> ExpressionContext<'a, '_, '_>268     fn reborrow(&mut self) -> ExpressionContext<'a, '_, '_> {
269         ExpressionContext {
270             lookup_ident: self.lookup_ident,
271             typifier: self.typifier,
272             expressions: self.expressions,
273             types: self.types,
274             constants: self.constants,
275             global_vars: self.global_vars,
276             local_vars: self.local_vars,
277             functions: self.functions,
278             arguments: self.arguments,
279             block: self.block,
280             emitter: self.emitter,
281         }
282     }
283 
resolve_type( &mut self, handle: Handle<crate::Expression>, ) -> Result<&crate::TypeInner, Error<'a>>284     fn resolve_type(
285         &mut self,
286         handle: Handle<crate::Expression>,
287     ) -> Result<&crate::TypeInner, Error<'a>> {
288         let resolve_ctx = ResolveContext {
289             constants: self.constants,
290             global_vars: self.global_vars,
291             local_vars: self.local_vars,
292             functions: self.functions,
293             arguments: self.arguments,
294         };
295         match self
296             .typifier
297             .grow(handle, self.expressions, self.types, &resolve_ctx)
298         {
299             Err(e) => Err(Error::InvalidResolve(e)),
300             Ok(()) => Ok(self.typifier.get(handle, self.types)),
301         }
302     }
303 
prepare_sampling(&mut self, image_name: &'a str) -> Result<SamplingContext, Error<'a>>304     fn prepare_sampling(&mut self, image_name: &'a str) -> Result<SamplingContext, Error<'a>> {
305         let image = self.lookup_ident.lookup(image_name)?;
306         Ok(SamplingContext {
307             image,
308             arrayed: match *self.resolve_type(image)? {
309                 crate::TypeInner::Image { arrayed, .. } => arrayed,
310                 _ => return Err(Error::BadTexture(image_name)),
311             },
312         })
313     }
314 
parse_binary_op( &mut self, lexer: &mut Lexer<'a>, classifier: impl Fn(Token<'a>) -> Option<crate::BinaryOperator>, mut parser: impl FnMut( &mut Lexer<'a>, ExpressionContext<'a, '_, '_>, ) -> Result<Handle<crate::Expression>, Error<'a>>, ) -> Result<Handle<crate::Expression>, Error<'a>>315     fn parse_binary_op(
316         &mut self,
317         lexer: &mut Lexer<'a>,
318         classifier: impl Fn(Token<'a>) -> Option<crate::BinaryOperator>,
319         mut parser: impl FnMut(
320             &mut Lexer<'a>,
321             ExpressionContext<'a, '_, '_>,
322         ) -> Result<Handle<crate::Expression>, Error<'a>>,
323     ) -> Result<Handle<crate::Expression>, Error<'a>> {
324         let mut left = parser(lexer, self.reborrow())?;
325         while let Some(op) = classifier(lexer.peek().0) {
326             let _ = lexer.next();
327             let right = parser(lexer, self.reborrow())?;
328             left = self
329                 .expressions
330                 .append(crate::Expression::Binary { op, left, right });
331         }
332         Ok(left)
333     }
334 
parse_binary_splat_op( &mut self, lexer: &mut Lexer<'a>, classifier: impl Fn(Token<'a>) -> Option<crate::BinaryOperator>, mut parser: impl FnMut( &mut Lexer<'a>, ExpressionContext<'a, '_, '_>, ) -> Result<Handle<crate::Expression>, Error<'a>>, ) -> Result<Handle<crate::Expression>, Error<'a>>335     fn parse_binary_splat_op(
336         &mut self,
337         lexer: &mut Lexer<'a>,
338         classifier: impl Fn(Token<'a>) -> Option<crate::BinaryOperator>,
339         mut parser: impl FnMut(
340             &mut Lexer<'a>,
341             ExpressionContext<'a, '_, '_>,
342         ) -> Result<Handle<crate::Expression>, Error<'a>>,
343     ) -> Result<Handle<crate::Expression>, Error<'a>> {
344         let mut left = parser(lexer, self.reborrow())?;
345         while let Some(op) = classifier(lexer.peek().0) {
346             let _ = lexer.next();
347             let mut right = parser(lexer, self.reborrow())?;
348             // insert splats, if needed by the non-'*' operations
349             if op != crate::BinaryOperator::Multiply {
350                 let left_size = match *self.resolve_type(left)? {
351                     crate::TypeInner::Vector { size, .. } => Some(size),
352                     _ => None,
353                 };
354                 match (left_size, self.resolve_type(right)?) {
355                     (Some(size), &crate::TypeInner::Scalar { .. }) => {
356                         right = self
357                             .expressions
358                             .append(crate::Expression::Splat { size, value: right });
359                     }
360                     (None, &crate::TypeInner::Vector { size, .. }) => {
361                         left = self
362                             .expressions
363                             .append(crate::Expression::Splat { size, value: left });
364                     }
365                     _ => {}
366                 }
367             }
368             left = self
369                 .expressions
370                 .append(crate::Expression::Binary { op, left, right });
371         }
372         Ok(left)
373     }
374 }
375 
376 enum Composition {
377     Single(u32),
378     Multi(crate::VectorSize, [crate::SwizzleComponent; 4]),
379 }
380 
381 impl Composition {
382     //TODO: could be `const fn` once MSRV allows
letter_component(letter: char) -> Option<crate::SwizzleComponent>383     fn letter_component(letter: char) -> Option<crate::SwizzleComponent> {
384         use crate::SwizzleComponent as Sc;
385         match letter {
386             'x' | 'r' => Some(Sc::X),
387             'y' | 'g' => Some(Sc::Y),
388             'z' | 'b' => Some(Sc::Z),
389             'w' | 'a' => Some(Sc::W),
390             _ => None,
391         }
392     }
393 
extract_impl(name: &str, name_span: Span) -> Result<u32, Error>394     fn extract_impl(name: &str, name_span: Span) -> Result<u32, Error> {
395         let ch = name
396             .chars()
397             .next()
398             .ok_or_else(|| Error::BadAccessor(name_span.clone()))?;
399         match Self::letter_component(ch) {
400             Some(sc) => Ok(sc as u32),
401             None => Err(Error::BadAccessor(name_span)),
402         }
403     }
404 
extract( base: Handle<crate::Expression>, name: &str, name_span: Span, ) -> Result<crate::Expression, Error>405     fn extract(
406         base: Handle<crate::Expression>,
407         name: &str,
408         name_span: Span,
409     ) -> Result<crate::Expression, Error> {
410         Self::extract_impl(name, name_span)
411             .map(|index| crate::Expression::AccessIndex { base, index })
412     }
413 
make(name: &str, name_span: Span) -> Result<Self, Error>414     fn make(name: &str, name_span: Span) -> Result<Self, Error> {
415         if name.len() > 1 {
416             let mut components = [crate::SwizzleComponent::X; 4];
417             for (comp, ch) in components.iter_mut().zip(name.chars()) {
418                 *comp = Self::letter_component(ch)
419                     .ok_or_else(|| Error::BadAccessor(name_span.clone()))?;
420             }
421 
422             let size = match name.len() {
423                 2 => crate::VectorSize::Bi,
424                 3 => crate::VectorSize::Tri,
425                 4 => crate::VectorSize::Quad,
426                 _ => return Err(Error::BadAccessor(name_span)),
427             };
428             Ok(Composition::Multi(size, components))
429         } else {
430             Self::extract_impl(name, name_span).map(Composition::Single)
431         }
432     }
433 }
434 
435 #[derive(Default)]
436 struct TypeAttributes {
437     stride: Option<NonZeroU32>,
438     access: crate::StorageAccess,
439 }
440 
441 #[derive(Clone, Debug, PartialEq)]
442 pub enum Scope {
443     Attribute,
444     ImportDecl,
445     VariableDecl,
446     TypeDecl,
447     FunctionDecl,
448     Block,
449     Statement,
450     ConstantExpr,
451     PrimaryExpr,
452     SingularExpr,
453     GeneralExpr,
454 }
455 
456 type LocalFunctionCall = (Handle<crate::Function>, Vec<Handle<crate::Expression>>);
457 
458 #[derive(Default)]
459 struct BindingParser {
460     location: Option<u32>,
461     built_in: Option<crate::BuiltIn>,
462     interpolation: Option<crate::Interpolation>,
463     sampling: Option<crate::Sampling>,
464 }
465 
466 impl BindingParser {
parse<'a>(&mut self, lexer: &mut Lexer<'a>, name: &'a str) -> Result<(), Error<'a>>467     fn parse<'a>(&mut self, lexer: &mut Lexer<'a>, name: &'a str) -> Result<(), Error<'a>> {
468         match name {
469             "location" => {
470                 lexer.expect(Token::Paren('('))?;
471                 self.location = Some(lexer.next_uint_literal()?);
472                 lexer.expect(Token::Paren(')'))?;
473             }
474             "builtin" => {
475                 lexer.expect(Token::Paren('('))?;
476                 let raw = lexer.next_ident()?;
477                 self.built_in = Some(conv::map_built_in(raw)?);
478                 lexer.expect(Token::Paren(')'))?;
479             }
480             "interpolate" => {
481                 lexer.expect(Token::Paren('('))?;
482                 let raw = lexer.next_ident()?;
483                 self.interpolation = Some(conv::map_interpolation(raw)?);
484                 if lexer.skip(Token::Separator(',')) {
485                     let raw = lexer.next_ident()?;
486                     self.sampling = Some(conv::map_sampling(raw)?);
487                 }
488                 lexer.expect(Token::Paren(')'))?;
489             }
490             _ => return Err(Error::UnknownAttribute(name)),
491         }
492         Ok(())
493     }
494 
finish<'a>(self) -> Result<Option<crate::Binding>, Error<'a>>495     fn finish<'a>(self) -> Result<Option<crate::Binding>, Error<'a>> {
496         match (
497             self.location,
498             self.built_in,
499             self.interpolation,
500             self.sampling,
501         ) {
502             (None, None, None, None) => Ok(None),
503             (Some(location), None, interpolation, sampling) => {
504                 // Before handing over the completed `Module`, we call
505                 // `apply_common_default_interpolation` to ensure that the interpolation and
506                 // sampling have been explicitly specified on all vertex shader output and fragment
507                 // shader input user bindings, so leaving them potentially `None` here is fine.
508                 Ok(Some(crate::Binding::Location {
509                     location,
510                     interpolation,
511                     sampling,
512                 }))
513             }
514             (None, Some(bi), None, None) => Ok(Some(crate::Binding::BuiltIn(bi))),
515             (location, built_in, interpolation, sampling) => Err(Error::InconsistentBinding(
516                 location,
517                 built_in,
518                 interpolation,
519                 sampling,
520             )),
521         }
522     }
523 }
524 
525 struct ParsedVariable<'a> {
526     name: &'a str,
527     class: Option<crate::StorageClass>,
528     ty: Handle<crate::Type>,
529     access: crate::StorageAccess,
530     init: Option<Handle<crate::Constant>>,
531 }
532 
533 #[derive(Clone, Debug)]
534 pub struct ParseError {
535     message: String,
536     labels: Vec<(Span, String)>,
537     notes: Vec<String>,
538 }
539 
540 impl ParseError {
diagnostic(&self) -> Diagnostic<()>541     fn diagnostic(&self) -> Diagnostic<()> {
542         let diagnostic = Diagnostic::error()
543             .with_message(self.message.to_string())
544             .with_labels(
545                 self.labels
546                     .iter()
547                     .map(|label| {
548                         Label::primary((), label.0.clone()).with_message(label.1.to_string())
549                     })
550                     .collect(),
551             )
552             .with_notes(
553                 self.notes
554                     .iter()
555                     .map(|note| format!("note: {}", note))
556                     .collect(),
557             );
558         diagnostic
559     }
560 
561     /// Emits a summary of the error to standard error stream.
emit_to_stderr(&self, source: &str)562     pub fn emit_to_stderr(&self, source: &str) {
563         let files = SimpleFile::new("wgsl", source);
564         let config = codespan_reporting::term::Config::default();
565         let writer = StandardStream::stderr(ColorChoice::Always);
566         term::emit(&mut writer.lock(), &config, &files, &self.diagnostic())
567             .expect("cannot write error");
568     }
569 
570     /// Emits a summary of the error to a string.
emit_to_string(&self, source: &str) -> String571     pub fn emit_to_string(&self, source: &str) -> String {
572         let files = SimpleFile::new("wgsl", source);
573         let config = codespan_reporting::term::Config::default();
574         let mut writer = StringErrorBuffer::new();
575         term::emit(&mut writer, &config, &files, &self.diagnostic()).expect("cannot write error");
576         writer.into_string()
577     }
578 
579     /// Returns the 1-based line number and column of the first label in the
580     /// error message.
location(&self, source: &str) -> (usize, usize)581     pub fn location(&self, source: &str) -> (usize, usize) {
582         let files = SimpleFile::new("wgsl", source);
583         match self.labels.get(0) {
584             Some(label) => {
585                 let location = files
586                     .location((), label.0.start)
587                     .expect("invalid span location");
588                 (location.line_number, location.column_number)
589             }
590             None => (1, 1),
591         }
592     }
593 }
594 
595 impl std::fmt::Display for ParseError {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result596     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
597         write!(f, "{}", self.message)
598     }
599 }
600 
601 impl std::error::Error for ParseError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>602     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
603         None
604     }
605 }
606 
607 pub struct Parser {
608     scopes: Vec<Scope>,
609     lookup_type: FastHashMap<String, Handle<crate::Type>>,
610     layouter: layout::Layouter,
611 }
612 
613 impl Parser {
new() -> Self614     pub fn new() -> Self {
615         Parser {
616             scopes: Vec::new(),
617             lookup_type: FastHashMap::default(),
618             layouter: Default::default(),
619         }
620     }
621 
get_constant_inner<'a>( word: &'a str, ty: char, width: &'a str, token: TokenSpan<'a>, ) -> Result<crate::ConstantInner, Error<'a>>622     fn get_constant_inner<'a>(
623         word: &'a str,
624         ty: char,
625         width: &'a str,
626         token: TokenSpan<'a>,
627     ) -> Result<crate::ConstantInner, Error<'a>> {
628         let span = token.1;
629         let value = match ty {
630             'i' => word
631                 .parse()
632                 .map(crate::ScalarValue::Sint)
633                 .map_err(|_| Error::BadInteger(span.clone()))?,
634             'u' => word
635                 .parse()
636                 .map(crate::ScalarValue::Uint)
637                 .map_err(|_| Error::BadInteger(span.clone()))?,
638             'f' => word
639                 .parse()
640                 .map(crate::ScalarValue::Float)
641                 .map_err(|_| Error::BadFloat(span.clone()))?,
642             _ => unreachable!(),
643         };
644         Ok(crate::ConstantInner::Scalar {
645             value,
646             width: if width.is_empty() {
647                 4
648             } else {
649                 match width.parse::<crate::Bytes>() {
650                     Ok(bits) => bits / 8,
651                     Err(_) => return Err(Error::BadScalarWidth(span, width)),
652                 }
653             },
654         })
655     }
656 
parse_local_function_call<'a>( &mut self, lexer: &mut Lexer<'a>, name: &'a str, mut ctx: ExpressionContext<'a, '_, '_>, ) -> Result<Option<LocalFunctionCall>, Error<'a>>657     fn parse_local_function_call<'a>(
658         &mut self,
659         lexer: &mut Lexer<'a>,
660         name: &'a str,
661         mut ctx: ExpressionContext<'a, '_, '_>,
662     ) -> Result<Option<LocalFunctionCall>, Error<'a>> {
663         let fun_handle = match ctx.functions.iter().find(|&(_, fun)| match fun.name {
664             Some(ref string) => string == name,
665             None => false,
666         }) {
667             Some((fun_handle, _)) => fun_handle,
668             None => return Ok(None),
669         };
670 
671         let count = ctx.functions[fun_handle].arguments.len();
672         let mut arguments = Vec::with_capacity(count);
673         lexer.open_arguments()?;
674         while arguments.len() != count {
675             if !arguments.is_empty() {
676                 lexer.expect(Token::Separator(','))?;
677             }
678             let arg = self.parse_general_expression(lexer, ctx.reborrow())?;
679             arguments.push(arg);
680         }
681         lexer.close_arguments()?;
682         Ok(Some((fun_handle, arguments)))
683     }
684 
parse_function_call_inner<'a>( &mut self, lexer: &mut Lexer<'a>, name: &'a str, mut ctx: ExpressionContext<'a, '_, '_>, ) -> Result<Option<Handle<crate::Expression>>, Error<'a>>685     fn parse_function_call_inner<'a>(
686         &mut self,
687         lexer: &mut Lexer<'a>,
688         name: &'a str,
689         mut ctx: ExpressionContext<'a, '_, '_>,
690     ) -> Result<Option<Handle<crate::Expression>>, Error<'a>> {
691         let expr = if let Some(fun) = conv::map_relational_fun(name) {
692             lexer.open_arguments()?;
693             let argument = self.parse_general_expression(lexer, ctx.reborrow())?;
694             lexer.close_arguments()?;
695             crate::Expression::Relational { fun, argument }
696         } else if let Some(axis) = conv::map_derivative_axis(name) {
697             lexer.open_arguments()?;
698             let expr = self.parse_general_expression(lexer, ctx.reborrow())?;
699             lexer.close_arguments()?;
700             crate::Expression::Derivative { axis, expr }
701         } else if let Some(fun) = conv::map_standard_fun(name) {
702             lexer.open_arguments()?;
703             let arg_count = fun.argument_count();
704             let arg = self.parse_general_expression(lexer, ctx.reborrow())?;
705             let arg1 = if arg_count > 1 {
706                 lexer.expect(Token::Separator(','))?;
707                 Some(self.parse_general_expression(lexer, ctx.reborrow())?)
708             } else {
709                 None
710             };
711             let arg2 = if arg_count > 2 {
712                 lexer.expect(Token::Separator(','))?;
713                 Some(self.parse_general_expression(lexer, ctx.reborrow())?)
714             } else {
715                 None
716             };
717             lexer.close_arguments()?;
718             crate::Expression::Math {
719                 fun,
720                 arg,
721                 arg1,
722                 arg2,
723             }
724         } else if name == "select" {
725             lexer.open_arguments()?;
726             let accept = self.parse_general_expression(lexer, ctx.reborrow())?;
727             lexer.expect(Token::Separator(','))?;
728             let reject = self.parse_general_expression(lexer, ctx.reborrow())?;
729             lexer.expect(Token::Separator(','))?;
730             let condition = self.parse_general_expression(lexer, ctx.reborrow())?;
731             lexer.close_arguments()?;
732             crate::Expression::Select {
733                 condition,
734                 accept,
735                 reject,
736             }
737         } else if name == "arrayLength" {
738             lexer.open_arguments()?;
739             let array = self.parse_singular_expression(lexer, ctx.reborrow())?;
740             lexer.close_arguments()?;
741             crate::Expression::ArrayLength(array)
742         } else {
743             // texture sampling
744             match name {
745                 "textureSample" => {
746                     lexer.open_arguments()?;
747                     let image_name = lexer.next_ident()?;
748                     lexer.expect(Token::Separator(','))?;
749                     let sampler_name = lexer.next_ident()?;
750                     lexer.expect(Token::Separator(','))?;
751                     let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?;
752                     let sc = ctx.prepare_sampling(image_name)?;
753                     let array_index = if sc.arrayed {
754                         lexer.expect(Token::Separator(','))?;
755                         Some(self.parse_general_expression(lexer, ctx.reborrow())?)
756                     } else {
757                         None
758                     };
759                     let offset = if lexer.skip(Token::Separator(',')) {
760                         Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?)
761                     } else {
762                         None
763                     };
764                     lexer.close_arguments()?;
765                     crate::Expression::ImageSample {
766                         image: sc.image,
767                         sampler: ctx.lookup_ident.lookup(sampler_name)?,
768                         coordinate,
769                         array_index,
770                         offset,
771                         level: crate::SampleLevel::Auto,
772                         depth_ref: None,
773                     }
774                 }
775                 "textureSampleLevel" => {
776                     lexer.open_arguments()?;
777                     let image_name = lexer.next_ident()?;
778                     lexer.expect(Token::Separator(','))?;
779                     let sampler_name = lexer.next_ident()?;
780                     lexer.expect(Token::Separator(','))?;
781                     let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?;
782                     let sc = ctx.prepare_sampling(image_name)?;
783                     let array_index = if sc.arrayed {
784                         lexer.expect(Token::Separator(','))?;
785                         Some(self.parse_general_expression(lexer, ctx.reborrow())?)
786                     } else {
787                         None
788                     };
789                     lexer.expect(Token::Separator(','))?;
790                     let level = self.parse_general_expression(lexer, ctx.reborrow())?;
791                     let offset = if lexer.skip(Token::Separator(',')) {
792                         Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?)
793                     } else {
794                         None
795                     };
796                     lexer.close_arguments()?;
797                     crate::Expression::ImageSample {
798                         image: sc.image,
799                         sampler: ctx.lookup_ident.lookup(sampler_name)?,
800                         coordinate,
801                         array_index,
802                         offset,
803                         level: crate::SampleLevel::Exact(level),
804                         depth_ref: None,
805                     }
806                 }
807                 "textureSampleBias" => {
808                     lexer.open_arguments()?;
809                     let image_name = lexer.next_ident()?;
810                     lexer.expect(Token::Separator(','))?;
811                     let sampler_name = lexer.next_ident()?;
812                     lexer.expect(Token::Separator(','))?;
813                     let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?;
814                     let sc = ctx.prepare_sampling(image_name)?;
815                     let array_index = if sc.arrayed {
816                         lexer.expect(Token::Separator(','))?;
817                         Some(self.parse_general_expression(lexer, ctx.reborrow())?)
818                     } else {
819                         None
820                     };
821                     lexer.expect(Token::Separator(','))?;
822                     let bias = self.parse_general_expression(lexer, ctx.reborrow())?;
823                     let offset = if lexer.skip(Token::Separator(',')) {
824                         Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?)
825                     } else {
826                         None
827                     };
828                     lexer.close_arguments()?;
829                     crate::Expression::ImageSample {
830                         image: sc.image,
831                         sampler: ctx.lookup_ident.lookup(sampler_name)?,
832                         coordinate,
833                         array_index,
834                         offset,
835                         level: crate::SampleLevel::Bias(bias),
836                         depth_ref: None,
837                     }
838                 }
839                 "textureSampleGrad" => {
840                     lexer.open_arguments()?;
841                     let image_name = lexer.next_ident()?;
842                     lexer.expect(Token::Separator(','))?;
843                     let sampler_name = lexer.next_ident()?;
844                     lexer.expect(Token::Separator(','))?;
845                     let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?;
846                     let sc = ctx.prepare_sampling(image_name)?;
847                     let array_index = if sc.arrayed {
848                         lexer.expect(Token::Separator(','))?;
849                         Some(self.parse_general_expression(lexer, ctx.reborrow())?)
850                     } else {
851                         None
852                     };
853                     lexer.expect(Token::Separator(','))?;
854                     let x = self.parse_general_expression(lexer, ctx.reborrow())?;
855                     lexer.expect(Token::Separator(','))?;
856                     let y = self.parse_general_expression(lexer, ctx.reborrow())?;
857                     let offset = if lexer.skip(Token::Separator(',')) {
858                         Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?)
859                     } else {
860                         None
861                     };
862                     lexer.close_arguments()?;
863                     crate::Expression::ImageSample {
864                         image: sc.image,
865                         sampler: ctx.lookup_ident.lookup(sampler_name)?,
866                         coordinate,
867                         array_index,
868                         offset,
869                         level: crate::SampleLevel::Gradient { x, y },
870                         depth_ref: None,
871                     }
872                 }
873                 "textureSampleCompare" => {
874                     lexer.open_arguments()?;
875                     let image_name = lexer.next_ident()?;
876                     lexer.expect(Token::Separator(','))?;
877                     let sampler_name = lexer.next_ident()?;
878                     lexer.expect(Token::Separator(','))?;
879                     let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?;
880                     let sc = ctx.prepare_sampling(image_name)?;
881                     let array_index = if sc.arrayed {
882                         lexer.expect(Token::Separator(','))?;
883                         Some(self.parse_general_expression(lexer, ctx.reborrow())?)
884                     } else {
885                         None
886                     };
887                     lexer.expect(Token::Separator(','))?;
888                     let reference = self.parse_general_expression(lexer, ctx.reborrow())?;
889                     let offset = if lexer.skip(Token::Separator(',')) {
890                         Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?)
891                     } else {
892                         None
893                     };
894                     lexer.close_arguments()?;
895                     crate::Expression::ImageSample {
896                         image: sc.image,
897                         sampler: ctx.lookup_ident.lookup(sampler_name)?,
898                         coordinate,
899                         array_index,
900                         offset,
901                         level: crate::SampleLevel::Zero,
902                         depth_ref: Some(reference),
903                     }
904                 }
905                 "textureLoad" => {
906                     lexer.open_arguments()?;
907                     let image_name = lexer.next_ident()?;
908                     let image = ctx.lookup_ident.lookup(image_name)?;
909                     lexer.expect(Token::Separator(','))?;
910                     let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?;
911                     let (class, arrayed) = match *ctx.resolve_type(image)? {
912                         crate::TypeInner::Image { class, arrayed, .. } => (class, arrayed),
913                         _ => return Err(Error::BadTexture(image_name)),
914                     };
915                     let array_index = if arrayed {
916                         lexer.expect(Token::Separator(','))?;
917                         Some(self.parse_general_expression(lexer, ctx.reborrow())?)
918                     } else {
919                         None
920                     };
921                     let index = match class {
922                         crate::ImageClass::Storage(_) => None,
923                         // it's the MSAA index for multi-sampled, and LOD for the others
924                         crate::ImageClass::Sampled { .. } | crate::ImageClass::Depth => {
925                             lexer.expect(Token::Separator(','))?;
926                             Some(self.parse_general_expression(lexer, ctx.reborrow())?)
927                         }
928                     };
929                     lexer.close_arguments()?;
930                     crate::Expression::ImageLoad {
931                         image,
932                         coordinate,
933                         array_index,
934                         index,
935                     }
936                 }
937                 "textureDimensions" => {
938                     lexer.open_arguments()?;
939                     let image_name = lexer.next_ident()?;
940                     let image = ctx.lookup_ident.lookup(image_name)?;
941                     let level = if lexer.skip(Token::Separator(',')) {
942                         let expr = self.parse_general_expression(lexer, ctx.reborrow())?;
943                         Some(expr)
944                     } else {
945                         None
946                     };
947                     lexer.close_arguments()?;
948                     crate::Expression::ImageQuery {
949                         image,
950                         query: crate::ImageQuery::Size { level },
951                     }
952                 }
953                 "textureNumLevels" => {
954                     lexer.open_arguments()?;
955                     let image_name = lexer.next_ident()?;
956                     let image = ctx.lookup_ident.lookup(image_name)?;
957                     lexer.close_arguments()?;
958                     crate::Expression::ImageQuery {
959                         image,
960                         query: crate::ImageQuery::NumLevels,
961                     }
962                 }
963                 "textureNumLayers" => {
964                     lexer.open_arguments()?;
965                     let image_name = lexer.next_ident()?;
966                     let image = ctx.lookup_ident.lookup(image_name)?;
967                     lexer.close_arguments()?;
968                     crate::Expression::ImageQuery {
969                         image,
970                         query: crate::ImageQuery::NumLayers,
971                     }
972                 }
973                 "textureNumSamples" => {
974                     lexer.open_arguments()?;
975                     let image_name = lexer.next_ident()?;
976                     let image = ctx.lookup_ident.lookup(image_name)?;
977                     lexer.close_arguments()?;
978                     crate::Expression::ImageQuery {
979                         image,
980                         query: crate::ImageQuery::NumSamples,
981                     }
982                 }
983                 // other
984                 _ => {
985                     let handle =
986                         match self.parse_local_function_call(lexer, name, ctx.reborrow())? {
987                             Some((function, arguments)) => {
988                                 ctx.block.extend(ctx.emitter.finish(ctx.expressions));
989                                 let result =
990                                     Some(ctx.expressions.append(crate::Expression::Call(function)));
991                                 ctx.block.push(crate::Statement::Call {
992                                     function,
993                                     arguments,
994                                     result,
995                                 });
996                                 // restart the emitter
997                                 ctx.emitter.start(ctx.expressions);
998                                 result
999                             }
1000                             None => None,
1001                         };
1002                     return Ok(handle);
1003                 }
1004             }
1005         };
1006         Ok(Some(ctx.expressions.append(expr)))
1007     }
1008 
parse_const_expression_impl<'a>( &mut self, first_token_span: TokenSpan<'a>, lexer: &mut Lexer<'a>, register_name: Option<&'a str>, type_arena: &mut Arena<crate::Type>, const_arena: &mut Arena<crate::Constant>, ) -> Result<Handle<crate::Constant>, Error<'a>>1009     fn parse_const_expression_impl<'a>(
1010         &mut self,
1011         first_token_span: TokenSpan<'a>,
1012         lexer: &mut Lexer<'a>,
1013         register_name: Option<&'a str>,
1014         type_arena: &mut Arena<crate::Type>,
1015         const_arena: &mut Arena<crate::Constant>,
1016     ) -> Result<Handle<crate::Constant>, Error<'a>> {
1017         self.scopes.push(Scope::ConstantExpr);
1018         let inner = match first_token_span {
1019             (Token::Word("true"), _) => crate::ConstantInner::boolean(true),
1020             (Token::Word("false"), _) => crate::ConstantInner::boolean(false),
1021             (
1022                 Token::Number {
1023                     ref value,
1024                     ref ty,
1025                     ref width,
1026                 },
1027                 _,
1028             ) => Self::get_constant_inner(*value, *ty, *width, first_token_span)?,
1029             (Token::Word(name), _) => {
1030                 // look for an existing constant first
1031                 for (handle, var) in const_arena.iter() {
1032                     match var.name {
1033                         Some(ref string) if string == name => {
1034                             self.scopes.pop();
1035                             return Ok(handle);
1036                         }
1037                         _ => {}
1038                     }
1039                 }
1040                 let composite_ty = self.parse_type_decl_name(
1041                     lexer,
1042                     name,
1043                     None,
1044                     TypeAttributes::default(),
1045                     type_arena,
1046                     const_arena,
1047                 )?;
1048 
1049                 lexer.open_arguments()?;
1050                 //Note: this expects at least one argument
1051                 let mut components = Vec::new();
1052                 while components.is_empty() || lexer.next_argument()? {
1053                     let component = self.parse_const_expression(lexer, type_arena, const_arena)?;
1054                     components.push(component);
1055                 }
1056                 crate::ConstantInner::Composite {
1057                     ty: composite_ty,
1058                     components,
1059                 }
1060             }
1061             other => return Err(Error::Unexpected(other, "constant")),
1062         };
1063 
1064         let handle = if let Some(name) = register_name {
1065             const_arena.append(crate::Constant {
1066                 name: Some(name.to_string()),
1067                 specialization: None,
1068                 inner,
1069             })
1070         } else {
1071             const_arena.fetch_or_append(crate::Constant {
1072                 name: None,
1073                 specialization: None,
1074                 inner,
1075             })
1076         };
1077 
1078         self.scopes.pop();
1079         Ok(handle)
1080     }
1081 
parse_const_expression<'a>( &mut self, lexer: &mut Lexer<'a>, type_arena: &mut Arena<crate::Type>, const_arena: &mut Arena<crate::Constant>, ) -> Result<Handle<crate::Constant>, Error<'a>>1082     fn parse_const_expression<'a>(
1083         &mut self,
1084         lexer: &mut Lexer<'a>,
1085         type_arena: &mut Arena<crate::Type>,
1086         const_arena: &mut Arena<crate::Constant>,
1087     ) -> Result<Handle<crate::Constant>, Error<'a>> {
1088         self.parse_const_expression_impl(lexer.next(), lexer, None, type_arena, const_arena)
1089     }
1090 
parse_primary_expression<'a>( &mut self, lexer: &mut Lexer<'a>, mut ctx: ExpressionContext<'a, '_, '_>, ) -> Result<Handle<crate::Expression>, Error<'a>>1091     fn parse_primary_expression<'a>(
1092         &mut self,
1093         lexer: &mut Lexer<'a>,
1094         mut ctx: ExpressionContext<'a, '_, '_>,
1095     ) -> Result<Handle<crate::Expression>, Error<'a>> {
1096         self.scopes.push(Scope::PrimaryExpr);
1097         let handle = match lexer.next() {
1098             (Token::Paren('('), _) => {
1099                 let expr = self.parse_general_expression(lexer, ctx)?;
1100                 lexer.expect(Token::Paren(')'))?;
1101                 expr
1102             }
1103             token @ (Token::Word("true"), _)
1104             | token @ (Token::Word("false"), _)
1105             | token @ (Token::Number { .. }, _) => {
1106                 let const_handle =
1107                     self.parse_const_expression_impl(token, lexer, None, ctx.types, ctx.constants)?;
1108                 // pause the emitter while generating this expression, since it's pre-emitted
1109                 ctx.block.extend(ctx.emitter.finish(ctx.expressions));
1110                 let expr = ctx
1111                     .expressions
1112                     .append(crate::Expression::Constant(const_handle));
1113                 ctx.emitter.start(ctx.expressions);
1114                 expr
1115             }
1116             (Token::Word(word), _) => {
1117                 if let Some(&expr) = ctx.lookup_ident.get(word) {
1118                     expr
1119                 } else if let Some(expr) =
1120                     self.parse_function_call_inner(lexer, word, ctx.reborrow())?
1121                 {
1122                     //TODO: resolve the duplicate call in `parse_singular_expression`
1123                     expr
1124                 } else {
1125                     let ty_resolution = match self.lookup_type.get(word) {
1126                         Some(&handle) => TypeResolution::Handle(handle),
1127                         None => {
1128                             let inner = self.parse_type_decl_impl(
1129                                 lexer,
1130                                 TypeAttributes::default(),
1131                                 word,
1132                                 ctx.types,
1133                                 ctx.constants,
1134                             )?;
1135                             TypeResolution::Value(inner)
1136                         }
1137                     };
1138 
1139                     lexer.open_arguments()?;
1140                     let mut components = Vec::new();
1141                     let mut last_component =
1142                         self.parse_general_expression(lexer, ctx.reborrow())?;
1143                     while lexer.next_argument()? {
1144                         components.push(last_component);
1145                         last_component = self.parse_general_expression(lexer, ctx.reborrow())?;
1146                     }
1147 
1148                     let expr = if components.is_empty()
1149                         && ty_resolution.inner_with(ctx.types).scalar_kind().is_some()
1150                     {
1151                         // We can't use the `TypeInner` returned by this because
1152                         // `resolve_type` borrows context mutably.
1153                         // Use it to insert into the right maps,
1154                         // and then grab it again immutably.
1155                         ctx.resolve_type(last_component)?;
1156                         match (
1157                             ty_resolution.inner_with(ctx.types),
1158                             ctx.typifier.get(last_component, ctx.types),
1159                         ) {
1160                             (
1161                                 &crate::TypeInner::Vector { size, .. },
1162                                 &crate::TypeInner::Scalar { .. },
1163                             ) => crate::Expression::Splat {
1164                                 size,
1165                                 value: last_component,
1166                             },
1167                             (
1168                                 &crate::TypeInner::Scalar { kind, width, .. },
1169                                 &crate::TypeInner::Scalar { .. },
1170                             )
1171                             | (
1172                                 &crate::TypeInner::Vector { kind, width, .. },
1173                                 &crate::TypeInner::Vector { .. },
1174                             ) => crate::Expression::As {
1175                                 expr: last_component,
1176                                 kind,
1177                                 convert: Some(width),
1178                             },
1179                             (
1180                                 &crate::TypeInner::Matrix { width, .. },
1181                                 &crate::TypeInner::Matrix { .. },
1182                             ) => crate::Expression::As {
1183                                 expr: last_component,
1184                                 kind: crate::ScalarKind::Float,
1185                                 convert: Some(width),
1186                             },
1187                             _ => {
1188                                 return Err(Error::BadTypeCast(word));
1189                             }
1190                         }
1191                     } else {
1192                         let ty = match ty_resolution {
1193                             TypeResolution::Handle(handle) => handle,
1194                             TypeResolution::Value(inner) => {
1195                                 ctx.types.fetch_or_append(crate::Type { name: None, inner })
1196                             }
1197                         };
1198                         components.push(last_component);
1199                         crate::Expression::Compose { ty, components }
1200                     };
1201                     ctx.expressions.append(expr)
1202                 }
1203             }
1204             other => return Err(Error::Unexpected(other, "primary expression")),
1205         };
1206         self.scopes.pop();
1207         Ok(handle)
1208     }
1209 
parse_postfix<'a>( &mut self, lexer: &mut Lexer<'a>, mut ctx: ExpressionContext<'a, '_, '_>, mut handle: Handle<crate::Expression>, allow_deref: bool, ) -> Result<Handle<crate::Expression>, Error<'a>>1210     fn parse_postfix<'a>(
1211         &mut self,
1212         lexer: &mut Lexer<'a>,
1213         mut ctx: ExpressionContext<'a, '_, '_>,
1214         mut handle: Handle<crate::Expression>,
1215         allow_deref: bool,
1216     ) -> Result<Handle<crate::Expression>, Error<'a>> {
1217         let mut needs_deref = match ctx.expressions[handle] {
1218             crate::Expression::LocalVariable(_) | crate::Expression::GlobalVariable(_) => {
1219                 allow_deref
1220             }
1221             _ => false,
1222         };
1223         loop {
1224             // insert the E::Load when we reach a value
1225             if needs_deref {
1226                 let now = match *ctx.resolve_type(handle)? {
1227                     crate::TypeInner::Pointer { base, class: _ } => match ctx.types[base].inner {
1228                         crate::TypeInner::Scalar { .. } | crate::TypeInner::Vector { .. } => true,
1229                         _ => false,
1230                     },
1231                     crate::TypeInner::ValuePointer { .. } => true,
1232                     _ => false,
1233                 };
1234                 if now {
1235                     let expression = crate::Expression::Load { pointer: handle };
1236                     handle = ctx.expressions.append(expression);
1237                     needs_deref = false;
1238                 }
1239             }
1240 
1241             let expression = match lexer.peek().0 {
1242                 Token::Separator('.') => {
1243                     let _ = lexer.next();
1244                     let (name, name_span) = lexer.next_ident_with_span()?;
1245                     match *ctx.resolve_type(handle)? {
1246                         crate::TypeInner::Struct { ref members, .. } => {
1247                             let index = members
1248                                 .iter()
1249                                 .position(|m| m.name.as_deref() == Some(name))
1250                                 .ok_or(Error::BadAccessor(name_span))?
1251                                 as u32;
1252                             crate::Expression::AccessIndex {
1253                                 base: handle,
1254                                 index,
1255                             }
1256                         }
1257                         crate::TypeInner::Vector { .. } | crate::TypeInner::Matrix { .. } => {
1258                             match Composition::make(name, name_span)? {
1259                                 Composition::Multi(dst_size, pattern) => {
1260                                     crate::Expression::Swizzle {
1261                                         size: dst_size,
1262                                         vector: handle,
1263                                         pattern,
1264                                     }
1265                                 }
1266                                 Composition::Single(index) => crate::Expression::AccessIndex {
1267                                     base: handle,
1268                                     index,
1269                                 },
1270                             }
1271                         }
1272                         crate::TypeInner::ValuePointer { .. } => {
1273                             Composition::extract(handle, name, name_span)?
1274                         }
1275                         crate::TypeInner::Pointer { base, class: _ } => match ctx.types[base].inner
1276                         {
1277                             crate::TypeInner::Struct { ref members, .. } => {
1278                                 let index = members
1279                                     .iter()
1280                                     .position(|m| m.name.as_deref() == Some(name))
1281                                     .ok_or(Error::BadAccessor(name_span))?
1282                                     as u32;
1283                                 crate::Expression::AccessIndex {
1284                                     base: handle,
1285                                     index,
1286                                 }
1287                             }
1288                             _ => Composition::extract(handle, name, name_span)?,
1289                         },
1290                         _ => return Err(Error::BadAccessor(name_span)),
1291                     }
1292                 }
1293                 Token::Paren('[') => {
1294                     let _ = lexer.next();
1295                     let index = self.parse_general_expression(lexer, ctx.reborrow())?;
1296                     lexer.expect(Token::Paren(']'))?;
1297                     crate::Expression::Access {
1298                         base: handle,
1299                         index,
1300                     }
1301                 }
1302                 _ => {
1303                     // after we reached for the value, load it
1304                     return Ok(if needs_deref {
1305                         let expression = crate::Expression::Load { pointer: handle };
1306                         ctx.expressions.append(expression)
1307                     } else {
1308                         handle
1309                     });
1310                 }
1311             };
1312 
1313             handle = ctx.expressions.append(expression);
1314         }
1315     }
1316 
parse_singular_expression<'a>( &mut self, lexer: &mut Lexer<'a>, mut ctx: ExpressionContext<'a, '_, '_>, ) -> Result<Handle<crate::Expression>, Error<'a>>1317     fn parse_singular_expression<'a>(
1318         &mut self,
1319         lexer: &mut Lexer<'a>,
1320         mut ctx: ExpressionContext<'a, '_, '_>,
1321     ) -> Result<Handle<crate::Expression>, Error<'a>> {
1322         self.scopes.push(Scope::SingularExpr);
1323         //TODO: refactor this to avoid backing up
1324         let backup = lexer.clone();
1325         let (allow_deref, handle) = match lexer.next().0 {
1326             Token::Operation('-') => {
1327                 let expr = crate::Expression::Unary {
1328                     op: crate::UnaryOperator::Negate,
1329                     expr: self.parse_singular_expression(lexer, ctx.reborrow())?,
1330                 };
1331                 (true, ctx.expressions.append(expr))
1332             }
1333             Token::Operation('!') | Token::Operation('~') => {
1334                 let expr = crate::Expression::Unary {
1335                     op: crate::UnaryOperator::Not,
1336                     expr: self.parse_singular_expression(lexer, ctx.reborrow())?,
1337                 };
1338                 (true, ctx.expressions.append(expr))
1339             }
1340             Token::Operation('&') => {
1341                 let handle = self.parse_primary_expression(lexer, ctx.reborrow())?;
1342                 (false, handle)
1343             }
1344             Token::Word(word) => {
1345                 let handle = match self.parse_function_call_inner(lexer, word, ctx.reborrow())? {
1346                     Some(handle) => handle,
1347                     None => {
1348                         *lexer = backup;
1349                         self.parse_primary_expression(lexer, ctx.reborrow())?
1350                     }
1351                 };
1352                 (true, handle)
1353             }
1354             _ => {
1355                 *lexer = backup;
1356                 let handle = self.parse_primary_expression(lexer, ctx.reborrow())?;
1357                 (true, handle)
1358             }
1359         };
1360 
1361         let post_handle = self.parse_postfix(lexer, ctx, handle, allow_deref)?;
1362         self.scopes.pop();
1363         Ok(post_handle)
1364     }
1365 
parse_equality_expression<'a>( &mut self, lexer: &mut Lexer<'a>, mut context: ExpressionContext<'a, '_, '_>, ) -> Result<Handle<crate::Expression>, Error<'a>>1366     fn parse_equality_expression<'a>(
1367         &mut self,
1368         lexer: &mut Lexer<'a>,
1369         mut context: ExpressionContext<'a, '_, '_>,
1370     ) -> Result<Handle<crate::Expression>, Error<'a>> {
1371         // equality_expression
1372         context.parse_binary_op(
1373             lexer,
1374             |token| match token {
1375                 Token::LogicalOperation('=') => Some(crate::BinaryOperator::Equal),
1376                 Token::LogicalOperation('!') => Some(crate::BinaryOperator::NotEqual),
1377                 _ => None,
1378             },
1379             // relational_expression
1380             |lexer, mut context| {
1381                 context.parse_binary_op(
1382                     lexer,
1383                     |token| match token {
1384                         Token::Paren('<') => Some(crate::BinaryOperator::Less),
1385                         Token::Paren('>') => Some(crate::BinaryOperator::Greater),
1386                         Token::LogicalOperation('<') => Some(crate::BinaryOperator::LessEqual),
1387                         Token::LogicalOperation('>') => Some(crate::BinaryOperator::GreaterEqual),
1388                         _ => None,
1389                     },
1390                     // shift_expression
1391                     |lexer, mut context| {
1392                         context.parse_binary_op(
1393                             lexer,
1394                             |token| match token {
1395                                 Token::ShiftOperation('<') => {
1396                                     Some(crate::BinaryOperator::ShiftLeft)
1397                                 }
1398                                 Token::ShiftOperation('>') => {
1399                                     Some(crate::BinaryOperator::ShiftRight)
1400                                 }
1401                                 _ => None,
1402                             },
1403                             // additive_expression
1404                             |lexer, mut context| {
1405                                 context.parse_binary_splat_op(
1406                                     lexer,
1407                                     |token| match token {
1408                                         Token::Operation('+') => Some(crate::BinaryOperator::Add),
1409                                         Token::Operation('-') => {
1410                                             Some(crate::BinaryOperator::Subtract)
1411                                         }
1412                                         _ => None,
1413                                     },
1414                                     // multiplicative_expression
1415                                     |lexer, mut context| {
1416                                         context.parse_binary_splat_op(
1417                                             lexer,
1418                                             |token| match token {
1419                                                 Token::Operation('*') => {
1420                                                     Some(crate::BinaryOperator::Multiply)
1421                                                 }
1422                                                 Token::Operation('/') => {
1423                                                     Some(crate::BinaryOperator::Divide)
1424                                                 }
1425                                                 Token::Operation('%') => {
1426                                                     Some(crate::BinaryOperator::Modulo)
1427                                                 }
1428                                                 _ => None,
1429                                             },
1430                                             |lexer, context| {
1431                                                 self.parse_singular_expression(lexer, context)
1432                                             },
1433                                         )
1434                                     },
1435                                 )
1436                             },
1437                         )
1438                     },
1439                 )
1440             },
1441         )
1442     }
1443 
parse_general_expression<'a>( &mut self, lexer: &mut Lexer<'a>, mut context: ExpressionContext<'a, '_, '_>, ) -> Result<Handle<crate::Expression>, Error<'a>>1444     fn parse_general_expression<'a>(
1445         &mut self,
1446         lexer: &mut Lexer<'a>,
1447         mut context: ExpressionContext<'a, '_, '_>,
1448     ) -> Result<Handle<crate::Expression>, Error<'a>> {
1449         self.scopes.push(Scope::GeneralExpr);
1450         // logical_or_expression
1451         let handle = context.parse_binary_op(
1452             lexer,
1453             |token| match token {
1454                 Token::LogicalOperation('|') => Some(crate::BinaryOperator::LogicalOr),
1455                 _ => None,
1456             },
1457             // logical_and_expression
1458             |lexer, mut context| {
1459                 context.parse_binary_op(
1460                     lexer,
1461                     |token| match token {
1462                         Token::LogicalOperation('&') => Some(crate::BinaryOperator::LogicalAnd),
1463                         _ => None,
1464                     },
1465                     // inclusive_or_expression
1466                     |lexer, mut context| {
1467                         context.parse_binary_op(
1468                             lexer,
1469                             |token| match token {
1470                                 Token::Operation('|') => Some(crate::BinaryOperator::InclusiveOr),
1471                                 _ => None,
1472                             },
1473                             // exclusive_or_expression
1474                             |lexer, mut context| {
1475                                 context.parse_binary_op(
1476                                     lexer,
1477                                     |token| match token {
1478                                         Token::Operation('^') => {
1479                                             Some(crate::BinaryOperator::ExclusiveOr)
1480                                         }
1481                                         _ => None,
1482                                     },
1483                                     // and_expression
1484                                     |lexer, mut context| {
1485                                         context.parse_binary_op(
1486                                             lexer,
1487                                             |token| match token {
1488                                                 Token::Operation('&') => {
1489                                                     Some(crate::BinaryOperator::And)
1490                                                 }
1491                                                 _ => None,
1492                                             },
1493                                             |lexer, context| {
1494                                                 self.parse_equality_expression(lexer, context)
1495                                             },
1496                                         )
1497                                     },
1498                                 )
1499                             },
1500                         )
1501                     },
1502                 )
1503             },
1504         )?;
1505         self.scopes.pop();
1506         Ok(handle)
1507     }
1508 
parse_variable_ident_decl<'a>( &mut self, lexer: &mut Lexer<'a>, type_arena: &mut Arena<crate::Type>, const_arena: &mut Arena<crate::Constant>, ) -> Result<(&'a str, Handle<crate::Type>, crate::StorageAccess), Error<'a>>1509     fn parse_variable_ident_decl<'a>(
1510         &mut self,
1511         lexer: &mut Lexer<'a>,
1512         type_arena: &mut Arena<crate::Type>,
1513         const_arena: &mut Arena<crate::Constant>,
1514     ) -> Result<(&'a str, Handle<crate::Type>, crate::StorageAccess), Error<'a>> {
1515         let name = lexer.next_ident()?;
1516         lexer.expect(Token::Separator(':'))?;
1517         let (ty, access) = self.parse_type_decl(lexer, None, type_arena, const_arena)?;
1518         Ok((name, ty, access))
1519     }
1520 
parse_variable_decl<'a>( &mut self, lexer: &mut Lexer<'a>, type_arena: &mut Arena<crate::Type>, const_arena: &mut Arena<crate::Constant>, ) -> Result<ParsedVariable<'a>, Error<'a>>1521     fn parse_variable_decl<'a>(
1522         &mut self,
1523         lexer: &mut Lexer<'a>,
1524         type_arena: &mut Arena<crate::Type>,
1525         const_arena: &mut Arena<crate::Constant>,
1526     ) -> Result<ParsedVariable<'a>, Error<'a>> {
1527         self.scopes.push(Scope::VariableDecl);
1528         let mut class = None;
1529         if lexer.skip(Token::Paren('<')) {
1530             let class_str = lexer.next_ident()?;
1531             class = Some(conv::map_storage_class(class_str)?);
1532             lexer.expect(Token::Paren('>'))?;
1533         }
1534         let name = lexer.next_ident()?;
1535         lexer.expect(Token::Separator(':'))?;
1536         let (ty, access) = self.parse_type_decl(lexer, None, type_arena, const_arena)?;
1537 
1538         let init = if lexer.skip(Token::Operation('=')) {
1539             let handle = self.parse_const_expression(lexer, type_arena, const_arena)?;
1540             Some(handle)
1541         } else {
1542             None
1543         };
1544         lexer.expect(Token::Separator(';'))?;
1545         self.scopes.pop();
1546         Ok(ParsedVariable {
1547             name,
1548             class,
1549             ty,
1550             access,
1551             init,
1552         })
1553     }
1554 
parse_struct_body<'a>( &mut self, lexer: &mut Lexer<'a>, type_arena: &mut Arena<crate::Type>, const_arena: &mut Arena<crate::Constant>, ) -> Result<(Vec<crate::StructMember>, u32, crate::Alignment), Error<'a>>1555     fn parse_struct_body<'a>(
1556         &mut self,
1557         lexer: &mut Lexer<'a>,
1558         type_arena: &mut Arena<crate::Type>,
1559         const_arena: &mut Arena<crate::Constant>,
1560     ) -> Result<(Vec<crate::StructMember>, u32, crate::Alignment), Error<'a>> {
1561         let mut offset = 0;
1562         let mut alignment = crate::Alignment::new(1).unwrap();
1563         let mut members = Vec::new();
1564 
1565         lexer.expect(Token::Paren('{'))?;
1566         loop {
1567             let (mut size, mut align) = (None, None);
1568             let mut bind_parser = BindingParser::default();
1569             if lexer.skip(Token::DoubleParen('[')) {
1570                 self.scopes.push(Scope::Attribute);
1571                 let mut ready = true;
1572                 loop {
1573                     match lexer.next() {
1574                         (Token::DoubleParen(']'), _) => {
1575                             break;
1576                         }
1577                         (Token::Separator(','), _) if !ready => {
1578                             ready = true;
1579                         }
1580                         (Token::Word(word), _) if ready => {
1581                             match word {
1582                                 "size" => {
1583                                     lexer.expect(Token::Paren('('))?;
1584                                     let value = lexer.next_uint_literal()?;
1585                                     lexer.expect(Token::Paren(')'))?;
1586                                     size =
1587                                         Some(NonZeroU32::new(value).ok_or(Error::ZeroSizeOrAlign)?);
1588                                 }
1589                                 "align" => {
1590                                     lexer.expect(Token::Paren('('))?;
1591                                     let value = lexer.next_uint_literal()?;
1592                                     lexer.expect(Token::Paren(')'))?;
1593                                     align =
1594                                         Some(NonZeroU32::new(value).ok_or(Error::ZeroSizeOrAlign)?);
1595                                 }
1596                                 _ => bind_parser.parse(lexer, word)?,
1597                             }
1598                             ready = false;
1599                         }
1600                         other => return Err(Error::Unexpected(other, "attribute separator")),
1601                     }
1602                 }
1603                 self.scopes.pop();
1604             }
1605 
1606             let name = match lexer.next() {
1607                 (Token::Word(word), _) => word,
1608                 (Token::Paren('}'), _) => {
1609                     let span = layout::Layouter::round_up(alignment, offset);
1610                     return Ok((members, span, alignment));
1611                 }
1612                 other => return Err(Error::Unexpected(other, "field name")),
1613             };
1614             lexer.expect(Token::Separator(':'))?;
1615             let (ty, _access) = self.parse_type_decl(lexer, None, type_arena, const_arena)?;
1616             lexer.expect(Token::Separator(';'))?;
1617 
1618             self.layouter.update(type_arena, const_arena);
1619             let (range, align) = self.layouter.member_placement(offset, ty, align, size);
1620             alignment = alignment.max(align);
1621             offset = range.end;
1622 
1623             members.push(crate::StructMember {
1624                 name: Some(name.to_owned()),
1625                 ty,
1626                 binding: bind_parser.finish()?,
1627                 offset: range.start,
1628             });
1629         }
1630     }
1631 
parse_type_decl_impl<'a>( &mut self, lexer: &mut Lexer<'a>, attribute: TypeAttributes, word: &'a str, type_arena: &mut Arena<crate::Type>, const_arena: &mut Arena<crate::Constant>, ) -> Result<crate::TypeInner, Error<'a>>1632     fn parse_type_decl_impl<'a>(
1633         &mut self,
1634         lexer: &mut Lexer<'a>,
1635         attribute: TypeAttributes,
1636         word: &'a str,
1637         type_arena: &mut Arena<crate::Type>,
1638         const_arena: &mut Arena<crate::Constant>,
1639     ) -> Result<crate::TypeInner, Error<'a>> {
1640         if let Some((kind, width)) = conv::get_scalar_type(word) {
1641             return Ok(crate::TypeInner::Scalar { kind, width });
1642         }
1643         Ok(match word {
1644             "vec2" => {
1645                 let (kind, width) = lexer.next_scalar_generic()?;
1646                 crate::TypeInner::Vector {
1647                     size: crate::VectorSize::Bi,
1648                     kind,
1649                     width,
1650                 }
1651             }
1652             "vec3" => {
1653                 let (kind, width) = lexer.next_scalar_generic()?;
1654                 crate::TypeInner::Vector {
1655                     size: crate::VectorSize::Tri,
1656                     kind,
1657                     width,
1658                 }
1659             }
1660             "vec4" => {
1661                 let (kind, width) = lexer.next_scalar_generic()?;
1662                 crate::TypeInner::Vector {
1663                     size: crate::VectorSize::Quad,
1664                     kind,
1665                     width,
1666                 }
1667             }
1668             "mat2x2" => {
1669                 let (_, width) = lexer.next_scalar_generic()?;
1670                 crate::TypeInner::Matrix {
1671                     columns: crate::VectorSize::Bi,
1672                     rows: crate::VectorSize::Bi,
1673                     width,
1674                 }
1675             }
1676             "mat2x3" => {
1677                 let (_, width) = lexer.next_scalar_generic()?;
1678                 crate::TypeInner::Matrix {
1679                     columns: crate::VectorSize::Bi,
1680                     rows: crate::VectorSize::Tri,
1681                     width,
1682                 }
1683             }
1684             "mat2x4" => {
1685                 let (_, width) = lexer.next_scalar_generic()?;
1686                 crate::TypeInner::Matrix {
1687                     columns: crate::VectorSize::Bi,
1688                     rows: crate::VectorSize::Quad,
1689                     width,
1690                 }
1691             }
1692             "mat3x2" => {
1693                 let (_, width) = lexer.next_scalar_generic()?;
1694                 crate::TypeInner::Matrix {
1695                     columns: crate::VectorSize::Tri,
1696                     rows: crate::VectorSize::Bi,
1697                     width,
1698                 }
1699             }
1700             "mat3x3" => {
1701                 let (_, width) = lexer.next_scalar_generic()?;
1702                 crate::TypeInner::Matrix {
1703                     columns: crate::VectorSize::Tri,
1704                     rows: crate::VectorSize::Tri,
1705                     width,
1706                 }
1707             }
1708             "mat3x4" => {
1709                 let (_, width) = lexer.next_scalar_generic()?;
1710                 crate::TypeInner::Matrix {
1711                     columns: crate::VectorSize::Tri,
1712                     rows: crate::VectorSize::Quad,
1713                     width,
1714                 }
1715             }
1716             "mat4x2" => {
1717                 let (_, width) = lexer.next_scalar_generic()?;
1718                 crate::TypeInner::Matrix {
1719                     columns: crate::VectorSize::Quad,
1720                     rows: crate::VectorSize::Bi,
1721                     width,
1722                 }
1723             }
1724             "mat4x3" => {
1725                 let (_, width) = lexer.next_scalar_generic()?;
1726                 crate::TypeInner::Matrix {
1727                     columns: crate::VectorSize::Quad,
1728                     rows: crate::VectorSize::Tri,
1729                     width,
1730                 }
1731             }
1732             "mat4x4" => {
1733                 let (_, width) = lexer.next_scalar_generic()?;
1734                 crate::TypeInner::Matrix {
1735                     columns: crate::VectorSize::Quad,
1736                     rows: crate::VectorSize::Quad,
1737                     width,
1738                 }
1739             }
1740             "ptr" => {
1741                 lexer.expect_generic_paren('<')?;
1742                 let class = conv::map_storage_class(lexer.next_ident()?)?;
1743                 lexer.expect(Token::Separator(','))?;
1744                 let (base, _access) = self.parse_type_decl(lexer, None, type_arena, const_arena)?;
1745                 lexer.expect_generic_paren('>')?;
1746                 crate::TypeInner::Pointer { base, class }
1747             }
1748             "array" => {
1749                 lexer.expect_generic_paren('<')?;
1750                 let (base, _access) = self.parse_type_decl(lexer, None, type_arena, const_arena)?;
1751                 let size = if lexer.skip(Token::Separator(',')) {
1752                     let const_handle =
1753                         self.parse_const_expression(lexer, type_arena, const_arena)?;
1754                     crate::ArraySize::Constant(const_handle)
1755                 } else {
1756                     crate::ArraySize::Dynamic
1757                 };
1758                 lexer.expect_generic_paren('>')?;
1759                 let stride = match attribute.stride {
1760                     Some(stride) => stride.get(),
1761                     None => type_arena[base].inner.span(const_arena),
1762                 };
1763 
1764                 crate::TypeInner::Array { base, size, stride }
1765             }
1766             "sampler" => crate::TypeInner::Sampler { comparison: false },
1767             "sampler_comparison" => crate::TypeInner::Sampler { comparison: true },
1768             "texture_1d" => {
1769                 let (kind, _) = lexer.next_scalar_generic()?;
1770                 crate::TypeInner::Image {
1771                     dim: crate::ImageDimension::D1,
1772                     arrayed: false,
1773                     class: crate::ImageClass::Sampled { kind, multi: false },
1774                 }
1775             }
1776             "texture_1d_array" => {
1777                 let (kind, _) = lexer.next_scalar_generic()?;
1778                 crate::TypeInner::Image {
1779                     dim: crate::ImageDimension::D1,
1780                     arrayed: true,
1781                     class: crate::ImageClass::Sampled { kind, multi: false },
1782                 }
1783             }
1784             "texture_2d" => {
1785                 let (kind, _) = lexer.next_scalar_generic()?;
1786                 crate::TypeInner::Image {
1787                     dim: crate::ImageDimension::D2,
1788                     arrayed: false,
1789                     class: crate::ImageClass::Sampled { kind, multi: false },
1790                 }
1791             }
1792             "texture_2d_array" => {
1793                 let (kind, _) = lexer.next_scalar_generic()?;
1794                 crate::TypeInner::Image {
1795                     dim: crate::ImageDimension::D2,
1796                     arrayed: true,
1797                     class: crate::ImageClass::Sampled { kind, multi: false },
1798                 }
1799             }
1800             "texture_3d" => {
1801                 let (kind, _) = lexer.next_scalar_generic()?;
1802                 crate::TypeInner::Image {
1803                     dim: crate::ImageDimension::D3,
1804                     arrayed: false,
1805                     class: crate::ImageClass::Sampled { kind, multi: false },
1806                 }
1807             }
1808             "texture_cube" => {
1809                 let (kind, _) = lexer.next_scalar_generic()?;
1810                 crate::TypeInner::Image {
1811                     dim: crate::ImageDimension::Cube,
1812                     arrayed: false,
1813                     class: crate::ImageClass::Sampled { kind, multi: false },
1814                 }
1815             }
1816             "texture_cube_array" => {
1817                 let (kind, _) = lexer.next_scalar_generic()?;
1818                 crate::TypeInner::Image {
1819                     dim: crate::ImageDimension::Cube,
1820                     arrayed: true,
1821                     class: crate::ImageClass::Sampled { kind, multi: false },
1822                 }
1823             }
1824             "texture_multisampled_2d" => {
1825                 let (kind, _) = lexer.next_scalar_generic()?;
1826                 crate::TypeInner::Image {
1827                     dim: crate::ImageDimension::D2,
1828                     arrayed: false,
1829                     class: crate::ImageClass::Sampled { kind, multi: true },
1830                 }
1831             }
1832             "texture_multisampled_2d_array" => {
1833                 let (kind, _) = lexer.next_scalar_generic()?;
1834                 crate::TypeInner::Image {
1835                     dim: crate::ImageDimension::D2,
1836                     arrayed: true,
1837                     class: crate::ImageClass::Sampled { kind, multi: true },
1838                 }
1839             }
1840             "texture_depth_2d" => crate::TypeInner::Image {
1841                 dim: crate::ImageDimension::D2,
1842                 arrayed: false,
1843                 class: crate::ImageClass::Depth,
1844             },
1845             "texture_depth_2d_array" => crate::TypeInner::Image {
1846                 dim: crate::ImageDimension::D2,
1847                 arrayed: true,
1848                 class: crate::ImageClass::Depth,
1849             },
1850             "texture_depth_cube" => crate::TypeInner::Image {
1851                 dim: crate::ImageDimension::Cube,
1852                 arrayed: false,
1853                 class: crate::ImageClass::Depth,
1854             },
1855             "texture_depth_cube_array" => crate::TypeInner::Image {
1856                 dim: crate::ImageDimension::Cube,
1857                 arrayed: true,
1858                 class: crate::ImageClass::Depth,
1859             },
1860             "texture_storage_1d" => {
1861                 let format = lexer.next_format_generic()?;
1862                 crate::TypeInner::Image {
1863                     dim: crate::ImageDimension::D1,
1864                     arrayed: false,
1865                     class: crate::ImageClass::Storage(format),
1866                 }
1867             }
1868             "texture_storage_1d_array" => {
1869                 let format = lexer.next_format_generic()?;
1870                 crate::TypeInner::Image {
1871                     dim: crate::ImageDimension::D1,
1872                     arrayed: true,
1873                     class: crate::ImageClass::Storage(format),
1874                 }
1875             }
1876             "texture_storage_2d" => {
1877                 let format = lexer.next_format_generic()?;
1878                 crate::TypeInner::Image {
1879                     dim: crate::ImageDimension::D2,
1880                     arrayed: false,
1881                     class: crate::ImageClass::Storage(format),
1882                 }
1883             }
1884             "texture_storage_2d_array" => {
1885                 let format = lexer.next_format_generic()?;
1886                 crate::TypeInner::Image {
1887                     dim: crate::ImageDimension::D2,
1888                     arrayed: true,
1889                     class: crate::ImageClass::Storage(format),
1890                 }
1891             }
1892             "texture_storage_3d" => {
1893                 let format = lexer.next_format_generic()?;
1894                 crate::TypeInner::Image {
1895                     dim: crate::ImageDimension::D3,
1896                     arrayed: false,
1897                     class: crate::ImageClass::Storage(format),
1898                 }
1899             }
1900             _ => return Err(Error::UnknownType(word)),
1901         })
1902     }
1903 
1904     /// Parse type declaration of a given name and attribute.
parse_type_decl_name<'a>( &mut self, lexer: &mut Lexer<'a>, name: &'a str, debug_name: Option<&'a str>, attribute: TypeAttributes, type_arena: &mut Arena<crate::Type>, const_arena: &mut Arena<crate::Constant>, ) -> Result<Handle<crate::Type>, Error<'a>>1905     fn parse_type_decl_name<'a>(
1906         &mut self,
1907         lexer: &mut Lexer<'a>,
1908         name: &'a str,
1909         debug_name: Option<&'a str>,
1910         attribute: TypeAttributes,
1911         type_arena: &mut Arena<crate::Type>,
1912         const_arena: &mut Arena<crate::Constant>,
1913     ) -> Result<Handle<crate::Type>, Error<'a>> {
1914         Ok(match self.lookup_type.get(name) {
1915             Some(&handle) => handle,
1916             None => {
1917                 let inner =
1918                     self.parse_type_decl_impl(lexer, attribute, name, type_arena, const_arena)?;
1919                 type_arena.fetch_or_append(crate::Type {
1920                     name: debug_name.map(|s| s.to_string()),
1921                     inner,
1922                 })
1923             }
1924         })
1925     }
1926 
parse_type_decl<'a>( &mut self, lexer: &mut Lexer<'a>, debug_name: Option<&'a str>, type_arena: &mut Arena<crate::Type>, const_arena: &mut Arena<crate::Constant>, ) -> Result<(Handle<crate::Type>, crate::StorageAccess), Error<'a>>1927     fn parse_type_decl<'a>(
1928         &mut self,
1929         lexer: &mut Lexer<'a>,
1930         debug_name: Option<&'a str>,
1931         type_arena: &mut Arena<crate::Type>,
1932         const_arena: &mut Arena<crate::Constant>,
1933     ) -> Result<(Handle<crate::Type>, crate::StorageAccess), Error<'a>> {
1934         self.scopes.push(Scope::TypeDecl);
1935         let mut attribute = TypeAttributes::default();
1936 
1937         if lexer.skip(Token::DoubleParen('[')) {
1938             self.scopes.push(Scope::Attribute);
1939             loop {
1940                 match lexer.next() {
1941                     (Token::Word("access"), _) => {
1942                         lexer.expect(Token::Paren('('))?;
1943                         attribute.access = match lexer.next_ident()? {
1944                             "read" => crate::StorageAccess::LOAD,
1945                             "write" => crate::StorageAccess::STORE,
1946                             "read_write" => crate::StorageAccess::all(),
1947                             other => return Err(Error::UnknownAccess(other)),
1948                         };
1949                         lexer.expect(Token::Paren(')'))?;
1950                     }
1951                     (Token::Word("stride"), _) => {
1952                         lexer.expect(Token::Paren('('))?;
1953                         attribute.stride = Some(
1954                             NonZeroU32::new(lexer.next_uint_literal()?).ok_or(Error::ZeroStride)?,
1955                         );
1956                         lexer.expect(Token::Paren(')'))?;
1957                     }
1958                     (Token::DoubleParen(']'), _) => break,
1959                     other => return Err(Error::Unexpected(other, "type attribute")),
1960                 }
1961             }
1962             self.scopes.pop();
1963         }
1964 
1965         let storage_access = attribute.access;
1966         let name = lexer.next_ident()?;
1967         let handle =
1968             self.parse_type_decl_name(lexer, name, debug_name, attribute, type_arena, const_arena)?;
1969         self.scopes.pop();
1970         Ok((handle, storage_access))
1971     }
1972 
1973     /// Parse a statement that is either an assignment or a function call.
parse_statement_restricted<'a, 'out>( &mut self, lexer: &mut Lexer<'a>, ident: &'a str, mut context: ExpressionContext<'a, '_, 'out>, ) -> Result<(), Error<'a>>1974     fn parse_statement_restricted<'a, 'out>(
1975         &mut self,
1976         lexer: &mut Lexer<'a>,
1977         ident: &'a str,
1978         mut context: ExpressionContext<'a, '_, 'out>,
1979     ) -> Result<(), Error<'a>> {
1980         context.emitter.start(context.expressions);
1981         let stmt = match context.lookup_ident.get(ident) {
1982             Some(&expr) => {
1983                 let left = self.parse_postfix(lexer, context.reborrow(), expr, false)?;
1984                 lexer.expect(Token::Operation('='))?;
1985                 let value = self.parse_general_expression(lexer, context.reborrow())?;
1986                 crate::Statement::Store {
1987                     pointer: left,
1988                     value,
1989                 }
1990             }
1991             None => {
1992                 let (function, arguments) = self
1993                     .parse_local_function_call(lexer, ident, context.reborrow())?
1994                     .ok_or(Error::UnknownLocalFunction(ident))?;
1995                 crate::Statement::Call {
1996                     function,
1997                     arguments,
1998                     result: None,
1999                 }
2000             }
2001         };
2002         context
2003             .block
2004             .extend(context.emitter.finish(context.expressions));
2005         context.block.push(stmt);
2006         Ok(())
2007     }
2008 
parse_statement<'a, 'out>( &mut self, lexer: &mut Lexer<'a>, mut context: StatementContext<'a, '_, 'out>, block: &'out mut crate::Block, is_uniform_control_flow: bool, ) -> Result<(), Error<'a>>2009     fn parse_statement<'a, 'out>(
2010         &mut self,
2011         lexer: &mut Lexer<'a>,
2012         mut context: StatementContext<'a, '_, 'out>,
2013         block: &'out mut crate::Block,
2014         is_uniform_control_flow: bool,
2015     ) -> Result<(), Error<'a>> {
2016         let word = match lexer.next() {
2017             (Token::Separator(';'), _) => return Ok(()),
2018             (Token::Paren('{'), _) => {
2019                 self.scopes.push(Scope::Block);
2020                 let mut statements = Vec::new();
2021                 while !lexer.skip(Token::Paren('}')) {
2022                     self.parse_statement(
2023                         lexer,
2024                         context.reborrow(),
2025                         &mut statements,
2026                         is_uniform_control_flow,
2027                     )?;
2028                 }
2029                 self.scopes.pop();
2030                 block.push(crate::Statement::Block(statements));
2031                 return Ok(());
2032             }
2033             (Token::Word(word), _) => word,
2034             other => return Err(Error::Unexpected(other, "statement")),
2035         };
2036 
2037         self.scopes.push(Scope::Statement);
2038         let mut emitter = super::Emitter::default();
2039         match word {
2040             "let" => {
2041                 emitter.start(context.expressions);
2042                 let name = lexer.next_ident()?;
2043                 let given_ty = if lexer.skip(Token::Separator(':')) {
2044                     let (ty, _access) =
2045                         self.parse_type_decl(lexer, None, context.types, context.constants)?;
2046                     Some(ty)
2047                 } else {
2048                     None
2049                 };
2050                 lexer.expect(Token::Operation('='))?;
2051                 let expr_id = self
2052                     .parse_general_expression(lexer, context.as_expression(block, &mut emitter))?;
2053                 lexer.expect(Token::Separator(';'))?;
2054                 if let Some(ty) = given_ty {
2055                     // prepare the typifier, but work around mutable borrowing...
2056                     let _ = context
2057                         .as_expression(block, &mut emitter)
2058                         .resolve_type(expr_id)?;
2059                     let expr_inner = context.typifier.get(expr_id, context.types);
2060                     let given_inner = &context.types[ty].inner;
2061                     if given_inner != expr_inner {
2062                         log::error!(
2063                             "Given type {:?} doesn't match expected {:?}",
2064                             given_inner,
2065                             expr_inner
2066                         );
2067                         return Err(Error::LetTypeMismatch(name, ty));
2068                     }
2069                 }
2070                 block.extend(emitter.finish(context.expressions));
2071                 context.lookup_ident.insert(name, expr_id);
2072             }
2073             "var" => {
2074                 enum Init {
2075                     Empty,
2076                     Constant(Handle<crate::Constant>),
2077                     Variable(Handle<crate::Expression>),
2078                 }
2079 
2080                 let (name, ty, _access) =
2081                     self.parse_variable_ident_decl(lexer, context.types, context.constants)?;
2082 
2083                 let init = if lexer.skip(Token::Operation('=')) {
2084                     emitter.start(context.expressions);
2085                     let value = self.parse_general_expression(
2086                         lexer,
2087                         context.as_expression(block, &mut emitter),
2088                     )?;
2089                     block.extend(emitter.finish(context.expressions));
2090                     match context.expressions[value] {
2091                         crate::Expression::Constant(handle) if is_uniform_control_flow => {
2092                             Init::Constant(handle)
2093                         }
2094                         _ => Init::Variable(value),
2095                     }
2096                 } else {
2097                     Init::Empty
2098                 };
2099 
2100                 lexer.expect(Token::Separator(';'))?;
2101                 let var_id = context.variables.append(crate::LocalVariable {
2102                     name: Some(name.to_owned()),
2103                     ty,
2104                     init: match init {
2105                         Init::Constant(value) => Some(value),
2106                         _ => None,
2107                     },
2108                 });
2109 
2110                 let expr_id = context
2111                     .expressions
2112                     .append(crate::Expression::LocalVariable(var_id));
2113                 context.lookup_ident.insert(name, expr_id);
2114 
2115                 if let Init::Variable(value) = init {
2116                     block.push(crate::Statement::Store {
2117                         pointer: expr_id,
2118                         value,
2119                     });
2120                 }
2121             }
2122             "return" => {
2123                 let value = if lexer.peek().0 != Token::Separator(';') {
2124                     emitter.start(context.expressions);
2125                     let handle = self.parse_general_expression(
2126                         lexer,
2127                         context.as_expression(block, &mut emitter),
2128                     )?;
2129                     block.extend(emitter.finish(context.expressions));
2130                     Some(handle)
2131                 } else {
2132                     None
2133                 };
2134                 lexer.expect(Token::Separator(';'))?;
2135                 block.push(crate::Statement::Return { value });
2136             }
2137             "if" => {
2138                 emitter.start(context.expressions);
2139                 lexer.expect(Token::Paren('('))?;
2140                 let condition = self
2141                     .parse_general_expression(lexer, context.as_expression(block, &mut emitter))?;
2142                 lexer.expect(Token::Paren(')'))?;
2143                 block.extend(emitter.finish(context.expressions));
2144 
2145                 let accept = self.parse_block(lexer, context.reborrow(), false)?;
2146                 let mut elsif_stack = Vec::new();
2147                 while lexer.skip(Token::Word("elseif")) {
2148                     let mut sub_emitter = super::Emitter::default();
2149                     sub_emitter.start(context.expressions);
2150                     lexer.expect(Token::Paren('('))?;
2151                     let other_condition = self.parse_general_expression(
2152                         lexer,
2153                         context.as_expression(block, &mut sub_emitter),
2154                     )?;
2155                     lexer.expect(Token::Paren(')'))?;
2156                     let other_emit = sub_emitter.finish(context.expressions);
2157                     let other_block = self.parse_block(lexer, context.reborrow(), false)?;
2158                     elsif_stack.push((other_condition, other_emit, other_block));
2159                 }
2160                 let mut reject = if lexer.skip(Token::Word("else")) {
2161                     self.parse_block(lexer, context.reborrow(), false)?
2162                 } else {
2163                     Vec::new()
2164                 };
2165                 // reverse-fold the else-if blocks
2166                 //Note: we may consider uplifting this to the IR
2167                 for (other_cond, other_emit, other_block) in elsif_stack.drain(..).rev() {
2168                     reject = other_emit
2169                         .into_iter()
2170                         .chain(iter::once(crate::Statement::If {
2171                             condition: other_cond,
2172                             accept: other_block,
2173                             reject,
2174                         }))
2175                         .collect();
2176                 }
2177 
2178                 block.push(crate::Statement::If {
2179                     condition,
2180                     accept,
2181                     reject,
2182                 });
2183             }
2184             "switch" => {
2185                 emitter.start(context.expressions);
2186                 lexer.expect(Token::Paren('('))?;
2187                 let selector = self
2188                     .parse_general_expression(lexer, context.as_expression(block, &mut emitter))?;
2189                 lexer.expect(Token::Paren(')'))?;
2190                 block.extend(emitter.finish(context.expressions));
2191                 lexer.expect(Token::Paren('{'))?;
2192                 let mut cases = Vec::new();
2193                 let mut default = Vec::new();
2194 
2195                 loop {
2196                     // cases + default
2197                     match lexer.next() {
2198                         (Token::Word("case"), _) => {
2199                             // parse a list of values
2200                             let value = loop {
2201                                 let value = lexer.next_sint_literal()?;
2202                                 if lexer.skip(Token::Separator(',')) {
2203                                     if lexer.skip(Token::Separator(':')) {
2204                                         break value;
2205                                     }
2206                                 } else {
2207                                     lexer.expect(Token::Separator(':'))?;
2208                                     break value;
2209                                 }
2210                                 cases.push(crate::SwitchCase {
2211                                     value,
2212                                     body: Vec::new(),
2213                                     fall_through: true,
2214                                 });
2215                             };
2216 
2217                             let mut body = Vec::new();
2218                             lexer.expect(Token::Paren('{'))?;
2219                             let fall_through = loop {
2220                                 // default statements
2221                                 if lexer.skip(Token::Word("fallthrough")) {
2222                                     lexer.expect(Token::Separator(';'))?;
2223                                     lexer.expect(Token::Paren('}'))?;
2224                                     break true;
2225                                 }
2226                                 if lexer.skip(Token::Paren('}')) {
2227                                     break false;
2228                                 }
2229                                 self.parse_statement(lexer, context.reborrow(), &mut body, false)?;
2230                             };
2231 
2232                             cases.push(crate::SwitchCase {
2233                                 value,
2234                                 body,
2235                                 fall_through,
2236                             });
2237                         }
2238                         (Token::Word("default"), _) => {
2239                             lexer.expect(Token::Separator(':'))?;
2240                             default = self.parse_block(lexer, context.reborrow(), false)?;
2241                         }
2242                         (Token::Paren('}'), _) => break,
2243                         other => return Err(Error::Unexpected(other, "switch item")),
2244                     }
2245                 }
2246 
2247                 block.push(crate::Statement::Switch {
2248                     selector,
2249                     cases,
2250                     default,
2251                 });
2252             }
2253             "loop" => {
2254                 let mut body = Vec::new();
2255                 let mut continuing = Vec::new();
2256                 lexer.expect(Token::Paren('{'))?;
2257 
2258                 loop {
2259                     if lexer.skip(Token::Word("continuing")) {
2260                         continuing = self.parse_block(lexer, context.reborrow(), false)?;
2261                         lexer.expect(Token::Paren('}'))?;
2262                         break;
2263                     }
2264                     if lexer.skip(Token::Paren('}')) {
2265                         break;
2266                     }
2267                     self.parse_statement(lexer, context.reborrow(), &mut body, false)?;
2268                 }
2269 
2270                 block.push(crate::Statement::Loop { body, continuing });
2271             }
2272             "for" => {
2273                 lexer.expect(Token::Paren('('))?;
2274                 if !lexer.skip(Token::Separator(';')) {
2275                     let num_statements = block.len();
2276                     self.parse_statement(
2277                         lexer,
2278                         context.reborrow(),
2279                         block,
2280                         is_uniform_control_flow,
2281                     )?;
2282                     if block.len() != num_statements {
2283                         match *block.last().unwrap() {
2284                             crate::Statement::Store { .. } | crate::Statement::Call { .. } => {}
2285                             _ => return Err(Error::InvalidForInitializer),
2286                         }
2287                     }
2288                 };
2289 
2290                 let mut body = Vec::new();
2291                 if !lexer.skip(Token::Separator(';')) {
2292                     emitter.start(context.expressions);
2293                     let condition = self.parse_general_expression(
2294                         lexer,
2295                         context.as_expression(&mut body, &mut emitter),
2296                     )?;
2297                     lexer.expect(Token::Separator(';'))?;
2298                     body.extend(emitter.finish(context.expressions));
2299                     body.push(crate::Statement::If {
2300                         condition,
2301                         accept: Vec::new(),
2302                         reject: vec![crate::Statement::Break],
2303                     });
2304                 };
2305 
2306                 let mut continuing = Vec::new();
2307                 if let Token::Word(ident) = lexer.peek().0 {
2308                     // manually parse the next statement here instead of calling parse_statement
2309                     // because the statement is not terminated with a semicolon
2310                     let _ = lexer.next();
2311                     self.parse_statement_restricted(
2312                         lexer,
2313                         ident,
2314                         context.as_expression(&mut continuing, &mut emitter),
2315                     )?;
2316                 }
2317                 lexer.expect(Token::Paren(')'))?;
2318                 lexer.expect(Token::Paren('{'))?;
2319 
2320                 while !lexer.skip(Token::Paren('}')) {
2321                     self.parse_statement(lexer, context.reborrow(), &mut body, false)?;
2322                 }
2323 
2324                 block.push(crate::Statement::Loop { body, continuing });
2325             }
2326             "break" => block.push(crate::Statement::Break),
2327             "continue" => block.push(crate::Statement::Continue),
2328             "discard" => block.push(crate::Statement::Kill),
2329             "storageBarrier" => {
2330                 lexer.expect(Token::Paren('('))?;
2331                 lexer.expect(Token::Paren(')'))?;
2332                 block.push(crate::Statement::Barrier(crate::Barrier::STORAGE));
2333             }
2334             "workgroupBarrier" => {
2335                 lexer.expect(Token::Paren('('))?;
2336                 lexer.expect(Token::Paren(')'))?;
2337                 block.push(crate::Statement::Barrier(crate::Barrier::WORK_GROUP));
2338             }
2339             "textureStore" => {
2340                 emitter.start(context.expressions);
2341                 lexer.open_arguments()?;
2342                 let image_name = lexer.next_ident()?;
2343                 let image = context.lookup_ident.lookup(image_name)?;
2344                 lexer.expect(Token::Separator(','))?;
2345                 let mut expr_context = context.as_expression(block, &mut emitter);
2346                 let arrayed = match *expr_context.resolve_type(image)? {
2347                     crate::TypeInner::Image { arrayed, .. } => arrayed,
2348                     _ => return Err(Error::BadTexture(image_name)),
2349                 };
2350                 let coordinate = self.parse_general_expression(lexer, expr_context)?;
2351                 let array_index = if arrayed {
2352                     lexer.expect(Token::Separator(','))?;
2353                     Some(self.parse_general_expression(
2354                         lexer,
2355                         context.as_expression(block, &mut emitter),
2356                     )?)
2357                 } else {
2358                     None
2359                 };
2360                 lexer.expect(Token::Separator(','))?;
2361                 let value = self
2362                     .parse_general_expression(lexer, context.as_expression(block, &mut emitter))?;
2363                 lexer.close_arguments()?;
2364                 block.extend(emitter.finish(context.expressions));
2365                 block.push(crate::Statement::ImageStore {
2366                     image,
2367                     coordinate,
2368                     array_index,
2369                     value,
2370                 });
2371             }
2372             // assignment or a function call
2373             ident => {
2374                 self.parse_statement_restricted(
2375                     lexer,
2376                     ident,
2377                     context.as_expression(block, &mut emitter),
2378                 )?;
2379                 lexer.expect(Token::Separator(';'))?;
2380             }
2381         }
2382         self.scopes.pop();
2383         Ok(())
2384     }
2385 
parse_block<'a>( &mut self, lexer: &mut Lexer<'a>, mut context: StatementContext<'a, '_, '_>, is_uniform_control_flow: bool, ) -> Result<Vec<crate::Statement>, Error<'a>>2386     fn parse_block<'a>(
2387         &mut self,
2388         lexer: &mut Lexer<'a>,
2389         mut context: StatementContext<'a, '_, '_>,
2390         is_uniform_control_flow: bool,
2391     ) -> Result<Vec<crate::Statement>, Error<'a>> {
2392         self.scopes.push(Scope::Block);
2393         lexer.expect(Token::Paren('{'))?;
2394         let mut block = Vec::new();
2395         while !lexer.skip(Token::Paren('}')) {
2396             self.parse_statement(
2397                 lexer,
2398                 context.reborrow(),
2399                 &mut block,
2400                 is_uniform_control_flow,
2401             )?;
2402         }
2403         self.scopes.pop();
2404         Ok(block)
2405     }
2406 
parse_varying_binding<'a>( &mut self, lexer: &mut Lexer<'a>, ) -> Result<Option<crate::Binding>, Error<'a>>2407     fn parse_varying_binding<'a>(
2408         &mut self,
2409         lexer: &mut Lexer<'a>,
2410     ) -> Result<Option<crate::Binding>, Error<'a>> {
2411         if !lexer.skip(Token::DoubleParen('[')) {
2412             return Ok(None);
2413         }
2414 
2415         let mut bind_parser = BindingParser::default();
2416         self.scopes.push(Scope::Attribute);
2417         loop {
2418             let word = lexer.next_ident()?;
2419             bind_parser.parse(lexer, word)?;
2420             match lexer.next() {
2421                 (Token::DoubleParen(']'), _) => {
2422                     break;
2423                 }
2424                 (Token::Separator(','), _) => {}
2425                 other => return Err(Error::Unexpected(other, "attribute separator")),
2426             }
2427         }
2428         self.scopes.pop();
2429         bind_parser.finish()
2430     }
2431 
parse_function_decl<'a>( &mut self, lexer: &mut Lexer<'a>, module: &mut crate::Module, lookup_global_expression: &FastHashMap<&'a str, crate::Expression>, ) -> Result<(crate::Function, &'a str), Error<'a>>2432     fn parse_function_decl<'a>(
2433         &mut self,
2434         lexer: &mut Lexer<'a>,
2435         module: &mut crate::Module,
2436         lookup_global_expression: &FastHashMap<&'a str, crate::Expression>,
2437     ) -> Result<(crate::Function, &'a str), Error<'a>> {
2438         self.scopes.push(Scope::FunctionDecl);
2439         // read function name
2440         let mut lookup_ident = FastHashMap::default();
2441         let fun_name = lexer.next_ident()?;
2442         // populate initial expressions
2443         let mut expressions = Arena::new();
2444         for (&name, expression) in lookup_global_expression.iter() {
2445             let expr_handle = expressions.append(expression.clone());
2446             lookup_ident.insert(name, expr_handle);
2447         }
2448         // read parameter list
2449         let mut arguments = Vec::new();
2450         lexer.expect(Token::Paren('('))?;
2451         let mut ready = true;
2452         while !lexer.skip(Token::Paren(')')) {
2453             if !ready {
2454                 return Err(Error::Unexpected(lexer.next(), "comma"));
2455             }
2456             let binding = self.parse_varying_binding(lexer)?;
2457             let (param_name, param_type, _access) =
2458                 self.parse_variable_ident_decl(lexer, &mut module.types, &mut module.constants)?;
2459             let param_index = arguments.len() as u32;
2460             let expression_token =
2461                 expressions.append(crate::Expression::FunctionArgument(param_index));
2462             lookup_ident.insert(param_name, expression_token);
2463             arguments.push(crate::FunctionArgument {
2464                 name: Some(param_name.to_string()),
2465                 ty: param_type,
2466                 binding,
2467             });
2468             ready = lexer.skip(Token::Separator(','));
2469         }
2470         // read return type
2471         let result = if lexer.skip(Token::Arrow) && !lexer.skip(Token::Word("void")) {
2472             let binding = self.parse_varying_binding(lexer)?;
2473             let (ty, _access) =
2474                 self.parse_type_decl(lexer, None, &mut module.types, &mut module.constants)?;
2475             Some(crate::FunctionResult { ty, binding })
2476         } else {
2477             None
2478         };
2479 
2480         let mut fun = crate::Function {
2481             name: Some(fun_name.to_string()),
2482             arguments,
2483             result,
2484             local_variables: Arena::new(),
2485             expressions,
2486             body: Vec::new(),
2487         };
2488 
2489         // read body
2490         let mut typifier = super::Typifier::new();
2491         fun.body = self.parse_block(
2492             lexer,
2493             StatementContext {
2494                 lookup_ident: &mut lookup_ident,
2495                 typifier: &mut typifier,
2496                 variables: &mut fun.local_variables,
2497                 expressions: &mut fun.expressions,
2498                 types: &mut module.types,
2499                 constants: &mut module.constants,
2500                 global_vars: &module.global_variables,
2501                 functions: &module.functions,
2502                 arguments: &fun.arguments,
2503             },
2504             true,
2505         )?;
2506         // fixup the IR
2507         ensure_block_returns(&mut fun.body);
2508         // done
2509         self.scopes.pop();
2510 
2511         Ok((fun, fun_name))
2512     }
2513 
parse_global_decl<'a>( &mut self, lexer: &mut Lexer<'a>, module: &mut crate::Module, lookup_global_expression: &mut FastHashMap<&'a str, crate::Expression>, ) -> Result<bool, Error<'a>>2514     fn parse_global_decl<'a>(
2515         &mut self,
2516         lexer: &mut Lexer<'a>,
2517         module: &mut crate::Module,
2518         lookup_global_expression: &mut FastHashMap<&'a str, crate::Expression>,
2519     ) -> Result<bool, Error<'a>> {
2520         // read attributes
2521         let mut binding = None;
2522         // Perspective is the default qualifier.
2523         let mut stage = None;
2524         let mut is_block = false;
2525         let mut workgroup_size = [0u32; 3];
2526         let mut early_depth_test = None;
2527 
2528         if lexer.skip(Token::DoubleParen('[')) {
2529             let (mut bind_index, mut bind_group) = (None, None);
2530             self.scopes.push(Scope::Attribute);
2531             loop {
2532                 match lexer.next_ident()? {
2533                     "binding" => {
2534                         lexer.expect(Token::Paren('('))?;
2535                         bind_index = Some(lexer.next_uint_literal()?);
2536                         lexer.expect(Token::Paren(')'))?;
2537                     }
2538                     "block" => {
2539                         is_block = true;
2540                     }
2541                     "group" => {
2542                         lexer.expect(Token::Paren('('))?;
2543                         bind_group = Some(lexer.next_uint_literal()?);
2544                         lexer.expect(Token::Paren(')'))?;
2545                     }
2546                     "stage" => {
2547                         lexer.expect(Token::Paren('('))?;
2548                         stage = Some(conv::map_shader_stage(lexer.next_ident()?)?);
2549                         lexer.expect(Token::Paren(')'))?;
2550                     }
2551                     "workgroup_size" => {
2552                         lexer.expect(Token::Paren('('))?;
2553                         for (i, size) in workgroup_size.iter_mut().enumerate() {
2554                             *size = lexer.next_uint_literal()?;
2555                             match lexer.next() {
2556                                 (Token::Paren(')'), _) => break,
2557                                 (Token::Separator(','), _) if i != 2 => (),
2558                                 other => {
2559                                     return Err(Error::Unexpected(
2560                                         other,
2561                                         "workgroup size separator",
2562                                     ))
2563                                 }
2564                             }
2565                         }
2566                         for size in workgroup_size.iter_mut() {
2567                             if *size == 0 {
2568                                 *size = 1;
2569                             }
2570                         }
2571                     }
2572                     "early_depth_test" => {
2573                         let conservative = if lexer.skip(Token::Paren('(')) {
2574                             let value = conv::map_conservative_depth(lexer.next_ident()?)?;
2575                             lexer.expect(Token::Paren(')'))?;
2576                             Some(value)
2577                         } else {
2578                             None
2579                         };
2580                         early_depth_test = Some(crate::EarlyDepthTest { conservative });
2581                     }
2582                     word => return Err(Error::UnknownAttribute(word)),
2583                 }
2584                 match lexer.next() {
2585                     (Token::DoubleParen(']'), _) => {
2586                         break;
2587                     }
2588                     (Token::Separator(','), _) => {}
2589                     other => return Err(Error::Unexpected(other, "attribute separator")),
2590                 }
2591             }
2592             if let (Some(group), Some(index)) = (bind_group, bind_index) {
2593                 binding = Some(crate::ResourceBinding {
2594                     group,
2595                     binding: index,
2596                 });
2597             }
2598             self.scopes.pop();
2599         }
2600 
2601         // read items
2602         match lexer.next() {
2603             (Token::Separator(';'), _) => {}
2604             (Token::Word("struct"), _) => {
2605                 let name = lexer.next_ident()?;
2606                 let (members, span, alignment) =
2607                     self.parse_struct_body(lexer, &mut module.types, &mut module.constants)?;
2608                 let ty = module.types.fetch_or_append(crate::Type {
2609                     name: Some(name.to_string()),
2610                     inner: crate::TypeInner::Struct {
2611                         level: if is_block {
2612                             crate::StructLevel::Root
2613                         } else {
2614                             crate::StructLevel::Normal { alignment }
2615                         },
2616                         members,
2617                         span,
2618                     },
2619                 });
2620                 self.lookup_type.insert(name.to_owned(), ty);
2621                 lexer.expect(Token::Separator(';'))?;
2622             }
2623             (Token::Word("type"), _) => {
2624                 let name = lexer.next_ident()?;
2625                 lexer.expect(Token::Operation('='))?;
2626                 let (ty, _access) = self.parse_type_decl(
2627                     lexer,
2628                     Some(name),
2629                     &mut module.types,
2630                     &mut module.constants,
2631                 )?;
2632                 self.lookup_type.insert(name.to_owned(), ty);
2633                 lexer.expect(Token::Separator(';'))?;
2634             }
2635             (Token::Word("let"), _) => {
2636                 let (name, explicit_ty, _access) = self.parse_variable_ident_decl(
2637                     lexer,
2638                     &mut module.types,
2639                     &mut module.constants,
2640                 )?;
2641                 lexer.expect(Token::Operation('='))?;
2642                 let first_token_span = lexer.next();
2643                 let const_handle = self.parse_const_expression_impl(
2644                     first_token_span,
2645                     lexer,
2646                     Some(name),
2647                     &mut module.types,
2648                     &mut module.constants,
2649                 )?;
2650                 let con = &module.constants[const_handle];
2651                 let type_match = match con.inner {
2652                     crate::ConstantInner::Scalar { width, value } => {
2653                         module.types[explicit_ty].inner
2654                             == crate::TypeInner::Scalar {
2655                                 kind: value.scalar_kind(),
2656                                 width,
2657                             }
2658                     }
2659                     crate::ConstantInner::Composite { ty, components: _ } => ty == explicit_ty,
2660                 };
2661                 if !type_match {
2662                     return Err(Error::LetTypeMismatch(name, explicit_ty));
2663                 }
2664                 //TODO: check `ty` against `const_handle`.
2665                 lexer.expect(Token::Separator(';'))?;
2666                 lookup_global_expression.insert(name, crate::Expression::Constant(const_handle));
2667             }
2668             (Token::Word("var"), _) => {
2669                 let pvar =
2670                     self.parse_variable_decl(lexer, &mut module.types, &mut module.constants)?;
2671                 let class = match pvar.class {
2672                     Some(c) => c,
2673                     None => match module.types[pvar.ty].inner {
2674                         crate::TypeInner::Struct { .. } if binding.is_some() => {
2675                             if pvar.access.is_empty() {
2676                                 crate::StorageClass::Uniform
2677                             } else {
2678                                 crate::StorageClass::Storage
2679                             }
2680                         }
2681                         crate::TypeInner::Array { .. } if binding.is_some() => {
2682                             crate::StorageClass::Storage
2683                         }
2684                         crate::TypeInner::Image { .. } | crate::TypeInner::Sampler { .. } => {
2685                             crate::StorageClass::Handle
2686                         }
2687                         _ => crate::StorageClass::Private,
2688                     },
2689                 };
2690                 let var_handle = module.global_variables.append(crate::GlobalVariable {
2691                     name: Some(pvar.name.to_owned()),
2692                     class,
2693                     binding: binding.take(),
2694                     ty: pvar.ty,
2695                     init: pvar.init,
2696                     storage_access: pvar.access,
2697                 });
2698                 lookup_global_expression
2699                     .insert(pvar.name, crate::Expression::GlobalVariable(var_handle));
2700             }
2701             (Token::Word("fn"), _) => {
2702                 let (function, name) =
2703                     self.parse_function_decl(lexer, module, &lookup_global_expression)?;
2704                 match stage {
2705                     Some(stage) => module.entry_points.push(crate::EntryPoint {
2706                         name: name.to_string(),
2707                         stage,
2708                         early_depth_test,
2709                         workgroup_size,
2710                         function,
2711                     }),
2712                     None => {
2713                         module.functions.append(function);
2714                     }
2715                 }
2716             }
2717             (Token::End, _) => return Ok(false),
2718             other => return Err(Error::Unexpected(other, "global item")),
2719         }
2720 
2721         match binding {
2722             None => Ok(true),
2723             // we had the attribute but no var?
2724             Some(_) => Err(Error::Other),
2725         }
2726     }
2727 
parse(&mut self, source: &str) -> Result<crate::Module, ParseError>2728     pub fn parse(&mut self, source: &str) -> Result<crate::Module, ParseError> {
2729         self.scopes.clear();
2730         self.lookup_type.clear();
2731         self.layouter.clear();
2732 
2733         let mut module = crate::Module::default();
2734         let mut lexer = Lexer::new(source);
2735         let mut lookup_global_expression = FastHashMap::default();
2736         loop {
2737             match self.parse_global_decl(&mut lexer, &mut module, &mut lookup_global_expression) {
2738                 Err(error) => return Err(error.as_parse_error(lexer.source)),
2739                 Ok(true) => {}
2740                 Ok(false) => {
2741                     if !self.scopes.is_empty() {
2742                         log::error!("Reached the end of file, but scopes are not closed");
2743                         return Err(Error::Other.as_parse_error(lexer.source));
2744                     };
2745                     module.apply_common_default_interpolation();
2746                     return Ok(module);
2747                 }
2748             }
2749         }
2750     }
2751 }
2752 
parse_str(source: &str) -> Result<crate::Module, ParseError>2753 pub fn parse_str(source: &str) -> Result<crate::Module, ParseError> {
2754     Parser::new().parse(source)
2755 }
2756 
2757 pub struct StringErrorBuffer {
2758     buf: Vec<u8>,
2759 }
2760 
2761 impl StringErrorBuffer {
new() -> Self2762     pub fn new() -> Self {
2763         Self { buf: Vec::new() }
2764     }
2765 
into_string(self) -> String2766     pub fn into_string(self) -> String {
2767         String::from_utf8(self.buf).unwrap()
2768     }
2769 }
2770 
2771 impl Write for StringErrorBuffer {
write(&mut self, buf: &[u8]) -> io::Result<usize>2772     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
2773         self.buf.extend(buf);
2774         Ok(buf.len())
2775     }
2776 
flush(&mut self) -> io::Result<()>2777     fn flush(&mut self) -> io::Result<()> {
2778         Ok(())
2779     }
2780 }
2781 
2782 impl WriteColor for StringErrorBuffer {
supports_color(&self) -> bool2783     fn supports_color(&self) -> bool {
2784         false
2785     }
2786 
set_color(&mut self, _spec: &ColorSpec) -> io::Result<()>2787     fn set_color(&mut self, _spec: &ColorSpec) -> io::Result<()> {
2788         Ok(())
2789     }
2790 
reset(&mut self) -> io::Result<()>2791     fn reset(&mut self) -> io::Result<()> {
2792         Ok(())
2793     }
2794 }
2795