1 use crate::parsers::*;
2 use crate::syntax;
3 
4 #[test]
parse_uniline_comment()5 fn parse_uniline_comment() {
6   assert_eq!(comment("// lol"), Ok(("", " lol")));
7   assert_eq!(comment("// lol\nfoo"), Ok(("foo", " lol")));
8   assert_eq!(comment("// lol\\\nfoo"), Ok(("", " lol\\\nfoo")));
9   assert_eq!(
10     comment("// lol   \\\n   foo\n"),
11     Ok(("", " lol   \\\n   foo"))
12   );
13 }
14 
15 #[test]
parse_multiline_comment()16 fn parse_multiline_comment() {
17   assert_eq!(comment("/* lol\nfoo\n*/bar"), Ok(("bar", " lol\nfoo\n")));
18 }
19 
20 #[test]
parse_unsigned_suffix()21 fn parse_unsigned_suffix() {
22   assert_eq!(unsigned_suffix("u"), Ok(("", 'u')));
23   assert_eq!(unsigned_suffix("U"), Ok(("", 'U')));
24 }
25 
26 #[test]
parse_nonzero_digits()27 fn parse_nonzero_digits() {
28   assert_eq!(nonzero_digits("3"), Ok(("", "3")));
29   assert_eq!(nonzero_digits("12345953"), Ok(("", "12345953")));
30 }
31 
32 #[test]
parse_decimal_lit()33 fn parse_decimal_lit() {
34   assert_eq!(decimal_lit("3"), Ok(("", Ok(3))));
35   assert_eq!(decimal_lit("3"), Ok(("", Ok(3))));
36   assert_eq!(decimal_lit("13"), Ok(("", Ok(13))));
37   assert_eq!(decimal_lit("42"), Ok(("", Ok(42))));
38   assert_eq!(decimal_lit("123456"), Ok(("", Ok(123456))));
39 }
40 
41 #[test]
parse_octal_lit()42 fn parse_octal_lit() {
43   assert_eq!(octal_lit("0"), Ok(("", Ok(0o0))));
44   assert_eq!(octal_lit("03 "), Ok((" ", Ok(0o3))));
45   assert_eq!(octal_lit("012 "), Ok((" ", Ok(0o12))));
46   assert_eq!(octal_lit("07654321 "), Ok((" ", Ok(0o7654321))));
47 }
48 
49 #[test]
parse_hexadecimal_lit()50 fn parse_hexadecimal_lit() {
51   assert_eq!(hexadecimal_lit("0x3 "), Ok((" ", Ok(0x3))));
52   assert_eq!(hexadecimal_lit("0x0123789"), Ok(("", Ok(0x0123789))));
53   assert_eq!(hexadecimal_lit("0xABCDEF"), Ok(("", Ok(0xabcdef))));
54   assert_eq!(hexadecimal_lit("0xabcdef"), Ok(("", Ok(0xabcdef))));
55 }
56 
57 #[test]
parse_integral_lit()58 fn parse_integral_lit() {
59   assert_eq!(integral_lit("0"), Ok(("", 0)));
60   assert_eq!(integral_lit("3"), Ok(("", 3)));
61   assert_eq!(integral_lit("3 "), Ok((" ", 3)));
62   assert_eq!(integral_lit("03 "), Ok((" ", 3)));
63   assert_eq!(integral_lit("076556 "), Ok((" ", 0o76556)));
64   assert_eq!(integral_lit("012 "), Ok((" ", 0o12)));
65   assert_eq!(integral_lit("0x3 "), Ok((" ", 0x3)));
66   assert_eq!(integral_lit("0x9ABCDEF"), Ok(("", 0x9ABCDEF)));
67   assert_eq!(integral_lit("0x9ABCDEF"), Ok(("", 0x9ABCDEF)));
68   assert_eq!(integral_lit("0x9abcdef"), Ok(("", 0x9abcdef)));
69   assert_eq!(integral_lit("0x9abcdef"), Ok(("", 0x9abcdef)));
70   assert_eq!(integral_lit("0xffffffff"), Ok(("", 0xffffffffu32 as i32)));
71 }
72 
73 #[test]
parse_integral_neg_lit()74 fn parse_integral_neg_lit() {
75   assert_eq!(integral_lit("-3"), Ok(("", -3)));
76   assert_eq!(integral_lit("-3 "), Ok((" ", -3)));
77   assert_eq!(integral_lit("-03 "), Ok((" ", -3)));
78   assert_eq!(integral_lit("-076556 "), Ok((" ", -0o76556)));
79   assert_eq!(integral_lit("-012 "), Ok((" ", -0o12)));
80   assert_eq!(integral_lit("-0x3 "), Ok((" ", -0x3)));
81   assert_eq!(integral_lit("-0x9ABCDEF"), Ok(("", -0x9ABCDEF)));
82   assert_eq!(integral_lit("-0x9ABCDEF"), Ok(("", -0x9ABCDEF)));
83   assert_eq!(integral_lit("-0x9abcdef"), Ok(("", -0x9abcdef)));
84   assert_eq!(integral_lit("-0x9abcdef"), Ok(("", -0x9abcdef)));
85 }
86 
87 #[test]
parse_unsigned_lit()88 fn parse_unsigned_lit() {
89   assert_eq!(unsigned_lit("0xffffffffU"), Ok(("", 0xffffffff as u32)));
90   assert_eq!(unsigned_lit("-1u"), Ok(("", 0xffffffff as u32)));
91   assert!(unsigned_lit("0xfffffffffU").is_err());
92 }
93 
94 #[test]
parse_float_lit()95 fn parse_float_lit() {
96   assert_eq!(float_lit("0.;"), Ok((";", 0.)));
97   assert_eq!(float_lit(".0;"), Ok((";", 0.)));
98   assert_eq!(float_lit(".035 "), Ok((" ", 0.035)));
99   assert_eq!(float_lit("0. "), Ok((" ", 0.)));
100   assert_eq!(float_lit("0.035 "), Ok((" ", 0.035)));
101   assert_eq!(float_lit(".035f"), Ok(("", 0.035)));
102   assert_eq!(float_lit("0.f"), Ok(("", 0.)));
103   assert_eq!(float_lit("314.f"), Ok(("", 314.)));
104   assert_eq!(float_lit("0.035f"), Ok(("", 0.035)));
105   assert_eq!(float_lit(".035F"), Ok(("", 0.035)));
106   assert_eq!(float_lit("0.F"), Ok(("", 0.)));
107   assert_eq!(float_lit("0.035F"), Ok(("", 0.035)));
108   assert_eq!(float_lit("1.03e+34 "), Ok((" ", 1.03e+34)));
109   assert_eq!(float_lit("1.03E+34 "), Ok((" ", 1.03E+34)));
110   assert_eq!(float_lit("1.03e-34 "), Ok((" ", 1.03e-34)));
111   assert_eq!(float_lit("1.03E-34 "), Ok((" ", 1.03E-34)));
112   assert_eq!(float_lit("1.03e+34f"), Ok(("", 1.03e+34)));
113   assert_eq!(float_lit("1.03E+34f"), Ok(("", 1.03E+34)));
114   assert_eq!(float_lit("1.03e-34f"), Ok(("", 1.03e-34)));
115   assert_eq!(float_lit("1.03E-34f"), Ok(("", 1.03E-34)));
116   assert_eq!(float_lit("1.03e+34F"), Ok(("", 1.03e+34)));
117   assert_eq!(float_lit("1.03E+34F"), Ok(("", 1.03E+34)));
118   assert_eq!(float_lit("1.03e-34F"), Ok(("", 1.03e-34)));
119   assert_eq!(float_lit("1.03E-34F"), Ok(("", 1.03E-34)));
120 }
121 
122 #[test]
parse_float_neg_lit()123 fn parse_float_neg_lit() {
124   assert_eq!(float_lit("-.035 "), Ok((" ", -0.035)));
125   assert_eq!(float_lit("-0. "), Ok((" ", -0.)));
126   assert_eq!(float_lit("-0.035 "), Ok((" ", -0.035)));
127   assert_eq!(float_lit("-.035f"), Ok(("", -0.035)));
128   assert_eq!(float_lit("-0.f"), Ok(("", -0.)));
129   assert_eq!(float_lit("-0.035f"), Ok(("", -0.035)));
130   assert_eq!(float_lit("-.035F"), Ok(("", -0.035)));
131   assert_eq!(float_lit("-0.F"), Ok(("", -0.)));
132   assert_eq!(float_lit("-0.035F"), Ok(("", -0.035)));
133   assert_eq!(float_lit("-1.03e+34 "), Ok((" ", -1.03e+34)));
134   assert_eq!(float_lit("-1.03E+34 "), Ok((" ", -1.03E+34)));
135   assert_eq!(float_lit("-1.03e-34 "), Ok((" ", -1.03e-34)));
136   assert_eq!(float_lit("-1.03E-34 "), Ok((" ", -1.03E-34)));
137   assert_eq!(float_lit("-1.03e+34f"), Ok(("", -1.03e+34)));
138   assert_eq!(float_lit("-1.03E+34f"), Ok(("", -1.03E+34)));
139   assert_eq!(float_lit("-1.03e-34f"), Ok(("", -1.03e-34)));
140   assert_eq!(float_lit("-1.03E-34f"), Ok(("", -1.03E-34)));
141   assert_eq!(float_lit("-1.03e+34F"), Ok(("", -1.03e+34)));
142   assert_eq!(float_lit("-1.03E+34F"), Ok(("", -1.03E+34)));
143   assert_eq!(float_lit("-1.03e-34F"), Ok(("", -1.03e-34)));
144   assert_eq!(float_lit("-1.03E-34F"), Ok(("", -1.03E-34)));
145 }
146 
147 #[test]
parse_double_lit()148 fn parse_double_lit() {
149   assert_eq!(double_lit("0.;"), Ok((";", 0.)));
150   assert_eq!(double_lit(".0;"), Ok((";", 0.)));
151   assert_eq!(double_lit(".035 "), Ok((" ", 0.035)));
152   assert_eq!(double_lit("0. "), Ok((" ", 0.)));
153   assert_eq!(double_lit("0.035 "), Ok((" ", 0.035)));
154   assert_eq!(double_lit("0.lf"), Ok(("", 0.)));
155   assert_eq!(double_lit("0.035lf"), Ok(("", 0.035)));
156   assert_eq!(double_lit(".035lf"), Ok(("", 0.035)));
157   assert_eq!(double_lit(".035LF"), Ok(("", 0.035)));
158   assert_eq!(double_lit("0.LF"), Ok(("", 0.)));
159   assert_eq!(double_lit("0.035LF"), Ok(("", 0.035)));
160   assert_eq!(double_lit("1.03e+34lf"), Ok(("", 1.03e+34)));
161   assert_eq!(double_lit("1.03E+34lf"), Ok(("", 1.03E+34)));
162   assert_eq!(double_lit("1.03e-34lf"), Ok(("", 1.03e-34)));
163   assert_eq!(double_lit("1.03E-34lf"), Ok(("", 1.03E-34)));
164   assert_eq!(double_lit("1.03e+34LF"), Ok(("", 1.03e+34)));
165   assert_eq!(double_lit("1.03E+34LF"), Ok(("", 1.03E+34)));
166   assert_eq!(double_lit("1.03e-34LF"), Ok(("", 1.03e-34)));
167   assert_eq!(double_lit("1.03E-34LF"), Ok(("", 1.03E-34)));
168 }
169 
170 #[test]
parse_double_neg_lit()171 fn parse_double_neg_lit() {
172   assert_eq!(double_lit("-0.;"), Ok((";", -0.)));
173   assert_eq!(double_lit("-.0;"), Ok((";", -0.)));
174   assert_eq!(double_lit("-.035 "), Ok((" ", -0.035)));
175   assert_eq!(double_lit("-0. "), Ok((" ", -0.)));
176   assert_eq!(double_lit("-0.035 "), Ok((" ", -0.035)));
177   assert_eq!(double_lit("-0.lf"), Ok(("", -0.)));
178   assert_eq!(double_lit("-0.035lf"), Ok(("", -0.035)));
179   assert_eq!(double_lit("-.035lf"), Ok(("", -0.035)));
180   assert_eq!(double_lit("-.035LF"), Ok(("", -0.035)));
181   assert_eq!(double_lit("-0.LF"), Ok(("", -0.)));
182   assert_eq!(double_lit("-0.035LF"), Ok(("", -0.035)));
183   assert_eq!(double_lit("-1.03e+34lf"), Ok(("", -1.03e+34)));
184   assert_eq!(double_lit("-1.03E+34lf"), Ok(("", -1.03E+34)));
185   assert_eq!(double_lit("-1.03e-34lf"), Ok(("", -1.03e-34)));
186   assert_eq!(double_lit("-1.03E-34lf"), Ok(("", -1.03E-34)));
187   assert_eq!(double_lit("-1.03e+34LF"), Ok(("", -1.03e+34)));
188   assert_eq!(double_lit("-1.03E+34LF"), Ok(("", -1.03E+34)));
189   assert_eq!(double_lit("-1.03e-34LF"), Ok(("", -1.03e-34)));
190   assert_eq!(double_lit("-1.03E-34LF"), Ok(("", -1.03E-34)));
191 }
192 
193 #[test]
parse_bool_lit()194 fn parse_bool_lit() {
195   assert_eq!(bool_lit("false"), Ok(("", false)));
196   assert_eq!(bool_lit("true"), Ok(("", true)));
197 }
198 
199 #[test]
parse_identifier()200 fn parse_identifier() {
201   assert_eq!(identifier("a"), Ok(("", "a".into())));
202   assert_eq!(identifier("ab_cd"), Ok(("", "ab_cd".into())));
203   assert_eq!(identifier("Ab_cd"), Ok(("", "Ab_cd".into())));
204   assert_eq!(identifier("Ab_c8d"), Ok(("", "Ab_c8d".into())));
205   assert_eq!(identifier("Ab_c8d9"), Ok(("", "Ab_c8d9".into())));
206 }
207 
208 #[test]
parse_unary_op_add()209 fn parse_unary_op_add() {
210   assert_eq!(unary_op("+ "), Ok((" ", syntax::UnaryOp::Add)));
211 }
212 
213 #[test]
parse_unary_op_minus()214 fn parse_unary_op_minus() {
215   assert_eq!(unary_op("- "), Ok((" ", syntax::UnaryOp::Minus)));
216 }
217 
218 #[test]
parse_unary_op_not()219 fn parse_unary_op_not() {
220   assert_eq!(unary_op("!"), Ok(("", syntax::UnaryOp::Not)));
221 }
222 
223 #[test]
parse_unary_op_complement()224 fn parse_unary_op_complement() {
225   assert_eq!(unary_op("~"), Ok(("", syntax::UnaryOp::Complement)));
226 }
227 
228 #[test]
parse_unary_op_inc()229 fn parse_unary_op_inc() {
230   assert_eq!(unary_op("++"), Ok(("", syntax::UnaryOp::Inc)));
231 }
232 
233 #[test]
parse_unary_op_dec()234 fn parse_unary_op_dec() {
235   assert_eq!(unary_op("--"), Ok(("", syntax::UnaryOp::Dec)));
236 }
237 
238 #[test]
parse_array_specifier_unsized()239 fn parse_array_specifier_unsized() {
240   assert_eq!(
241     array_specifier("[]"),
242     Ok(("", syntax::ArraySpecifier::Unsized))
243   );
244   assert_eq!(
245     array_specifier("[ ]"),
246     Ok(("", syntax::ArraySpecifier::Unsized))
247   );
248   assert_eq!(
249     array_specifier("[\n]"),
250     Ok(("", syntax::ArraySpecifier::Unsized))
251   );
252 }
253 
254 #[test]
parse_array_specifier_sized()255 fn parse_array_specifier_sized() {
256   let ix = syntax::Expr::IntConst(0);
257 
258   assert_eq!(
259     array_specifier("[0]"),
260     Ok((
261       "",
262       syntax::ArraySpecifier::ExplicitlySized(Box::new(ix.clone()))
263     ))
264   );
265   assert_eq!(
266     array_specifier("[\n0   \t]"),
267     Ok(("", syntax::ArraySpecifier::ExplicitlySized(Box::new(ix))))
268   );
269 }
270 
271 #[test]
parse_precise_qualifier()272 fn parse_precise_qualifier() {
273   assert_eq!(precise_qualifier("precise "), Ok((" ", ())));
274 }
275 
276 #[test]
parse_invariant_qualifier()277 fn parse_invariant_qualifier() {
278   assert_eq!(invariant_qualifier("invariant "), Ok((" ", ())));
279 }
280 
281 #[test]
parse_interpolation_qualifier()282 fn parse_interpolation_qualifier() {
283   assert_eq!(
284     interpolation_qualifier("smooth "),
285     Ok((" ", syntax::InterpolationQualifier::Smooth))
286   );
287   assert_eq!(
288     interpolation_qualifier("flat "),
289     Ok((" ", syntax::InterpolationQualifier::Flat))
290   );
291   assert_eq!(
292     interpolation_qualifier("noperspective "),
293     Ok((" ", syntax::InterpolationQualifier::NoPerspective))
294   );
295 }
296 
297 #[test]
parse_precision_qualifier()298 fn parse_precision_qualifier() {
299   assert_eq!(
300     precision_qualifier("highp "),
301     Ok((" ", syntax::PrecisionQualifier::High))
302   );
303   assert_eq!(
304     precision_qualifier("mediump "),
305     Ok((" ", syntax::PrecisionQualifier::Medium))
306   );
307   assert_eq!(
308     precision_qualifier("lowp "),
309     Ok((" ", syntax::PrecisionQualifier::Low))
310   );
311 }
312 
313 #[test]
parse_storage_qualifier()314 fn parse_storage_qualifier() {
315   assert_eq!(
316     storage_qualifier("const "),
317     Ok((" ", syntax::StorageQualifier::Const))
318   );
319   assert_eq!(
320     storage_qualifier("inout "),
321     Ok((" ", syntax::StorageQualifier::InOut))
322   );
323   assert_eq!(
324     storage_qualifier("in "),
325     Ok((" ", syntax::StorageQualifier::In))
326   );
327   assert_eq!(
328     storage_qualifier("out "),
329     Ok((" ", syntax::StorageQualifier::Out))
330   );
331   assert_eq!(
332     storage_qualifier("centroid "),
333     Ok((" ", syntax::StorageQualifier::Centroid))
334   );
335   assert_eq!(
336     storage_qualifier("patch "),
337     Ok((" ", syntax::StorageQualifier::Patch))
338   );
339   assert_eq!(
340     storage_qualifier("sample "),
341     Ok((" ", syntax::StorageQualifier::Sample))
342   );
343   assert_eq!(
344     storage_qualifier("uniform "),
345     Ok((" ", syntax::StorageQualifier::Uniform))
346   );
347   assert_eq!(
348     storage_qualifier("attribute "),
349     Ok((" ", syntax::StorageQualifier::Attribute))
350   );
351   assert_eq!(
352     storage_qualifier("varying "),
353     Ok((" ", syntax::StorageQualifier::Varying))
354   );
355   assert_eq!(
356     storage_qualifier("buffer "),
357     Ok((" ", syntax::StorageQualifier::Buffer))
358   );
359   assert_eq!(
360     storage_qualifier("shared "),
361     Ok((" ", syntax::StorageQualifier::Shared))
362   );
363   assert_eq!(
364     storage_qualifier("coherent "),
365     Ok((" ", syntax::StorageQualifier::Coherent))
366   );
367   assert_eq!(
368     storage_qualifier("volatile "),
369     Ok((" ", syntax::StorageQualifier::Volatile))
370   );
371   assert_eq!(
372     storage_qualifier("restrict "),
373     Ok((" ", syntax::StorageQualifier::Restrict))
374   );
375   assert_eq!(
376     storage_qualifier("readonly "),
377     Ok((" ", syntax::StorageQualifier::ReadOnly))
378   );
379   assert_eq!(
380     storage_qualifier("writeonly "),
381     Ok((" ", syntax::StorageQualifier::WriteOnly))
382   );
383   assert_eq!(
384     storage_qualifier("subroutine a"),
385     Ok((" a", syntax::StorageQualifier::Subroutine(vec![])))
386   );
387 
388   let a = syntax::TypeName("vec3".to_owned());
389   let b = syntax::TypeName("float".to_owned());
390   let c = syntax::TypeName("dmat43".to_owned());
391   let types = vec![a, b, c];
392   assert_eq!(
393     storage_qualifier("subroutine (  vec3 , float \\\n, dmat43)"),
394     Ok(("", syntax::StorageQualifier::Subroutine(types)))
395   );
396 }
397 
398 #[test]
parse_layout_qualifier_std430()399 fn parse_layout_qualifier_std430() {
400   let expected = syntax::LayoutQualifier {
401     ids: syntax::NonEmpty(vec![syntax::LayoutQualifierSpec::Identifier(
402       "std430".into(),
403       None,
404     )]),
405   };
406 
407   assert_eq!(
408     layout_qualifier("layout (std430)"),
409     Ok(("", expected.clone()))
410   );
411   assert_eq!(
412     layout_qualifier("layout  (std430   )"),
413     Ok(("", expected.clone()))
414   );
415   assert_eq!(
416     layout_qualifier("layout \n\t (  std430  )"),
417     Ok(("", expected.clone()))
418   );
419   assert_eq!(layout_qualifier("layout(std430)"), Ok(("", expected)));
420 }
421 
422 #[test]
parse_layout_qualifier_shared()423 fn parse_layout_qualifier_shared() {
424   let expected = syntax::LayoutQualifier {
425     ids: syntax::NonEmpty(vec![syntax::LayoutQualifierSpec::Shared]),
426   };
427 
428   assert_eq!(
429     layout_qualifier("layout (shared)"),
430     Ok(("", expected.clone()))
431   );
432   assert_eq!(
433     layout_qualifier("layout ( shared )"),
434     Ok(("", expected.clone()))
435   );
436   assert_eq!(layout_qualifier("layout(shared)"), Ok(("", expected)));
437 }
438 
439 #[test]
parse_layout_qualifier_list()440 fn parse_layout_qualifier_list() {
441   let id_0 = syntax::LayoutQualifierSpec::Shared;
442   let id_1 = syntax::LayoutQualifierSpec::Identifier("std140".into(), None);
443   let id_2 = syntax::LayoutQualifierSpec::Identifier(
444     "max_vertices".into(),
445     Some(Box::new(syntax::Expr::IntConst(3))),
446   );
447   let expected = syntax::LayoutQualifier {
448     ids: syntax::NonEmpty(vec![id_0, id_1, id_2]),
449   };
450 
451   assert_eq!(
452     layout_qualifier("layout (shared, std140, max_vertices = 3)"),
453     Ok(("", expected.clone()))
454   );
455   assert_eq!(
456     layout_qualifier("layout(shared,std140,max_vertices=3)"),
457     Ok(("", expected.clone()))
458   );
459   assert_eq!(
460     layout_qualifier("layout\n\n\t (    shared , std140, max_vertices= 3)"),
461     Ok(("", expected.clone()))
462   );
463 }
464 
465 #[test]
parse_type_qualifier()466 fn parse_type_qualifier() {
467   let storage_qual = syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Const);
468   let id_0 = syntax::LayoutQualifierSpec::Shared;
469   let id_1 = syntax::LayoutQualifierSpec::Identifier("std140".into(), None);
470   let id_2 = syntax::LayoutQualifierSpec::Identifier(
471     "max_vertices".into(),
472     Some(Box::new(syntax::Expr::IntConst(3))),
473   );
474   let layout_qual = syntax::TypeQualifierSpec::Layout(syntax::LayoutQualifier {
475     ids: syntax::NonEmpty(vec![id_0, id_1, id_2]),
476   });
477   let expected = syntax::TypeQualifier {
478     qualifiers: syntax::NonEmpty(vec![storage_qual, layout_qual]),
479   };
480 
481   assert_eq!(
482     type_qualifier("const layout (shared, std140, max_vertices = 3)"),
483     Ok(("", expected.clone()))
484   );
485   assert_eq!(
486     type_qualifier("const layout(shared,std140,max_vertices=3)"),
487     Ok(("", expected))
488   );
489 }
490 
491 #[test]
parse_struct_field_specifier()492 fn parse_struct_field_specifier() {
493   let expected = syntax::StructFieldSpecifier {
494     qualifier: None,
495     ty: syntax::TypeSpecifier {
496       ty: syntax::TypeSpecifierNonArray::Vec4,
497       array_specifier: None,
498     },
499     identifiers: syntax::NonEmpty(vec!["foo".into()]),
500   };
501 
502   assert_eq!(
503     struct_field_specifier("vec4 foo;"),
504     Ok(("", expected.clone()))
505   );
506   assert_eq!(
507     struct_field_specifier("vec4     foo ; "),
508     Ok((" ", expected.clone()))
509   );
510 }
511 
512 #[test]
parse_struct_field_specifier_type_name()513 fn parse_struct_field_specifier_type_name() {
514   let expected = syntax::StructFieldSpecifier {
515     qualifier: None,
516     ty: syntax::TypeSpecifier {
517       ty: syntax::TypeSpecifierNonArray::TypeName("S0238_3".into()),
518       array_specifier: None,
519     },
520     identifiers: syntax::NonEmpty(vec!["x".into()]),
521   };
522 
523   assert_eq!(
524     struct_field_specifier("S0238_3 x;"),
525     Ok(("", expected.clone()))
526   );
527   assert_eq!(
528     struct_field_specifier("S0238_3     x ;"),
529     Ok(("", expected.clone()))
530   );
531 }
532 
533 #[test]
parse_struct_field_specifier_several()534 fn parse_struct_field_specifier_several() {
535   let expected = syntax::StructFieldSpecifier {
536     qualifier: None,
537     ty: syntax::TypeSpecifier {
538       ty: syntax::TypeSpecifierNonArray::Vec4,
539       array_specifier: None,
540     },
541     identifiers: syntax::NonEmpty(vec!["foo".into(), "bar".into(), "zoo".into()]),
542   };
543 
544   assert_eq!(
545     struct_field_specifier("vec4 foo, bar, zoo;"),
546     Ok(("", expected.clone()))
547   );
548   assert_eq!(
549     struct_field_specifier("vec4     foo , bar  , zoo ;"),
550     Ok(("", expected.clone()))
551   );
552 }
553 
554 #[test]
parse_struct_specifier_one_field()555 fn parse_struct_specifier_one_field() {
556   let field = syntax::StructFieldSpecifier {
557     qualifier: None,
558     ty: syntax::TypeSpecifier {
559       ty: syntax::TypeSpecifierNonArray::Vec4,
560       array_specifier: None,
561     },
562     identifiers: syntax::NonEmpty(vec!["foo".into()]),
563   };
564   let expected = syntax::StructSpecifier {
565     name: Some("TestStruct".into()),
566     fields: syntax::NonEmpty(vec![field]),
567   };
568 
569   assert_eq!(
570     struct_specifier("struct TestStruct { vec4 foo; }"),
571     Ok(("", expected.clone()))
572   );
573   assert_eq!(
574     struct_specifier("struct      TestStruct \n \n\n {\n    vec4   foo  ;}"),
575     Ok(("", expected))
576   );
577 }
578 
579 #[test]
parse_struct_specifier_multi_fields()580 fn parse_struct_specifier_multi_fields() {
581   let a = syntax::StructFieldSpecifier {
582     qualifier: None,
583     ty: syntax::TypeSpecifier {
584       ty: syntax::TypeSpecifierNonArray::Vec4,
585       array_specifier: None,
586     },
587     identifiers: syntax::NonEmpty(vec!["foo".into()]),
588   };
589   let b = syntax::StructFieldSpecifier {
590     qualifier: None,
591     ty: syntax::TypeSpecifier {
592       ty: syntax::TypeSpecifierNonArray::Float,
593       array_specifier: None,
594     },
595     identifiers: syntax::NonEmpty(vec!["bar".into()]),
596   };
597   let c = syntax::StructFieldSpecifier {
598     qualifier: None,
599     ty: syntax::TypeSpecifier {
600       ty: syntax::TypeSpecifierNonArray::UInt,
601       array_specifier: None,
602     },
603     identifiers: syntax::NonEmpty(vec!["zoo".into()]),
604   };
605   let d = syntax::StructFieldSpecifier {
606     qualifier: None,
607     ty: syntax::TypeSpecifier {
608       ty: syntax::TypeSpecifierNonArray::BVec3,
609       array_specifier: None,
610     },
611     identifiers: syntax::NonEmpty(vec!["foo_BAR_zoo3497_34".into()]),
612   };
613   let e = syntax::StructFieldSpecifier {
614     qualifier: None,
615     ty: syntax::TypeSpecifier {
616       ty: syntax::TypeSpecifierNonArray::TypeName("S0238_3".into()),
617       array_specifier: None,
618     },
619     identifiers: syntax::NonEmpty(vec!["x".into()]),
620   };
621   let expected = syntax::StructSpecifier {
622     name: Some("_TestStruct_934i".into()),
623     fields: syntax::NonEmpty(vec![a, b, c, d, e]),
624   };
625 
626   assert_eq!(
627     struct_specifier(
628       "struct _TestStruct_934i { vec4 foo; float bar; uint zoo; bvec3 foo_BAR_zoo3497_34; S0238_3 x; }"
629     ),
630     Ok(("", expected.clone()))
631   );
632   assert_eq!(
633     struct_specifier(
634       "struct _TestStruct_934i{vec4 foo;float bar;uint zoo;bvec3 foo_BAR_zoo3497_34;S0238_3 x;}"
635     ),
636     Ok(("", expected.clone()))
637   );
638   assert_eq!(struct_specifier("struct _TestStruct_934i\n   {  vec4\nfoo ;   \n\t float\n\t\t  bar  ;   \nuint   zoo;    \n bvec3   foo_BAR_zoo3497_34\n\n\t\n\t\n  ; S0238_3 x;}"), Ok(("", expected)));
639 }
640 
641 #[test]
parse_type_specifier_non_array()642 fn parse_type_specifier_non_array() {
643   assert_eq!(
644     type_specifier_non_array("bool"),
645     Ok(("", syntax::TypeSpecifierNonArray::Bool))
646   );
647   assert_eq!(
648     type_specifier_non_array("int"),
649     Ok(("", syntax::TypeSpecifierNonArray::Int))
650   );
651   assert_eq!(
652     type_specifier_non_array("uint"),
653     Ok(("", syntax::TypeSpecifierNonArray::UInt))
654   );
655   assert_eq!(
656     type_specifier_non_array("float"),
657     Ok(("", syntax::TypeSpecifierNonArray::Float))
658   );
659   assert_eq!(
660     type_specifier_non_array("double"),
661     Ok(("", syntax::TypeSpecifierNonArray::Double))
662   );
663   assert_eq!(
664     type_specifier_non_array("vec2"),
665     Ok(("", syntax::TypeSpecifierNonArray::Vec2))
666   );
667   assert_eq!(
668     type_specifier_non_array("vec3"),
669     Ok(("", syntax::TypeSpecifierNonArray::Vec3))
670   );
671   assert_eq!(
672     type_specifier_non_array("vec4"),
673     Ok(("", syntax::TypeSpecifierNonArray::Vec4))
674   );
675   assert_eq!(
676     type_specifier_non_array("dvec2"),
677     Ok(("", syntax::TypeSpecifierNonArray::DVec2))
678   );
679   assert_eq!(
680     type_specifier_non_array("dvec3"),
681     Ok(("", syntax::TypeSpecifierNonArray::DVec3))
682   );
683   assert_eq!(
684     type_specifier_non_array("dvec4"),
685     Ok(("", syntax::TypeSpecifierNonArray::DVec4))
686   );
687   assert_eq!(
688     type_specifier_non_array("bvec2"),
689     Ok(("", syntax::TypeSpecifierNonArray::BVec2))
690   );
691   assert_eq!(
692     type_specifier_non_array("bvec3"),
693     Ok(("", syntax::TypeSpecifierNonArray::BVec3))
694   );
695   assert_eq!(
696     type_specifier_non_array("bvec4"),
697     Ok(("", syntax::TypeSpecifierNonArray::BVec4))
698   );
699   assert_eq!(
700     type_specifier_non_array("ivec2"),
701     Ok(("", syntax::TypeSpecifierNonArray::IVec2))
702   );
703   assert_eq!(
704     type_specifier_non_array("ivec3"),
705     Ok(("", syntax::TypeSpecifierNonArray::IVec3))
706   );
707   assert_eq!(
708     type_specifier_non_array("ivec4"),
709     Ok(("", syntax::TypeSpecifierNonArray::IVec4))
710   );
711   assert_eq!(
712     type_specifier_non_array("uvec2"),
713     Ok(("", syntax::TypeSpecifierNonArray::UVec2))
714   );
715   assert_eq!(
716     type_specifier_non_array("uvec3"),
717     Ok(("", syntax::TypeSpecifierNonArray::UVec3))
718   );
719   assert_eq!(
720     type_specifier_non_array("uvec4"),
721     Ok(("", syntax::TypeSpecifierNonArray::UVec4))
722   );
723   assert_eq!(
724     type_specifier_non_array("mat2"),
725     Ok(("", syntax::TypeSpecifierNonArray::Mat2))
726   );
727   assert_eq!(
728     type_specifier_non_array("mat3"),
729     Ok(("", syntax::TypeSpecifierNonArray::Mat3))
730   );
731   assert_eq!(
732     type_specifier_non_array("mat4"),
733     Ok(("", syntax::TypeSpecifierNonArray::Mat4))
734   );
735   assert_eq!(
736     type_specifier_non_array("mat2x2"),
737     Ok(("", syntax::TypeSpecifierNonArray::Mat2))
738   );
739   assert_eq!(
740     type_specifier_non_array("mat2x3"),
741     Ok(("", syntax::TypeSpecifierNonArray::Mat23))
742   );
743   assert_eq!(
744     type_specifier_non_array("mat2x4"),
745     Ok(("", syntax::TypeSpecifierNonArray::Mat24))
746   );
747   assert_eq!(
748     type_specifier_non_array("mat3x2"),
749     Ok(("", syntax::TypeSpecifierNonArray::Mat32))
750   );
751   assert_eq!(
752     type_specifier_non_array("mat3x3"),
753     Ok(("", syntax::TypeSpecifierNonArray::Mat3))
754   );
755   assert_eq!(
756     type_specifier_non_array("mat3x4"),
757     Ok(("", syntax::TypeSpecifierNonArray::Mat34))
758   );
759   assert_eq!(
760     type_specifier_non_array("mat4x2"),
761     Ok(("", syntax::TypeSpecifierNonArray::Mat42))
762   );
763   assert_eq!(
764     type_specifier_non_array("mat4x3"),
765     Ok(("", syntax::TypeSpecifierNonArray::Mat43))
766   );
767   assert_eq!(
768     type_specifier_non_array("mat4x4"),
769     Ok(("", syntax::TypeSpecifierNonArray::Mat4))
770   );
771   assert_eq!(
772     type_specifier_non_array("dmat2"),
773     Ok(("", syntax::TypeSpecifierNonArray::DMat2))
774   );
775   assert_eq!(
776     type_specifier_non_array("dmat3"),
777     Ok(("", syntax::TypeSpecifierNonArray::DMat3))
778   );
779   assert_eq!(
780     type_specifier_non_array("dmat4"),
781     Ok(("", syntax::TypeSpecifierNonArray::DMat4))
782   );
783   assert_eq!(
784     type_specifier_non_array("dmat2x2"),
785     Ok(("", syntax::TypeSpecifierNonArray::DMat2))
786   );
787   assert_eq!(
788     type_specifier_non_array("dmat2x3"),
789     Ok(("", syntax::TypeSpecifierNonArray::DMat23))
790   );
791   assert_eq!(
792     type_specifier_non_array("dmat2x4"),
793     Ok(("", syntax::TypeSpecifierNonArray::DMat24))
794   );
795   assert_eq!(
796     type_specifier_non_array("dmat3x2"),
797     Ok(("", syntax::TypeSpecifierNonArray::DMat32))
798   );
799   assert_eq!(
800     type_specifier_non_array("dmat3x3"),
801     Ok(("", syntax::TypeSpecifierNonArray::DMat3))
802   );
803   assert_eq!(
804     type_specifier_non_array("dmat3x4"),
805     Ok(("", syntax::TypeSpecifierNonArray::DMat34))
806   );
807   assert_eq!(
808     type_specifier_non_array("dmat4x2"),
809     Ok(("", syntax::TypeSpecifierNonArray::DMat42))
810   );
811   assert_eq!(
812     type_specifier_non_array("dmat4x3"),
813     Ok(("", syntax::TypeSpecifierNonArray::DMat43))
814   );
815   assert_eq!(
816     type_specifier_non_array("dmat4x4"),
817     Ok(("", syntax::TypeSpecifierNonArray::DMat4))
818   );
819   assert_eq!(
820     type_specifier_non_array("sampler1D"),
821     Ok(("", syntax::TypeSpecifierNonArray::Sampler1D))
822   );
823   assert_eq!(
824     type_specifier_non_array("image1D"),
825     Ok(("", syntax::TypeSpecifierNonArray::Image1D))
826   );
827   assert_eq!(
828     type_specifier_non_array("sampler2D"),
829     Ok(("", syntax::TypeSpecifierNonArray::Sampler2D))
830   );
831   assert_eq!(
832     type_specifier_non_array("image2D"),
833     Ok(("", syntax::TypeSpecifierNonArray::Image2D))
834   );
835   assert_eq!(
836     type_specifier_non_array("sampler3D"),
837     Ok(("", syntax::TypeSpecifierNonArray::Sampler3D))
838   );
839   assert_eq!(
840     type_specifier_non_array("image3D"),
841     Ok(("", syntax::TypeSpecifierNonArray::Image3D))
842   );
843   assert_eq!(
844     type_specifier_non_array("samplerCube"),
845     Ok(("", syntax::TypeSpecifierNonArray::SamplerCube))
846   );
847   assert_eq!(
848     type_specifier_non_array("imageCube"),
849     Ok(("", syntax::TypeSpecifierNonArray::ImageCube))
850   );
851   assert_eq!(
852     type_specifier_non_array("sampler2DRect"),
853     Ok(("", syntax::TypeSpecifierNonArray::Sampler2DRect))
854   );
855   assert_eq!(
856     type_specifier_non_array("image2DRect"),
857     Ok(("", syntax::TypeSpecifierNonArray::Image2DRect))
858   );
859   assert_eq!(
860     type_specifier_non_array("sampler1DArray"),
861     Ok(("", syntax::TypeSpecifierNonArray::Sampler1DArray))
862   );
863   assert_eq!(
864     type_specifier_non_array("image1DArray"),
865     Ok(("", syntax::TypeSpecifierNonArray::Image1DArray))
866   );
867   assert_eq!(
868     type_specifier_non_array("sampler2DArray"),
869     Ok(("", syntax::TypeSpecifierNonArray::Sampler2DArray))
870   );
871   assert_eq!(
872     type_specifier_non_array("image2DArray"),
873     Ok(("", syntax::TypeSpecifierNonArray::Image2DArray))
874   );
875   assert_eq!(
876     type_specifier_non_array("samplerBuffer"),
877     Ok(("", syntax::TypeSpecifierNonArray::SamplerBuffer))
878   );
879   assert_eq!(
880     type_specifier_non_array("imageBuffer"),
881     Ok(("", syntax::TypeSpecifierNonArray::ImageBuffer))
882   );
883   assert_eq!(
884     type_specifier_non_array("sampler2DMS"),
885     Ok(("", syntax::TypeSpecifierNonArray::Sampler2DMS))
886   );
887   assert_eq!(
888     type_specifier_non_array("image2DMS"),
889     Ok(("", syntax::TypeSpecifierNonArray::Image2DMS))
890   );
891   assert_eq!(
892     type_specifier_non_array("sampler2DMSArray"),
893     Ok(("", syntax::TypeSpecifierNonArray::Sampler2DMSArray))
894   );
895   assert_eq!(
896     type_specifier_non_array("image2DMSArray"),
897     Ok(("", syntax::TypeSpecifierNonArray::Image2DMSArray))
898   );
899   assert_eq!(
900     type_specifier_non_array("samplerCubeArray"),
901     Ok(("", syntax::TypeSpecifierNonArray::SamplerCubeArray))
902   );
903   assert_eq!(
904     type_specifier_non_array("imageCubeArray"),
905     Ok(("", syntax::TypeSpecifierNonArray::ImageCubeArray))
906   );
907   assert_eq!(
908     type_specifier_non_array("sampler1DShadow"),
909     Ok(("", syntax::TypeSpecifierNonArray::Sampler1DShadow))
910   );
911   assert_eq!(
912     type_specifier_non_array("sampler2DShadow"),
913     Ok(("", syntax::TypeSpecifierNonArray::Sampler2DShadow))
914   );
915   assert_eq!(
916     type_specifier_non_array("sampler2DRectShadow"),
917     Ok(("", syntax::TypeSpecifierNonArray::Sampler2DRectShadow))
918   );
919   assert_eq!(
920     type_specifier_non_array("sampler1DArrayShadow"),
921     Ok(("", syntax::TypeSpecifierNonArray::Sampler1DArrayShadow))
922   );
923   assert_eq!(
924     type_specifier_non_array("sampler2DArrayShadow"),
925     Ok(("", syntax::TypeSpecifierNonArray::Sampler2DArrayShadow))
926   );
927   assert_eq!(
928     type_specifier_non_array("samplerCubeShadow"),
929     Ok(("", syntax::TypeSpecifierNonArray::SamplerCubeShadow))
930   );
931   assert_eq!(
932     type_specifier_non_array("samplerCubeArrayShadow"),
933     Ok(("", syntax::TypeSpecifierNonArray::SamplerCubeArrayShadow))
934   );
935   assert_eq!(
936     type_specifier_non_array("isampler1D"),
937     Ok(("", syntax::TypeSpecifierNonArray::ISampler1D))
938   );
939   assert_eq!(
940     type_specifier_non_array("iimage1D"),
941     Ok(("", syntax::TypeSpecifierNonArray::IImage1D))
942   );
943   assert_eq!(
944     type_specifier_non_array("isampler2D"),
945     Ok(("", syntax::TypeSpecifierNonArray::ISampler2D))
946   );
947   assert_eq!(
948     type_specifier_non_array("iimage2D"),
949     Ok(("", syntax::TypeSpecifierNonArray::IImage2D))
950   );
951   assert_eq!(
952     type_specifier_non_array("isampler3D"),
953     Ok(("", syntax::TypeSpecifierNonArray::ISampler3D))
954   );
955   assert_eq!(
956     type_specifier_non_array("iimage3D"),
957     Ok(("", syntax::TypeSpecifierNonArray::IImage3D))
958   );
959   assert_eq!(
960     type_specifier_non_array("isamplerCube"),
961     Ok(("", syntax::TypeSpecifierNonArray::ISamplerCube))
962   );
963   assert_eq!(
964     type_specifier_non_array("iimageCube"),
965     Ok(("", syntax::TypeSpecifierNonArray::IImageCube))
966   );
967   assert_eq!(
968     type_specifier_non_array("isampler2DRect"),
969     Ok(("", syntax::TypeSpecifierNonArray::ISampler2DRect))
970   );
971   assert_eq!(
972     type_specifier_non_array("iimage2DRect"),
973     Ok(("", syntax::TypeSpecifierNonArray::IImage2DRect))
974   );
975   assert_eq!(
976     type_specifier_non_array("isampler1DArray"),
977     Ok(("", syntax::TypeSpecifierNonArray::ISampler1DArray))
978   );
979   assert_eq!(
980     type_specifier_non_array("iimage1DArray"),
981     Ok(("", syntax::TypeSpecifierNonArray::IImage1DArray))
982   );
983   assert_eq!(
984     type_specifier_non_array("isampler2DArray"),
985     Ok(("", syntax::TypeSpecifierNonArray::ISampler2DArray))
986   );
987   assert_eq!(
988     type_specifier_non_array("iimage2DArray"),
989     Ok(("", syntax::TypeSpecifierNonArray::IImage2DArray))
990   );
991   assert_eq!(
992     type_specifier_non_array("isamplerBuffer"),
993     Ok(("", syntax::TypeSpecifierNonArray::ISamplerBuffer))
994   );
995   assert_eq!(
996     type_specifier_non_array("iimageBuffer"),
997     Ok(("", syntax::TypeSpecifierNonArray::IImageBuffer))
998   );
999   assert_eq!(
1000     type_specifier_non_array("isampler2DMS"),
1001     Ok(("", syntax::TypeSpecifierNonArray::ISampler2DMS))
1002   );
1003   assert_eq!(
1004     type_specifier_non_array("iimage2DMS"),
1005     Ok(("", syntax::TypeSpecifierNonArray::IImage2DMS))
1006   );
1007   assert_eq!(
1008     type_specifier_non_array("isampler2DMSArray"),
1009     Ok(("", syntax::TypeSpecifierNonArray::ISampler2DMSArray))
1010   );
1011   assert_eq!(
1012     type_specifier_non_array("iimage2DMSArray"),
1013     Ok(("", syntax::TypeSpecifierNonArray::IImage2DMSArray))
1014   );
1015   assert_eq!(
1016     type_specifier_non_array("isamplerCubeArray"),
1017     Ok(("", syntax::TypeSpecifierNonArray::ISamplerCubeArray))
1018   );
1019   assert_eq!(
1020     type_specifier_non_array("iimageCubeArray"),
1021     Ok(("", syntax::TypeSpecifierNonArray::IImageCubeArray))
1022   );
1023   assert_eq!(
1024     type_specifier_non_array("atomic_uint"),
1025     Ok(("", syntax::TypeSpecifierNonArray::AtomicUInt))
1026   );
1027   assert_eq!(
1028     type_specifier_non_array("usampler1D"),
1029     Ok(("", syntax::TypeSpecifierNonArray::USampler1D))
1030   );
1031   assert_eq!(
1032     type_specifier_non_array("uimage1D"),
1033     Ok(("", syntax::TypeSpecifierNonArray::UImage1D))
1034   );
1035   assert_eq!(
1036     type_specifier_non_array("usampler2D"),
1037     Ok(("", syntax::TypeSpecifierNonArray::USampler2D))
1038   );
1039   assert_eq!(
1040     type_specifier_non_array("uimage2D"),
1041     Ok(("", syntax::TypeSpecifierNonArray::UImage2D))
1042   );
1043   assert_eq!(
1044     type_specifier_non_array("usampler3D"),
1045     Ok(("", syntax::TypeSpecifierNonArray::USampler3D))
1046   );
1047   assert_eq!(
1048     type_specifier_non_array("uimage3D"),
1049     Ok(("", syntax::TypeSpecifierNonArray::UImage3D))
1050   );
1051   assert_eq!(
1052     type_specifier_non_array("usamplerCube"),
1053     Ok(("", syntax::TypeSpecifierNonArray::USamplerCube))
1054   );
1055   assert_eq!(
1056     type_specifier_non_array("uimageCube"),
1057     Ok(("", syntax::TypeSpecifierNonArray::UImageCube))
1058   );
1059   assert_eq!(
1060     type_specifier_non_array("usampler2DRect"),
1061     Ok(("", syntax::TypeSpecifierNonArray::USampler2DRect))
1062   );
1063   assert_eq!(
1064     type_specifier_non_array("uimage2DRect"),
1065     Ok(("", syntax::TypeSpecifierNonArray::UImage2DRect))
1066   );
1067   assert_eq!(
1068     type_specifier_non_array("usampler1DArray"),
1069     Ok(("", syntax::TypeSpecifierNonArray::USampler1DArray))
1070   );
1071   assert_eq!(
1072     type_specifier_non_array("uimage1DArray"),
1073     Ok(("", syntax::TypeSpecifierNonArray::UImage1DArray))
1074   );
1075   assert_eq!(
1076     type_specifier_non_array("usampler2DArray"),
1077     Ok(("", syntax::TypeSpecifierNonArray::USampler2DArray))
1078   );
1079   assert_eq!(
1080     type_specifier_non_array("uimage2DArray"),
1081     Ok(("", syntax::TypeSpecifierNonArray::UImage2DArray))
1082   );
1083   assert_eq!(
1084     type_specifier_non_array("usamplerBuffer"),
1085     Ok(("", syntax::TypeSpecifierNonArray::USamplerBuffer))
1086   );
1087   assert_eq!(
1088     type_specifier_non_array("uimageBuffer"),
1089     Ok(("", syntax::TypeSpecifierNonArray::UImageBuffer))
1090   );
1091   assert_eq!(
1092     type_specifier_non_array("usampler2DMS"),
1093     Ok(("", syntax::TypeSpecifierNonArray::USampler2DMS))
1094   );
1095   assert_eq!(
1096     type_specifier_non_array("uimage2DMS"),
1097     Ok(("", syntax::TypeSpecifierNonArray::UImage2DMS))
1098   );
1099   assert_eq!(
1100     type_specifier_non_array("usampler2DMSArray"),
1101     Ok(("", syntax::TypeSpecifierNonArray::USampler2DMSArray))
1102   );
1103   assert_eq!(
1104     type_specifier_non_array("uimage2DMSArray"),
1105     Ok(("", syntax::TypeSpecifierNonArray::UImage2DMSArray))
1106   );
1107   assert_eq!(
1108     type_specifier_non_array("usamplerCubeArray"),
1109     Ok(("", syntax::TypeSpecifierNonArray::USamplerCubeArray))
1110   );
1111   assert_eq!(
1112     type_specifier_non_array("uimageCubeArray"),
1113     Ok(("", syntax::TypeSpecifierNonArray::UImageCubeArray))
1114   );
1115   assert_eq!(
1116     type_specifier_non_array("ReturnType"),
1117     Ok((
1118       "",
1119       syntax::TypeSpecifierNonArray::TypeName(syntax::TypeName::new("ReturnType").unwrap())
1120     ))
1121   );
1122 }
1123 
1124 #[test]
parse_type_specifier()1125 fn parse_type_specifier() {
1126   assert_eq!(
1127     type_specifier("uint;"),
1128     Ok((
1129       ";",
1130       syntax::TypeSpecifier {
1131         ty: syntax::TypeSpecifierNonArray::UInt,
1132         array_specifier: None
1133       }
1134     ))
1135   );
1136   assert_eq!(
1137     type_specifier("iimage2DMSArray[35];"),
1138     Ok((
1139       ";",
1140       syntax::TypeSpecifier {
1141         ty: syntax::TypeSpecifierNonArray::IImage2DMSArray,
1142         array_specifier: Some(syntax::ArraySpecifier::ExplicitlySized(Box::new(
1143           syntax::Expr::IntConst(35)
1144         )))
1145       }
1146     ))
1147   );
1148 }
1149 
1150 #[test]
parse_fully_specified_type()1151 fn parse_fully_specified_type() {
1152   let ty = syntax::TypeSpecifier {
1153     ty: syntax::TypeSpecifierNonArray::IImage2DMSArray,
1154     array_specifier: None,
1155   };
1156   let expected = syntax::FullySpecifiedType {
1157     qualifier: None,
1158     ty,
1159   };
1160 
1161   assert_eq!(
1162     fully_specified_type("iimage2DMSArray;"),
1163     Ok((";", expected.clone()))
1164   );
1165 }
1166 
1167 #[test]
parse_fully_specified_type_with_qualifier()1168 fn parse_fully_specified_type_with_qualifier() {
1169   let qual_spec = syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Subroutine(vec![
1170     "vec2".into(),
1171     "S032_29k".into(),
1172   ]));
1173   let qual = syntax::TypeQualifier {
1174     qualifiers: syntax::NonEmpty(vec![qual_spec]),
1175   };
1176   let ty = syntax::TypeSpecifier {
1177     ty: syntax::TypeSpecifierNonArray::IImage2DMSArray,
1178     array_specifier: None,
1179   };
1180   let expected = syntax::FullySpecifiedType {
1181     qualifier: Some(qual),
1182     ty,
1183   };
1184 
1185   assert_eq!(
1186     fully_specified_type("subroutine (vec2, S032_29k) iimage2DMSArray;"),
1187     Ok((";", expected.clone()))
1188   );
1189   assert_eq!(
1190     fully_specified_type("subroutine (  vec2\t\n \t , \n S032_29k   )\n iimage2DMSArray ;"),
1191     Ok((" ;", expected.clone()))
1192   );
1193   assert_eq!(
1194     fully_specified_type("subroutine(vec2,S032_29k)iimage2DMSArray;"),
1195     Ok((";", expected))
1196   );
1197 }
1198 
1199 #[test]
parse_primary_expr_intconst()1200 fn parse_primary_expr_intconst() {
1201   assert_eq!(primary_expr("0 "), Ok((" ", syntax::Expr::IntConst(0))));
1202   assert_eq!(primary_expr("1 "), Ok((" ", syntax::Expr::IntConst(1))));
1203 }
1204 
1205 #[test]
parse_primary_expr_uintconst()1206 fn parse_primary_expr_uintconst() {
1207   assert_eq!(primary_expr("0u "), Ok((" ", syntax::Expr::UIntConst(0))));
1208   assert_eq!(primary_expr("1u "), Ok((" ", syntax::Expr::UIntConst(1))));
1209 }
1210 
1211 #[test]
parse_primary_expr_floatconst()1212 fn parse_primary_expr_floatconst() {
1213   assert_eq!(
1214     primary_expr("0.f "),
1215     Ok((" ", syntax::Expr::FloatConst(0.)))
1216   );
1217   assert_eq!(
1218     primary_expr("1.f "),
1219     Ok((" ", syntax::Expr::FloatConst(1.)))
1220   );
1221   assert_eq!(
1222     primary_expr("0.F "),
1223     Ok((" ", syntax::Expr::FloatConst(0.)))
1224   );
1225   assert_eq!(
1226     primary_expr("1.F "),
1227     Ok((" ", syntax::Expr::FloatConst(1.)))
1228   );
1229 }
1230 
1231 #[test]
parse_primary_expr_doubleconst()1232 fn parse_primary_expr_doubleconst() {
1233   assert_eq!(
1234     primary_expr("0. "),
1235     Ok((" ", syntax::Expr::DoubleConst(0.)))
1236   );
1237   assert_eq!(
1238     primary_expr("1. "),
1239     Ok((" ", syntax::Expr::DoubleConst(1.)))
1240   );
1241   assert_eq!(
1242     primary_expr("0.lf "),
1243     Ok((" ", syntax::Expr::DoubleConst(0.)))
1244   );
1245   assert_eq!(
1246     primary_expr("1.lf "),
1247     Ok((" ", syntax::Expr::DoubleConst(1.)))
1248   );
1249   assert_eq!(
1250     primary_expr("0.LF "),
1251     Ok((" ", syntax::Expr::DoubleConst(0.)))
1252   );
1253   assert_eq!(
1254     primary_expr("1.LF "),
1255     Ok((" ", syntax::Expr::DoubleConst(1.)))
1256   );
1257 }
1258 
1259 #[test]
parse_primary_expr_boolconst()1260 fn parse_primary_expr_boolconst() {
1261   assert_eq!(
1262     primary_expr("false"),
1263     Ok(("", syntax::Expr::BoolConst(false.to_owned())))
1264   );
1265   assert_eq!(
1266     primary_expr("true"),
1267     Ok(("", syntax::Expr::BoolConst(true.to_owned())))
1268   );
1269 }
1270 
1271 #[test]
parse_primary_expr_parens()1272 fn parse_primary_expr_parens() {
1273   assert_eq!(primary_expr("(0)"), Ok(("", syntax::Expr::IntConst(0))));
1274   assert_eq!(primary_expr("(  0 )"), Ok(("", syntax::Expr::IntConst(0))));
1275   assert_eq!(
1276     primary_expr("(  .0 )"),
1277     Ok(("", syntax::Expr::DoubleConst(0.)))
1278   );
1279   assert_eq!(
1280     primary_expr("(  (.0) )"),
1281     Ok(("", syntax::Expr::DoubleConst(0.)))
1282   );
1283   assert_eq!(
1284     primary_expr("(true) "),
1285     Ok((" ", syntax::Expr::BoolConst(true)))
1286   );
1287 }
1288 
1289 #[test]
parse_postfix_function_call_no_args()1290 fn parse_postfix_function_call_no_args() {
1291   let fun = syntax::FunIdentifier::Identifier("vec3".into());
1292   let args = Vec::new();
1293   let expected = syntax::Expr::FunCall(fun, args);
1294 
1295   assert_eq!(postfix_expr("vec3();"), Ok((";", expected.clone())));
1296   assert_eq!(postfix_expr("vec3   (  ) ;"), Ok((" ;", expected.clone())));
1297   assert_eq!(postfix_expr("vec3   (\nvoid\n) ;"), Ok((" ;", expected)));
1298 }
1299 
1300 #[test]
parse_postfix_function_call_one_arg()1301 fn parse_postfix_function_call_one_arg() {
1302   let fun = syntax::FunIdentifier::Identifier("foo".into());
1303   let args = vec![syntax::Expr::IntConst(0)];
1304   let expected = syntax::Expr::FunCall(fun, args);
1305 
1306   assert_eq!(postfix_expr("foo(0);"), Ok((";", expected.clone())));
1307   assert_eq!(postfix_expr("foo   ( 0 ) ;"), Ok((" ;", expected.clone())));
1308   assert_eq!(postfix_expr("foo   (\n0\t\n) ;"), Ok((" ;", expected)));
1309 }
1310 
1311 #[test]
parse_postfix_function_call_multi_arg()1312 fn parse_postfix_function_call_multi_arg() {
1313   let fun = syntax::FunIdentifier::Identifier("foo".into());
1314   let args = vec![
1315     syntax::Expr::IntConst(0),
1316     syntax::Expr::BoolConst(false),
1317     syntax::Expr::Variable("bar".into()),
1318   ];
1319   let expected = syntax::Expr::FunCall(fun, args);
1320 
1321   assert_eq!(
1322     postfix_expr("foo(0, false, bar);"),
1323     Ok((";", expected.clone()))
1324   );
1325   assert_eq!(
1326     postfix_expr("foo   ( 0\t, false    ,\t\tbar) ;"),
1327     Ok((" ;", expected))
1328   );
1329 }
1330 
1331 #[test]
parse_postfix_expr_bracket()1332 fn parse_postfix_expr_bracket() {
1333   let id = syntax::Expr::Variable("foo".into());
1334   let array_spec = syntax::ArraySpecifier::ExplicitlySized(Box::new(syntax::Expr::IntConst(7354)));
1335   let expected = syntax::Expr::Bracket(Box::new(id), array_spec);
1336 
1337   assert_eq!(postfix_expr("foo[7354];"), Ok((";", expected.clone())));
1338   assert_eq!(postfix_expr("foo[\n  7354    ] ;"), Ok((" ;", expected)));
1339 }
1340 
1341 #[test]
parse_postfix_expr_dot()1342 fn parse_postfix_expr_dot() {
1343   let foo = Box::new(syntax::Expr::Variable("foo".into()));
1344   let expected = syntax::Expr::Dot(foo, "bar".into());
1345 
1346   assert_eq!(postfix_expr("foo.bar;"), Ok((";", expected.clone())));
1347   assert_eq!(postfix_expr("(foo).bar;"), Ok((";", expected)));
1348 }
1349 
1350 #[test]
parse_postfix_expr_dot_several()1351 fn parse_postfix_expr_dot_several() {
1352   let foo = Box::new(syntax::Expr::Variable("foo".into()));
1353   let expected = syntax::Expr::Dot(Box::new(syntax::Expr::Dot(foo, "bar".into())), "zoo".into());
1354 
1355   assert_eq!(postfix_expr("foo.bar.zoo;"), Ok((";", expected.clone())));
1356   assert_eq!(postfix_expr("(foo).bar.zoo;"), Ok((";", expected.clone())));
1357   assert_eq!(postfix_expr("(foo.bar).zoo;"), Ok((";", expected)));
1358 }
1359 
1360 #[test]
parse_postfix_postinc()1361 fn parse_postfix_postinc() {
1362   let foo = syntax::Expr::Variable("foo".into());
1363   let expected = syntax::Expr::PostInc(Box::new(foo));
1364 
1365   assert_eq!(postfix_expr("foo++;"), Ok((";", expected.clone())));
1366 }
1367 
1368 #[test]
parse_postfix_postdec()1369 fn parse_postfix_postdec() {
1370   let foo = syntax::Expr::Variable("foo".into());
1371   let expected = syntax::Expr::PostDec(Box::new(foo));
1372 
1373   assert_eq!(postfix_expr("foo--;"), Ok((";", expected.clone())));
1374 }
1375 
1376 #[test]
parse_unary_add()1377 fn parse_unary_add() {
1378   let foo = syntax::Expr::Variable("foo".into());
1379   let expected = syntax::Expr::Unary(syntax::UnaryOp::Add, Box::new(foo));
1380 
1381   assert_eq!(unary_expr("+foo;"), Ok((";", expected.clone())));
1382 }
1383 
1384 #[test]
parse_unary_minus()1385 fn parse_unary_minus() {
1386   let foo = syntax::Expr::Variable("foo".into());
1387   let expected = syntax::Expr::Unary(syntax::UnaryOp::Minus, Box::new(foo));
1388 
1389   assert_eq!(unary_expr("-foo;"), Ok((";", expected.clone())));
1390 }
1391 
1392 #[test]
parse_unary_not()1393 fn parse_unary_not() {
1394   let foo = syntax::Expr::Variable("foo".into());
1395   let expected = syntax::Expr::Unary(syntax::UnaryOp::Not, Box::new(foo));
1396 
1397   assert_eq!(unary_expr("!foo;"), Ok((";", expected)));
1398 }
1399 
1400 #[test]
parse_unary_complement()1401 fn parse_unary_complement() {
1402   let foo = syntax::Expr::Variable("foo".into());
1403   let expected = syntax::Expr::Unary(syntax::UnaryOp::Complement, Box::new(foo));
1404 
1405   assert_eq!(unary_expr("~foo;"), Ok((";", expected.clone())));
1406 }
1407 
1408 #[test]
parse_unary_inc()1409 fn parse_unary_inc() {
1410   let foo = syntax::Expr::Variable("foo".into());
1411   let expected = syntax::Expr::Unary(syntax::UnaryOp::Inc, Box::new(foo));
1412 
1413   assert_eq!(unary_expr("++foo;"), Ok((";", expected.clone())));
1414 }
1415 
1416 #[test]
parse_unary_dec()1417 fn parse_unary_dec() {
1418   let foo = syntax::Expr::Variable("foo".into());
1419   let expected = syntax::Expr::Unary(syntax::UnaryOp::Dec, Box::new(foo));
1420 
1421   assert_eq!(unary_expr("--foo;"), Ok((";", expected.clone())));
1422 }
1423 
1424 #[test]
parse_expr_float()1425 fn parse_expr_float() {
1426   assert_eq!(expr("314.;"), Ok((";", syntax::Expr::DoubleConst(314.))));
1427   assert_eq!(expr("314.f;"), Ok((";", syntax::Expr::FloatConst(314.))));
1428 }
1429 
1430 #[test]
parse_expr_add_2()1431 fn parse_expr_add_2() {
1432   let one = Box::new(syntax::Expr::IntConst(1));
1433   let expected = syntax::Expr::Binary(syntax::BinaryOp::Add, one.clone(), one);
1434 
1435   assert_eq!(expr("1 + 1;"), Ok((";", expected.clone())));
1436   assert_eq!(expr("1+1;"), Ok((";", expected.clone())));
1437   assert_eq!(expr("(1 + 1);"), Ok((";", expected)));
1438 }
1439 
1440 #[test]
parse_expr_add_3()1441 fn parse_expr_add_3() {
1442   let one = Box::new(syntax::Expr::UIntConst(1));
1443   let two = Box::new(syntax::Expr::UIntConst(2));
1444   let three = Box::new(syntax::Expr::UIntConst(3));
1445   let expected = syntax::Expr::Binary(
1446     syntax::BinaryOp::Add,
1447     Box::new(syntax::Expr::Binary(syntax::BinaryOp::Add, one, two)),
1448     three,
1449   );
1450 
1451   assert_eq!(expr("1u + 2u + 3u"), Ok(("", expected.clone())));
1452   assert_eq!(expr("1u + 2u + 3u   "), Ok(("   ", expected.clone())));
1453   assert_eq!(expr("1u+2u+3u"), Ok(("", expected.clone())));
1454   assert_eq!(expr("((1u + 2u) + 3u)"), Ok(("", expected)));
1455 }
1456 
1457 #[test]
parse_expr_add_mult_3()1458 fn parse_expr_add_mult_3() {
1459   let one = Box::new(syntax::Expr::UIntConst(1));
1460   let two = Box::new(syntax::Expr::UIntConst(2));
1461   let three = Box::new(syntax::Expr::UIntConst(3));
1462   let expected = syntax::Expr::Binary(
1463     syntax::BinaryOp::Add,
1464     Box::new(syntax::Expr::Binary(syntax::BinaryOp::Mult, one, two)),
1465     three,
1466   );
1467 
1468   assert_eq!(expr("1u * 2u + 3u ;"), Ok((" ;", expected.clone())));
1469   assert_eq!(expr("1u*2u+3u;"), Ok((";", expected.clone())));
1470   assert_eq!(expr("(1u * 2u) + 3u;"), Ok((";", expected)));
1471 }
1472 
1473 #[test]
parse_expr_add_sub_mult_div()1474 fn parse_expr_add_sub_mult_div() {
1475   let one = Box::new(syntax::Expr::IntConst(1));
1476   let two = Box::new(syntax::Expr::IntConst(2));
1477   let three = Box::new(syntax::Expr::IntConst(3));
1478   let four = Box::new(syntax::Expr::IntConst(4));
1479   let five = Box::new(syntax::Expr::IntConst(5));
1480   let six = Box::new(syntax::Expr::IntConst(6));
1481   let expected = syntax::Expr::Binary(
1482     syntax::BinaryOp::Add,
1483     Box::new(syntax::Expr::Binary(
1484       syntax::BinaryOp::Mult,
1485       one,
1486       Box::new(syntax::Expr::Binary(syntax::BinaryOp::Add, two, three)),
1487     )),
1488     Box::new(syntax::Expr::Binary(
1489       syntax::BinaryOp::Div,
1490       four,
1491       Box::new(syntax::Expr::Binary(syntax::BinaryOp::Add, five, six)),
1492     )),
1493   );
1494 
1495   assert_eq!(
1496     expr("1 * (2 + 3) + 4 / (5 + 6);"),
1497     Ok((";", expected.clone()))
1498   );
1499 }
1500 
1501 #[test]
parse_complex_expr()1502 fn parse_complex_expr() {
1503   let input = "normalize((inverse(view) * vec4(ray.dir, 0.)).xyz);";
1504   let zero = syntax::Expr::DoubleConst(0.);
1505   let ray = syntax::Expr::Variable("ray".into());
1506   let raydir = syntax::Expr::Dot(Box::new(ray), "dir".into());
1507   let vec4 = syntax::Expr::FunCall(
1508     syntax::FunIdentifier::Identifier("vec4".into()),
1509     vec![raydir, zero],
1510   );
1511   let view = syntax::Expr::Variable("view".into());
1512   let iview = syntax::Expr::FunCall(
1513     syntax::FunIdentifier::Identifier("inverse".into()),
1514     vec![view],
1515   );
1516   let mul = syntax::Expr::Binary(syntax::BinaryOp::Mult, Box::new(iview), Box::new(vec4));
1517   let xyz = syntax::Expr::Dot(Box::new(mul), "xyz".into());
1518   let normalize = syntax::Expr::FunCall(
1519     syntax::FunIdentifier::Identifier("normalize".into()),
1520     vec![xyz],
1521   );
1522   let expected = normalize;
1523 
1524   assert_eq!(expr(&input[..]), Ok((";", expected)));
1525 }
1526 
1527 #[test]
parse_function_identifier_typename()1528 fn parse_function_identifier_typename() {
1529   let expected = syntax::FunIdentifier::Identifier("foo".into());
1530   assert_eq!(function_identifier("foo("), Ok(("(", expected.clone())));
1531   assert_eq!(function_identifier("foo\n\t("), Ok(("(", expected.clone())));
1532   assert_eq!(function_identifier("foo\n ("), Ok(("(", expected)));
1533 }
1534 
1535 #[test]
parse_function_identifier_cast()1536 fn parse_function_identifier_cast() {
1537   let expected = syntax::FunIdentifier::Identifier("vec3".into());
1538   assert_eq!(function_identifier("vec3("), Ok(("(", expected.clone())));
1539   assert_eq!(function_identifier("vec3 ("), Ok(("(", expected.clone())));
1540   assert_eq!(function_identifier("vec3\t\n\n \t ("), Ok(("(", expected)));
1541 }
1542 
1543 #[test]
parse_function_identifier_cast_array_unsized()1544 fn parse_function_identifier_cast_array_unsized() {
1545   let expected = syntax::FunIdentifier::Expr(Box::new(syntax::Expr::Bracket(
1546     Box::new(syntax::Expr::Variable("vec3".into())),
1547     syntax::ArraySpecifier::Unsized,
1548   )));
1549 
1550   assert_eq!(function_identifier("vec3[]("), Ok(("(", expected.clone())));
1551   assert_eq!(function_identifier("vec3  [\t\n]("), Ok(("(", expected)));
1552 }
1553 
1554 #[test]
parse_function_identifier_cast_array_sized()1555 fn parse_function_identifier_cast_array_sized() {
1556   let expected = syntax::FunIdentifier::Expr(Box::new(syntax::Expr::Bracket(
1557     Box::new(syntax::Expr::Variable("vec3".into())),
1558     syntax::ArraySpecifier::ExplicitlySized(Box::new(syntax::Expr::IntConst(12))),
1559   )));
1560 
1561   assert_eq!(
1562     function_identifier("vec3[12]("),
1563     Ok(("(", expected.clone()))
1564   );
1565   assert_eq!(function_identifier("vec3  [\t 12\n]("), Ok(("(", expected)));
1566 }
1567 
1568 #[test]
parse_void()1569 fn parse_void() {
1570   assert_eq!(void("void "), Ok((" ", ())));
1571 }
1572 
1573 #[test]
parse_assignment_op_equal()1574 fn parse_assignment_op_equal() {
1575   assert_eq!(assignment_op("= "), Ok((" ", syntax::AssignmentOp::Equal)));
1576 }
1577 
1578 #[test]
parse_assignment_op_mult()1579 fn parse_assignment_op_mult() {
1580   assert_eq!(assignment_op("*= "), Ok((" ", syntax::AssignmentOp::Mult)));
1581 }
1582 
1583 #[test]
parse_assignment_op_div()1584 fn parse_assignment_op_div() {
1585   assert_eq!(assignment_op("/= "), Ok((" ", syntax::AssignmentOp::Div)));
1586 }
1587 
1588 #[test]
parse_assignment_op_mod()1589 fn parse_assignment_op_mod() {
1590   assert_eq!(assignment_op("%= "), Ok((" ", syntax::AssignmentOp::Mod)));
1591 }
1592 
1593 #[test]
parse_assignment_op_add()1594 fn parse_assignment_op_add() {
1595   assert_eq!(assignment_op("+= "), Ok((" ", syntax::AssignmentOp::Add)));
1596 }
1597 
1598 #[test]
parse_assignment_op_sub()1599 fn parse_assignment_op_sub() {
1600   assert_eq!(assignment_op("-= "), Ok((" ", syntax::AssignmentOp::Sub)));
1601 }
1602 
1603 #[test]
parse_assignment_op_lshift()1604 fn parse_assignment_op_lshift() {
1605   assert_eq!(
1606     assignment_op("<<= "),
1607     Ok((" ", syntax::AssignmentOp::LShift))
1608   );
1609 }
1610 
1611 #[test]
parse_assignment_op_rshift()1612 fn parse_assignment_op_rshift() {
1613   assert_eq!(
1614     assignment_op(">>= "),
1615     Ok((" ", syntax::AssignmentOp::RShift))
1616   );
1617 }
1618 
1619 #[test]
parse_assignment_op_and()1620 fn parse_assignment_op_and() {
1621   assert_eq!(assignment_op("&= "), Ok((" ", syntax::AssignmentOp::And)));
1622 }
1623 
1624 #[test]
parse_assignment_op_xor()1625 fn parse_assignment_op_xor() {
1626   assert_eq!(assignment_op("^= "), Ok((" ", syntax::AssignmentOp::Xor)));
1627 }
1628 
1629 #[test]
parse_assignment_op_or()1630 fn parse_assignment_op_or() {
1631   assert_eq!(assignment_op("|= "), Ok((" ", syntax::AssignmentOp::Or)));
1632 }
1633 
1634 #[test]
parse_expr_statement()1635 fn parse_expr_statement() {
1636   let expected = Some(syntax::Expr::Assignment(
1637     Box::new(syntax::Expr::Variable("foo".into())),
1638     syntax::AssignmentOp::Equal,
1639     Box::new(syntax::Expr::FloatConst(314.)),
1640   ));
1641 
1642   assert_eq!(expr_statement("foo = 314.f;"), Ok(("", expected.clone())));
1643   assert_eq!(expr_statement("foo=314.f;"), Ok(("", expected.clone())));
1644   assert_eq!(expr_statement("foo\n\t=  \n314.f;"), Ok(("", expected)));
1645 }
1646 
1647 #[test]
parse_declaration_function_prototype()1648 fn parse_declaration_function_prototype() {
1649   let rt = syntax::FullySpecifiedType {
1650     qualifier: None,
1651     ty: syntax::TypeSpecifier {
1652       ty: syntax::TypeSpecifierNonArray::Vec3,
1653       array_specifier: None,
1654     },
1655   };
1656   let arg0_ty = syntax::TypeSpecifier {
1657     ty: syntax::TypeSpecifierNonArray::Vec2,
1658     array_specifier: None,
1659   };
1660   let arg0 = syntax::FunctionParameterDeclaration::Unnamed(None, arg0_ty);
1661   let qual_spec = syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Out);
1662   let qual = syntax::TypeQualifier {
1663     qualifiers: syntax::NonEmpty(vec![qual_spec]),
1664   };
1665   let arg1 = syntax::FunctionParameterDeclaration::Named(
1666     Some(qual),
1667     syntax::FunctionParameterDeclarator {
1668       ty: syntax::TypeSpecifier {
1669         ty: syntax::TypeSpecifierNonArray::Float,
1670         array_specifier: None,
1671       },
1672       ident: "the_arg".into(),
1673     },
1674   );
1675   let fp = syntax::FunctionPrototype {
1676     ty: rt,
1677     name: "foo".into(),
1678     parameters: vec![arg0, arg1],
1679   };
1680   let expected = syntax::Declaration::FunctionPrototype(fp);
1681 
1682   assert_eq!(
1683     declaration("vec3 foo(vec2, out float the_arg);"),
1684     Ok(("", expected.clone()))
1685   );
1686   assert_eq!(
1687     declaration("vec3 \nfoo ( vec2\n, out float \n\tthe_arg )\n;"),
1688     Ok(("", expected.clone()))
1689   );
1690   assert_eq!(
1691     declaration("vec3 foo(vec2,out float the_arg);"),
1692     Ok(("", expected))
1693   );
1694 }
1695 
1696 #[test]
parse_declaration_init_declarator_list_single()1697 fn parse_declaration_init_declarator_list_single() {
1698   let ty = syntax::FullySpecifiedType {
1699     qualifier: None,
1700     ty: syntax::TypeSpecifier {
1701       ty: syntax::TypeSpecifierNonArray::Int,
1702       array_specifier: None,
1703     },
1704   };
1705   let sd = syntax::SingleDeclaration {
1706     ty,
1707     name: Some("foo".into()),
1708     array_specifier: None,
1709     initializer: Some(syntax::Initializer::Simple(Box::new(
1710       syntax::Expr::IntConst(34),
1711     ))),
1712   };
1713   let idl = syntax::InitDeclaratorList {
1714     head: sd,
1715     tail: Vec::new(),
1716   };
1717   let expected = syntax::Declaration::InitDeclaratorList(idl);
1718 
1719   assert_eq!(declaration("int foo = 34;"), Ok(("", expected.clone())));
1720   assert_eq!(declaration("int foo=34;"), Ok(("", expected.clone())));
1721   assert_eq!(declaration("int    \t  \nfoo =\t34  ;"), Ok(("", expected)));
1722 }
1723 
1724 #[test]
parse_declaration_init_declarator_list_complex()1725 fn parse_declaration_init_declarator_list_complex() {
1726   let ty = syntax::FullySpecifiedType {
1727     qualifier: None,
1728     ty: syntax::TypeSpecifier {
1729       ty: syntax::TypeSpecifierNonArray::Int,
1730       array_specifier: None,
1731     },
1732   };
1733   let sd = syntax::SingleDeclaration {
1734     ty,
1735     name: Some("foo".into()),
1736     array_specifier: None,
1737     initializer: Some(syntax::Initializer::Simple(Box::new(
1738       syntax::Expr::IntConst(34),
1739     ))),
1740   };
1741   let sdnt = syntax::SingleDeclarationNoType {
1742     ident: "bar".into(),
1743     initializer: Some(syntax::Initializer::Simple(Box::new(
1744       syntax::Expr::IntConst(12),
1745     ))),
1746   };
1747   let expected = syntax::Declaration::InitDeclaratorList(syntax::InitDeclaratorList {
1748     head: sd,
1749     tail: vec![sdnt],
1750   });
1751 
1752   assert_eq!(
1753     declaration("int foo = 34, bar = 12;"),
1754     Ok(("", expected.clone()))
1755   );
1756   assert_eq!(
1757     declaration("int foo=34,bar=12;"),
1758     Ok(("", expected.clone()))
1759   );
1760   assert_eq!(
1761     declaration("int    \t  \nfoo =\t34 \n,\tbar=      12\n ;"),
1762     Ok(("", expected))
1763   );
1764 }
1765 
1766 #[test]
parse_declaration_precision_low()1767 fn parse_declaration_precision_low() {
1768   let qual = syntax::PrecisionQualifier::Low;
1769   let ty = syntax::TypeSpecifier {
1770     ty: syntax::TypeSpecifierNonArray::Float,
1771     array_specifier: None,
1772   };
1773   let expected = syntax::Declaration::Precision(qual, ty);
1774 
1775   assert_eq!(declaration("precision lowp float;"), Ok(("", expected)));
1776 }
1777 
1778 #[test]
parse_declaration_precision_medium()1779 fn parse_declaration_precision_medium() {
1780   let qual = syntax::PrecisionQualifier::Medium;
1781   let ty = syntax::TypeSpecifier {
1782     ty: syntax::TypeSpecifierNonArray::Float,
1783     array_specifier: None,
1784   };
1785   let expected = syntax::Declaration::Precision(qual, ty);
1786 
1787   assert_eq!(declaration("precision mediump float;"), Ok(("", expected)));
1788 }
1789 
1790 #[test]
parse_declaration_precision_high()1791 fn parse_declaration_precision_high() {
1792   let qual = syntax::PrecisionQualifier::High;
1793   let ty = syntax::TypeSpecifier {
1794     ty: syntax::TypeSpecifierNonArray::Float,
1795     array_specifier: None,
1796   };
1797   let expected = syntax::Declaration::Precision(qual, ty);
1798 
1799   assert_eq!(declaration("precision highp float;"), Ok(("", expected)));
1800 }
1801 
1802 #[test]
parse_declaration_uniform_block()1803 fn parse_declaration_uniform_block() {
1804   let qual_spec = syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Uniform);
1805   let qual = syntax::TypeQualifier {
1806     qualifiers: syntax::NonEmpty(vec![qual_spec]),
1807   };
1808   let f0 = syntax::StructFieldSpecifier {
1809     qualifier: None,
1810     ty: syntax::TypeSpecifier {
1811       ty: syntax::TypeSpecifierNonArray::Float,
1812       array_specifier: None,
1813     },
1814     identifiers: syntax::NonEmpty(vec!["a".into()]),
1815   };
1816   let f1 = syntax::StructFieldSpecifier {
1817     qualifier: None,
1818     ty: syntax::TypeSpecifier {
1819       ty: syntax::TypeSpecifierNonArray::Vec3,
1820       array_specifier: None,
1821     },
1822     identifiers: syntax::NonEmpty(vec!["b".into()]),
1823   };
1824   let f2 = syntax::StructFieldSpecifier {
1825     qualifier: None,
1826     ty: syntax::TypeSpecifier {
1827       ty: syntax::TypeSpecifierNonArray::TypeName("foo".into()),
1828       array_specifier: None,
1829     },
1830     identifiers: syntax::NonEmpty(vec!["c".into(), "d".into()]),
1831   };
1832   let expected = syntax::Declaration::Block(syntax::Block {
1833     qualifier: qual,
1834     name: "UniformBlockTest".into(),
1835     fields: vec![f0, f1, f2],
1836     identifier: None,
1837   });
1838 
1839   assert_eq!(
1840     declaration("uniform UniformBlockTest { float a; vec3 b; foo c, d; };"),
1841     Ok(("", expected.clone()))
1842   );
1843   assert_eq!(declaration("uniform   \nUniformBlockTest\n {\n \t float   a  \n; \nvec3 b\n; foo \nc\n, \nd\n;\n }\n\t\n\t\t \t;"), Ok(("", expected)));
1844 }
1845 
1846 #[test]
parse_declaration_buffer_block()1847 fn parse_declaration_buffer_block() {
1848   let qual_spec = syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Buffer);
1849   let qual = syntax::TypeQualifier {
1850     qualifiers: syntax::NonEmpty(vec![qual_spec]),
1851   };
1852   let f0 = syntax::StructFieldSpecifier {
1853     qualifier: None,
1854     ty: syntax::TypeSpecifier {
1855       ty: syntax::TypeSpecifierNonArray::Float,
1856       array_specifier: None,
1857     },
1858     identifiers: syntax::NonEmpty(vec!["a".into()]),
1859   };
1860   let f1 = syntax::StructFieldSpecifier {
1861     qualifier: None,
1862     ty: syntax::TypeSpecifier {
1863       ty: syntax::TypeSpecifierNonArray::Vec3,
1864       array_specifier: None,
1865     },
1866     identifiers: syntax::NonEmpty(vec![syntax::ArrayedIdentifier::new(
1867       "b",
1868       Some(syntax::ArraySpecifier::Unsized),
1869     )]),
1870   };
1871   let f2 = syntax::StructFieldSpecifier {
1872     qualifier: None,
1873     ty: syntax::TypeSpecifier {
1874       ty: syntax::TypeSpecifierNonArray::TypeName("foo".into()),
1875       array_specifier: None,
1876     },
1877     identifiers: syntax::NonEmpty(vec!["c".into(), "d".into()]),
1878   };
1879   let expected = syntax::Declaration::Block(syntax::Block {
1880     qualifier: qual,
1881     name: "UniformBlockTest".into(),
1882     fields: vec![f0, f1, f2],
1883     identifier: None,
1884   });
1885 
1886   assert_eq!(
1887     declaration("buffer UniformBlockTest { float a; vec3 b[]; foo c, d; };"),
1888     Ok(("", expected.clone()))
1889   );
1890   assert_eq!(declaration("buffer   \nUniformBlockTest\n {\n \t float   a  \n; \nvec3 b   [   ]\n; foo \nc\n, \nd\n;\n }\n\t\n\t\t \t;"), Ok(("", expected)));
1891 }
1892 
1893 #[test]
parse_selection_statement_if()1894 fn parse_selection_statement_if() {
1895   let cond = syntax::Expr::Binary(
1896     syntax::BinaryOp::LT,
1897     Box::new(syntax::Expr::Variable("foo".into())),
1898     Box::new(syntax::Expr::IntConst(10)),
1899   );
1900   let ret = Box::new(syntax::Expr::BoolConst(false));
1901   let st = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::Jump(
1902     syntax::JumpStatement::Return(Some(ret)),
1903   )));
1904   let body = syntax::Statement::Compound(Box::new(syntax::CompoundStatement {
1905     statement_list: vec![st],
1906   }));
1907   let rest = syntax::SelectionRestStatement::Statement(Box::new(body));
1908   let expected = syntax::SelectionStatement {
1909     cond: Box::new(cond),
1910     rest,
1911   };
1912 
1913   assert_eq!(
1914     selection_statement("if (foo < 10) { return false; }K"),
1915     Ok(("K", expected.clone()))
1916   );
1917   assert_eq!(
1918     selection_statement("if \n(foo<10\n) \t{return false;}K"),
1919     Ok(("K", expected))
1920   );
1921 }
1922 
1923 #[test]
parse_selection_statement_if_else()1924 fn parse_selection_statement_if_else() {
1925   let cond = syntax::Expr::Binary(
1926     syntax::BinaryOp::LT,
1927     Box::new(syntax::Expr::Variable("foo".into())),
1928     Box::new(syntax::Expr::IntConst(10)),
1929   );
1930   let if_ret = Box::new(syntax::Expr::FloatConst(0.));
1931   let if_st = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::Jump(
1932     syntax::JumpStatement::Return(Some(if_ret)),
1933   )));
1934   let if_body = syntax::Statement::Compound(Box::new(syntax::CompoundStatement {
1935     statement_list: vec![if_st],
1936   }));
1937   let else_ret = Box::new(syntax::Expr::Variable("foo".into()));
1938   let else_st = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::Jump(
1939     syntax::JumpStatement::Return(Some(else_ret)),
1940   )));
1941   let else_body = syntax::Statement::Compound(Box::new(syntax::CompoundStatement {
1942     statement_list: vec![else_st],
1943   }));
1944   let rest = syntax::SelectionRestStatement::Else(Box::new(if_body), Box::new(else_body));
1945   let expected = syntax::SelectionStatement {
1946     cond: Box::new(cond),
1947     rest,
1948   };
1949 
1950   assert_eq!(
1951     selection_statement("if (foo < 10) { return 0.f; } else { return foo; }"),
1952     Ok(("", expected.clone()))
1953   );
1954   assert_eq!(
1955     selection_statement("if \n(foo<10\n) \t{return 0.f\t;\n\n}\n else{\n\t return foo   ;}"),
1956     Ok(("", expected))
1957   );
1958 }
1959 
1960 #[test]
parse_switch_statement_empty()1961 fn parse_switch_statement_empty() {
1962   let head = Box::new(syntax::Expr::Variable("foo".into()));
1963   let expected = syntax::SwitchStatement {
1964     head,
1965     body: Vec::new(),
1966   };
1967 
1968   assert_eq!(
1969     switch_statement("switch (foo) {}"),
1970     Ok(("", expected.clone()))
1971   );
1972   assert_eq!(
1973     switch_statement("switch(foo){}"),
1974     Ok(("", expected.clone()))
1975   );
1976   assert_eq!(
1977     switch_statement("switch\n\n (  foo  \t   \n) { \n\n   }"),
1978     Ok(("", expected))
1979   );
1980 }
1981 
1982 #[test]
parse_switch_statement_cases()1983 fn parse_switch_statement_cases() {
1984   let head = Box::new(syntax::Expr::Variable("foo".into()));
1985   let case0 = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::CaseLabel(
1986     syntax::CaseLabel::Case(Box::new(syntax::Expr::IntConst(0))),
1987   )));
1988   let case1 = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::CaseLabel(
1989     syntax::CaseLabel::Case(Box::new(syntax::Expr::IntConst(1))),
1990   )));
1991   let ret = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::Jump(
1992     syntax::JumpStatement::Return(Some(Box::new(syntax::Expr::UIntConst(12)))),
1993   )));
1994   let expected = syntax::SwitchStatement {
1995     head,
1996     body: vec![case0, case1, ret],
1997   };
1998 
1999   assert_eq!(
2000     switch_statement("switch (foo) { case 0: case 1: return 12u; }"),
2001     Ok(("", expected.clone()))
2002   );
2003 }
2004 
2005 #[test]
parse_case_label_def()2006 fn parse_case_label_def() {
2007   assert_eq!(case_label("default:"), Ok(("", syntax::CaseLabel::Def)));
2008   assert_eq!(case_label("default   :"), Ok(("", syntax::CaseLabel::Def)));
2009 }
2010 
2011 #[test]
parse_case_label()2012 fn parse_case_label() {
2013   let expected = syntax::CaseLabel::Case(Box::new(syntax::Expr::IntConst(3)));
2014 
2015   assert_eq!(case_label("case 3:"), Ok(("", expected.clone())));
2016   assert_eq!(case_label("case\n\t 3   :"), Ok(("", expected)));
2017 }
2018 
2019 #[test]
parse_iteration_statement_while_empty()2020 fn parse_iteration_statement_while_empty() {
2021   let cond = syntax::Condition::Expr(Box::new(syntax::Expr::Binary(
2022     syntax::BinaryOp::GTE,
2023     Box::new(syntax::Expr::Variable("a".into())),
2024     Box::new(syntax::Expr::Variable("b".into())),
2025   )));
2026   let st = syntax::Statement::Compound(Box::new(syntax::CompoundStatement {
2027     statement_list: Vec::new(),
2028   }));
2029   let expected = syntax::IterationStatement::While(cond, Box::new(st));
2030 
2031   assert_eq!(
2032     iteration_statement("while (a >= b) {}"),
2033     Ok(("", expected.clone()))
2034   );
2035   assert_eq!(
2036     iteration_statement("while(a>=b){}"),
2037     Ok(("", expected.clone()))
2038   );
2039   assert_eq!(
2040     iteration_statement("while (  a >=\n\tb  )\t  {   \n}"),
2041     Ok(("", expected))
2042   );
2043 }
2044 
2045 #[test]
parse_iteration_statement_do_while_empty()2046 fn parse_iteration_statement_do_while_empty() {
2047   let st = syntax::Statement::Compound(Box::new(syntax::CompoundStatement {
2048     statement_list: Vec::new(),
2049   }));
2050   let cond = Box::new(syntax::Expr::Binary(
2051     syntax::BinaryOp::GTE,
2052     Box::new(syntax::Expr::Variable("a".into())),
2053     Box::new(syntax::Expr::Variable("b".into())),
2054   ));
2055   let expected = syntax::IterationStatement::DoWhile(Box::new(st), cond);
2056 
2057   assert_eq!(
2058     iteration_statement("do {} while (a >= b);"),
2059     Ok(("", expected.clone()))
2060   );
2061   assert_eq!(
2062     iteration_statement("do{}while(a>=b);"),
2063     Ok(("", expected.clone()))
2064   );
2065   assert_eq!(
2066     iteration_statement("do \n {\n} while (  a >=\n\tb  )\t  \n;"),
2067     Ok(("", expected))
2068   );
2069 }
2070 
2071 #[test]
parse_iteration_statement_for_empty()2072 fn parse_iteration_statement_for_empty() {
2073   let init = syntax::ForInitStatement::Declaration(Box::new(
2074     syntax::Declaration::InitDeclaratorList(syntax::InitDeclaratorList {
2075       head: syntax::SingleDeclaration {
2076         ty: syntax::FullySpecifiedType {
2077           qualifier: None,
2078           ty: syntax::TypeSpecifier {
2079             ty: syntax::TypeSpecifierNonArray::Float,
2080             array_specifier: None,
2081           },
2082         },
2083         name: Some("i".into()),
2084         array_specifier: None,
2085         initializer: Some(syntax::Initializer::Simple(Box::new(
2086           syntax::Expr::FloatConst(0.),
2087         ))),
2088       },
2089       tail: Vec::new(),
2090     }),
2091   ));
2092   let rest = syntax::ForRestStatement {
2093     condition: Some(syntax::Condition::Expr(Box::new(syntax::Expr::Binary(
2094       syntax::BinaryOp::LTE,
2095       Box::new(syntax::Expr::Variable("i".into())),
2096       Box::new(syntax::Expr::FloatConst(10.)),
2097     )))),
2098     post_expr: Some(Box::new(syntax::Expr::Unary(
2099       syntax::UnaryOp::Inc,
2100       Box::new(syntax::Expr::Variable("i".into())),
2101     ))),
2102   };
2103   let st = syntax::Statement::Compound(Box::new(syntax::CompoundStatement {
2104     statement_list: Vec::new(),
2105   }));
2106   let expected = syntax::IterationStatement::For(init, rest, Box::new(st));
2107 
2108   assert_eq!(
2109     iteration_statement("for (float i = 0.f; i <= 10.f; ++i) {}"),
2110     Ok(("", expected.clone()))
2111   );
2112   assert_eq!(
2113     iteration_statement("for(float i=0.f;i<=10.f;++i){}"),
2114     Ok(("", expected.clone()))
2115   );
2116   assert_eq!(
2117     iteration_statement("for\n\t (  \t\n\nfloat \ni \t=\n0.f\n;\ni\t<=  10.f; \n++i\n)\n{\n}"),
2118     Ok(("", expected))
2119   );
2120 }
2121 
2122 #[test]
parse_jump_continue()2123 fn parse_jump_continue() {
2124   assert_eq!(
2125     jump_statement("continue;"),
2126     Ok(("", syntax::JumpStatement::Continue))
2127   );
2128 }
2129 
2130 #[test]
parse_jump_break()2131 fn parse_jump_break() {
2132   assert_eq!(
2133     jump_statement("break;"),
2134     Ok(("", syntax::JumpStatement::Break))
2135   );
2136 }
2137 
2138 #[test]
parse_jump_return()2139 fn parse_jump_return() {
2140   let expected = syntax::JumpStatement::Return(Some(Box::new(syntax::Expr::IntConst(3))));
2141   assert_eq!(jump_statement("return 3;"), Ok(("", expected)));
2142 }
2143 
2144 #[test]
parse_jump_empty_return()2145 fn parse_jump_empty_return() {
2146   let expected = syntax::SimpleStatement::Jump(syntax::JumpStatement::Return(None));
2147   assert_eq!(simple_statement("return;"), Ok(("", expected)));
2148 }
2149 
2150 #[test]
parse_jump_discard()2151 fn parse_jump_discard() {
2152   assert_eq!(
2153     jump_statement("discard;"),
2154     Ok(("", syntax::JumpStatement::Discard))
2155   );
2156 }
2157 
2158 #[test]
parse_simple_statement_return()2159 fn parse_simple_statement_return() {
2160   let e = syntax::Expr::BoolConst(false);
2161   let expected = syntax::SimpleStatement::Jump(syntax::JumpStatement::Return(Some(Box::new(e))));
2162 
2163   assert_eq!(simple_statement("return false;"), Ok(("", expected)));
2164 }
2165 
2166 #[test]
parse_compound_statement_empty()2167 fn parse_compound_statement_empty() {
2168   let expected = syntax::CompoundStatement {
2169     statement_list: Vec::new(),
2170   };
2171 
2172   assert_eq!(compound_statement("{}"), Ok(("", expected)));
2173 }
2174 
2175 #[test]
parse_compound_statement()2176 fn parse_compound_statement() {
2177   let st0 = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::Selection(
2178     syntax::SelectionStatement {
2179       cond: Box::new(syntax::Expr::BoolConst(true)),
2180       rest: syntax::SelectionRestStatement::Statement(Box::new(syntax::Statement::Compound(
2181         Box::new(syntax::CompoundStatement {
2182           statement_list: Vec::new(),
2183         }),
2184       ))),
2185     },
2186   )));
2187   let st1 = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::Declaration(
2188     syntax::Declaration::InitDeclaratorList(syntax::InitDeclaratorList {
2189       head: syntax::SingleDeclaration {
2190         ty: syntax::FullySpecifiedType {
2191           qualifier: None,
2192           ty: syntax::TypeSpecifier {
2193             ty: syntax::TypeSpecifierNonArray::ISampler3D,
2194             array_specifier: None,
2195           },
2196         },
2197         name: Some("x".into()),
2198         array_specifier: None,
2199         initializer: None,
2200       },
2201       tail: Vec::new(),
2202     }),
2203   )));
2204   let st2 = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::Jump(
2205     syntax::JumpStatement::Return(Some(Box::new(syntax::Expr::IntConst(42)))),
2206   )));
2207   let expected = syntax::CompoundStatement {
2208     statement_list: vec![st0, st1, st2],
2209   };
2210 
2211   assert_eq!(
2212     compound_statement("{ if (true) {} isampler3D x; return 42 ; }"),
2213     Ok(("", expected.clone()))
2214   );
2215   assert_eq!(
2216     compound_statement("{if(true){}isampler3D x;return 42;}"),
2217     Ok(("", expected))
2218   );
2219 }
2220 
2221 #[test]
parse_function_definition()2222 fn parse_function_definition() {
2223   let rt = syntax::FullySpecifiedType {
2224     qualifier: None,
2225     ty: syntax::TypeSpecifier {
2226       ty: syntax::TypeSpecifierNonArray::IImage2DArray,
2227       array_specifier: None,
2228     },
2229   };
2230   let fp = syntax::FunctionPrototype {
2231     ty: rt,
2232     name: "foo".into(),
2233     parameters: Vec::new(),
2234   };
2235   let st0 = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::Jump(
2236     syntax::JumpStatement::Return(Some(Box::new(syntax::Expr::Variable("bar".into())))),
2237   )));
2238   let expected = syntax::FunctionDefinition {
2239     prototype: fp,
2240     statement: syntax::CompoundStatement {
2241       statement_list: vec![st0],
2242     },
2243   };
2244 
2245   assert_eq!(
2246     function_definition("iimage2DArray foo() { return bar; }"),
2247     Ok(("", expected.clone()))
2248   );
2249   assert_eq!(
2250     function_definition("iimage2DArray \tfoo\n()\n \n{\n return \nbar\n;}"),
2251     Ok(("", expected.clone()))
2252   );
2253   assert_eq!(
2254     function_definition("iimage2DArray foo(){return bar;}"),
2255     Ok(("", expected))
2256   );
2257 }
2258 
2259 #[test]
parse_buffer_block_0()2260 fn parse_buffer_block_0() {
2261   let src = include_str!("../data/tests/buffer_block_0.glsl");
2262   let main_fn = syntax::ExternalDeclaration::FunctionDefinition(syntax::FunctionDefinition {
2263     prototype: syntax::FunctionPrototype {
2264       ty: syntax::FullySpecifiedType {
2265         qualifier: None,
2266         ty: syntax::TypeSpecifier {
2267           ty: syntax::TypeSpecifierNonArray::Void,
2268           array_specifier: None,
2269         },
2270       },
2271       name: "main".into(),
2272       parameters: Vec::new(),
2273     },
2274     statement: syntax::CompoundStatement {
2275       statement_list: Vec::new(),
2276     },
2277   });
2278   let buffer_block =
2279     syntax::ExternalDeclaration::Declaration(syntax::Declaration::Block(syntax::Block {
2280       qualifier: syntax::TypeQualifier {
2281         qualifiers: syntax::NonEmpty(vec![syntax::TypeQualifierSpec::Storage(
2282           syntax::StorageQualifier::Buffer,
2283         )]),
2284       },
2285       name: "Foo".into(),
2286       fields: vec![syntax::StructFieldSpecifier {
2287         qualifier: None,
2288         ty: syntax::TypeSpecifier {
2289           ty: syntax::TypeSpecifierNonArray::TypeName("char".into()),
2290           array_specifier: None,
2291         },
2292         identifiers: syntax::NonEmpty(vec![syntax::ArrayedIdentifier::new(
2293           "tiles",
2294           Some(syntax::ArraySpecifier::Unsized),
2295         )]),
2296       }],
2297       identifier: Some("main_tiles".into()),
2298     }));
2299   let expected = syntax::TranslationUnit(syntax::NonEmpty(vec![buffer_block, main_fn]));
2300 
2301   assert_eq!(translation_unit(src), Ok(("", expected)));
2302 }
2303 
2304 #[test]
parse_layout_buffer_block_0()2305 fn parse_layout_buffer_block_0() {
2306   let src = include_str!("../data/tests/layout_buffer_block_0.glsl");
2307   let layout = syntax::LayoutQualifier {
2308     ids: syntax::NonEmpty(vec![
2309       syntax::LayoutQualifierSpec::Identifier(
2310         "set".into(),
2311         Some(Box::new(syntax::Expr::IntConst(0))),
2312       ),
2313       syntax::LayoutQualifierSpec::Identifier(
2314         "binding".into(),
2315         Some(Box::new(syntax::Expr::IntConst(0))),
2316       ),
2317     ]),
2318   };
2319   let type_qual = syntax::TypeQualifier {
2320     qualifiers: syntax::NonEmpty(vec![
2321       syntax::TypeQualifierSpec::Layout(layout),
2322       syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Buffer),
2323     ]),
2324   };
2325   let block = syntax::ExternalDeclaration::Declaration(syntax::Declaration::Block(syntax::Block {
2326     qualifier: type_qual,
2327     name: "Foo".into(),
2328     fields: vec![syntax::StructFieldSpecifier {
2329       qualifier: None,
2330       ty: syntax::TypeSpecifier {
2331         ty: syntax::TypeSpecifierNonArray::TypeName("char".into()),
2332         array_specifier: None,
2333       },
2334       identifiers: syntax::NonEmpty(vec!["a".into()]),
2335     }],
2336     identifier: Some("foo".into()),
2337   }));
2338 
2339   let expected = syntax::TranslationUnit(syntax::NonEmpty(vec![block]));
2340 
2341   assert_eq!(translation_unit(src), Ok(("", expected)));
2342 }
2343 
2344 #[test]
parse_pp_space0()2345 fn parse_pp_space0() {
2346   assert_eq!(pp_space0("   \\\n  "), Ok(("", "   \\\n  ")));
2347   assert_eq!(pp_space0(""), Ok(("", "")));
2348 }
2349 
2350 #[test]
parse_pp_version_number()2351 fn parse_pp_version_number() {
2352   assert_eq!(pp_version_number("450"), Ok(("", 450)));
2353 }
2354 
2355 #[test]
parse_pp_version_profile()2356 fn parse_pp_version_profile() {
2357   assert_eq!(
2358     pp_version_profile("core"),
2359     Ok(("", syntax::PreprocessorVersionProfile::Core))
2360   );
2361   assert_eq!(
2362     pp_version_profile("compatibility"),
2363     Ok(("", syntax::PreprocessorVersionProfile::Compatibility))
2364   );
2365   assert_eq!(
2366     pp_version_profile("es"),
2367     Ok(("", syntax::PreprocessorVersionProfile::ES))
2368   );
2369 }
2370 
2371 #[test]
parse_pp_version()2372 fn parse_pp_version() {
2373   assert_eq!(
2374     preprocessor("#version 450\n"),
2375     Ok((
2376       "",
2377       syntax::Preprocessor::Version(syntax::PreprocessorVersion {
2378         version: 450,
2379         profile: None,
2380       })
2381     ))
2382   );
2383 
2384   assert_eq!(
2385     preprocessor("#version 450 core\n"),
2386     Ok((
2387       "",
2388       syntax::Preprocessor::Version(syntax::PreprocessorVersion {
2389         version: 450,
2390         profile: Some(syntax::PreprocessorVersionProfile::Core)
2391       })
2392     ))
2393   );
2394 }
2395 
2396 #[test]
parse_pp_version_newline()2397 fn parse_pp_version_newline() {
2398   assert_eq!(
2399     preprocessor("#version 450\n"),
2400     Ok((
2401       "",
2402       syntax::Preprocessor::Version(syntax::PreprocessorVersion {
2403         version: 450,
2404         profile: None,
2405       })
2406     ))
2407   );
2408 
2409   assert_eq!(
2410     preprocessor("#version 450 core\n"),
2411     Ok((
2412       "",
2413       syntax::Preprocessor::Version(syntax::PreprocessorVersion {
2414         version: 450,
2415         profile: Some(syntax::PreprocessorVersionProfile::Core)
2416       })
2417     ))
2418   );
2419 }
2420 
2421 #[test]
parse_pp_define()2422 fn parse_pp_define() {
2423   let expect = |v: &str| {
2424     Ok((
2425       "",
2426       syntax::Preprocessor::Define(syntax::PreprocessorDefine::ObjectLike {
2427         ident: "test".into(),
2428         value: v.to_owned(),
2429       }),
2430     ))
2431   };
2432 
2433   assert_eq!(preprocessor("#define test 1.0"), expect("1.0"));
2434   assert_eq!(preprocessor("#define test \\\n   1.0"), expect("1.0"));
2435   assert_eq!(preprocessor("#define test 1.0\n"), expect("1.0"));
2436 
2437   assert_eq!(
2438     preprocessor("#define test123 .0f\n"),
2439     Ok((
2440       "",
2441       syntax::Preprocessor::Define(syntax::PreprocessorDefine::ObjectLike {
2442         ident: "test123".into(),
2443         value: ".0f".to_owned()
2444       })
2445     ))
2446   );
2447 
2448   assert_eq!(
2449     preprocessor("#define test 1\n"),
2450     Ok((
2451       "",
2452       syntax::Preprocessor::Define(syntax::PreprocessorDefine::ObjectLike {
2453         ident: "test".into(),
2454         value: "1".to_owned()
2455       })
2456     ))
2457   );
2458 }
2459 
2460 #[test]
parse_pp_define_with_args()2461 fn parse_pp_define_with_args() {
2462   let expected = syntax::Preprocessor::Define(syntax::PreprocessorDefine::FunctionLike {
2463     ident: "add".into(),
2464     args: vec![
2465       syntax::Identifier::new("x").unwrap(),
2466       syntax::Identifier::new("y").unwrap(),
2467     ],
2468     value: "(x + y)".to_owned(),
2469   });
2470 
2471   assert_eq!(
2472     preprocessor("#define \\\n add(x, y) \\\n (x + y)"),
2473     Ok(("", expected.clone()))
2474   );
2475 
2476   assert_eq!(
2477     preprocessor("#define \\\n add(  x, y  ) \\\n (x + y)"),
2478     Ok(("", expected))
2479   );
2480 }
2481 
2482 #[test]
parse_pp_define_multiline()2483 fn parse_pp_define_multiline() {
2484   assert_eq!(
2485     preprocessor(
2486       r#"#define foo \
2487        32"#
2488     ),
2489     Ok((
2490       "",
2491       syntax::Preprocessor::Define(syntax::PreprocessorDefine::ObjectLike {
2492         ident: "foo".into(),
2493         value: "32".to_owned(),
2494       })
2495     ))
2496   );
2497 }
2498 
2499 #[test]
parse_pp_else()2500 fn parse_pp_else() {
2501   assert_eq!(
2502     preprocessor("#    else\n"),
2503     Ok(("", syntax::Preprocessor::Else))
2504   );
2505 }
2506 
2507 #[test]
parse_pp_elseif()2508 fn parse_pp_elseif() {
2509   assert_eq!(
2510     preprocessor("#   elseif \\\n42\n"),
2511     Ok((
2512       "",
2513       syntax::Preprocessor::ElseIf(syntax::PreprocessorElseIf {
2514         condition: "42".to_owned()
2515       })
2516     ))
2517   );
2518 }
2519 
2520 #[test]
parse_pp_endif()2521 fn parse_pp_endif() {
2522   assert_eq!(
2523     preprocessor("#\\\nendif"),
2524     Ok(("", syntax::Preprocessor::EndIf))
2525   );
2526 }
2527 
2528 #[test]
parse_pp_error()2529 fn parse_pp_error() {
2530   assert_eq!(
2531     preprocessor("#error \\\n     some message"),
2532     Ok((
2533       "",
2534       syntax::Preprocessor::Error(syntax::PreprocessorError {
2535         message: "some message".to_owned()
2536       })
2537     ))
2538   );
2539 }
2540 
2541 #[test]
parse_pp_if()2542 fn parse_pp_if() {
2543   assert_eq!(
2544     preprocessor("# \\\nif 42"),
2545     Ok((
2546       "",
2547       syntax::Preprocessor::If(syntax::PreprocessorIf {
2548         condition: "42".to_owned()
2549       })
2550     ))
2551   );
2552 }
2553 
2554 #[test]
parse_pp_ifdef()2555 fn parse_pp_ifdef() {
2556   assert_eq!(
2557     preprocessor("#ifdef       FOO\n"),
2558     Ok((
2559       "",
2560       syntax::Preprocessor::IfDef(syntax::PreprocessorIfDef {
2561         ident: syntax::Identifier("FOO".to_owned())
2562       })
2563     ))
2564   );
2565 }
2566 
2567 #[test]
parse_pp_ifndef()2568 fn parse_pp_ifndef() {
2569   assert_eq!(
2570     preprocessor("#\\\nifndef \\\n   FOO\n"),
2571     Ok((
2572       "",
2573       syntax::Preprocessor::IfNDef(syntax::PreprocessorIfNDef {
2574         ident: syntax::Identifier("FOO".to_owned())
2575       })
2576     ))
2577   );
2578 }
2579 
2580 #[test]
parse_pp_include()2581 fn parse_pp_include() {
2582   assert_eq!(
2583     preprocessor("#include <filename>\n"),
2584     Ok((
2585       "",
2586       syntax::Preprocessor::Include(syntax::PreprocessorInclude {
2587         path: syntax::Path::Absolute("filename".to_owned())
2588       })
2589     ))
2590   );
2591 
2592   assert_eq!(
2593     preprocessor("#include \\\n\"filename\"\n"),
2594     Ok((
2595       "",
2596       syntax::Preprocessor::Include(syntax::PreprocessorInclude {
2597         path: syntax::Path::Relative("filename".to_owned())
2598       })
2599     ))
2600   );
2601 }
2602 
2603 #[test]
parse_pp_line()2604 fn parse_pp_line() {
2605   assert_eq!(
2606     preprocessor("#   line \\\n2\n"),
2607     Ok((
2608       "",
2609       syntax::Preprocessor::Line(syntax::PreprocessorLine {
2610         line: 2,
2611         source_string_number: None,
2612       })
2613     ))
2614   );
2615 
2616   assert_eq!(
2617     preprocessor("#line 2 \\\n 4\n"),
2618     Ok((
2619       "",
2620       syntax::Preprocessor::Line(syntax::PreprocessorLine {
2621         line: 2,
2622         source_string_number: Some(4),
2623       })
2624     ))
2625   );
2626 }
2627 
2628 #[test]
parse_pp_pragma()2629 fn parse_pp_pragma() {
2630   assert_eq!(
2631     preprocessor("#\\\npragma  some   flag"),
2632     Ok((
2633       "",
2634       syntax::Preprocessor::Pragma(syntax::PreprocessorPragma {
2635         command: "some   flag".to_owned()
2636       })
2637     ))
2638   );
2639 }
2640 
2641 #[test]
parse_pp_undef()2642 fn parse_pp_undef() {
2643   assert_eq!(
2644     preprocessor("# undef \\\n FOO"),
2645     Ok((
2646       "",
2647       syntax::Preprocessor::Undef(syntax::PreprocessorUndef {
2648         name: syntax::Identifier("FOO".to_owned())
2649       })
2650     ))
2651   );
2652 }
2653 
2654 #[test]
parse_pp_extension_name()2655 fn parse_pp_extension_name() {
2656   assert_eq!(
2657     pp_extension_name("all"),
2658     Ok(("", syntax::PreprocessorExtensionName::All))
2659   );
2660   assert_eq!(
2661     pp_extension_name("GL_foobar_extension "),
2662     Ok((
2663       " ",
2664       syntax::PreprocessorExtensionName::Specific("GL_foobar_extension".to_owned())
2665     ))
2666   );
2667 }
2668 
2669 #[test]
parse_pp_extension_behavior()2670 fn parse_pp_extension_behavior() {
2671   assert_eq!(
2672     pp_extension_behavior("require"),
2673     Ok(("", syntax::PreprocessorExtensionBehavior::Require))
2674   );
2675   assert_eq!(
2676     pp_extension_behavior("enable"),
2677     Ok(("", syntax::PreprocessorExtensionBehavior::Enable))
2678   );
2679   assert_eq!(
2680     pp_extension_behavior("warn"),
2681     Ok(("", syntax::PreprocessorExtensionBehavior::Warn))
2682   );
2683   assert_eq!(
2684     pp_extension_behavior("disable"),
2685     Ok(("", syntax::PreprocessorExtensionBehavior::Disable))
2686   );
2687 }
2688 
2689 #[test]
parse_pp_extension()2690 fn parse_pp_extension() {
2691   assert_eq!(
2692     preprocessor("#extension all: require\n"),
2693     Ok((
2694       "",
2695       syntax::Preprocessor::Extension(syntax::PreprocessorExtension {
2696         name: syntax::PreprocessorExtensionName::All,
2697         behavior: Some(syntax::PreprocessorExtensionBehavior::Require)
2698       })
2699     ))
2700   );
2701 }
2702 
2703 #[test]
parse_dot_field_expr_array()2704 fn parse_dot_field_expr_array() {
2705   let src = "a[0].xyz;";
2706   let expected = syntax::Expr::Dot(
2707     Box::new(syntax::Expr::Bracket(
2708       Box::new(syntax::Expr::Variable("a".into())),
2709       syntax::ArraySpecifier::ExplicitlySized(Box::new(syntax::Expr::IntConst(0))),
2710     )),
2711     "xyz".into(),
2712   );
2713 
2714   assert_eq!(expr(src), Ok((";", expected)));
2715 }
2716 
2717 #[test]
parse_dot_field_expr_statement()2718 fn parse_dot_field_expr_statement() {
2719   let src = "vec3 v = smoothstep(vec3(border_width), vec3(0.0), v_barycenter).zyx;";
2720   let fun = syntax::FunIdentifier::Identifier("smoothstep".into());
2721   let args = vec![
2722     syntax::Expr::FunCall(
2723       syntax::FunIdentifier::Identifier("vec3".into()),
2724       vec![syntax::Expr::Variable("border_width".into())],
2725     ),
2726     syntax::Expr::FunCall(
2727       syntax::FunIdentifier::Identifier("vec3".into()),
2728       vec![syntax::Expr::DoubleConst(0.)],
2729     ),
2730     syntax::Expr::Variable("v_barycenter".into()),
2731   ];
2732   let ini = syntax::Initializer::Simple(Box::new(syntax::Expr::Dot(
2733     Box::new(syntax::Expr::FunCall(fun, args)),
2734     "zyx".into(),
2735   )));
2736   let sd = syntax::SingleDeclaration {
2737     ty: syntax::FullySpecifiedType {
2738       qualifier: None,
2739       ty: syntax::TypeSpecifier {
2740         ty: syntax::TypeSpecifierNonArray::Vec3,
2741         array_specifier: None,
2742       },
2743     },
2744     name: Some("v".into()),
2745     array_specifier: None,
2746     initializer: Some(ini),
2747   };
2748   let expected = syntax::Statement::Simple(Box::new(syntax::SimpleStatement::Declaration(
2749     syntax::Declaration::InitDeclaratorList(syntax::InitDeclaratorList {
2750       head: sd,
2751       tail: Vec::new(),
2752     }),
2753   )));
2754 
2755   assert_eq!(statement(src), Ok(("", expected)));
2756 }
2757 
2758 #[test]
parse_arrayed_identifier()2759 fn parse_arrayed_identifier() {
2760   let expected = syntax::ArrayedIdentifier::new("foo", syntax::ArraySpecifier::Unsized);
2761 
2762   assert_eq!(arrayed_identifier("foo[]"), Ok(("", expected.clone())));
2763   assert_eq!(arrayed_identifier("foo \t\n  [\n\t ]"), Ok(("", expected)));
2764 }
2765 
2766 #[test]
parse_nested_parens()2767 fn parse_nested_parens() {
2768   let start = std::time::Instant::now();
2769   parens_expr("((((((((1.0f))))))))").unwrap();
2770   let elapsed = start.elapsed();
2771   assert!(elapsed.as_millis() < 100, "{} ms", elapsed.as_millis());
2772 }
2773