Skip to content

Commit

Permalink
glsl-in: Update initializer list type when parsing (#2066)
Browse files Browse the repository at this point in the history
Previously when parsing an initializer list, the type passed to
`parse_initializer` was not updated to reflect the child type, this
caused implicit conversions to not work and nested initializer lists to
not be allowed.
  • Loading branch information
JCapucho committed Oct 5, 2022
1 parent 0f26e5c commit e07fd98
Showing 1 changed file with 53 additions and 2 deletions.
55 changes: 53 additions & 2 deletions src/front/glsl/parser/declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,55 @@ use crate::{

use super::{DeclarationContext, ParsingContext, Result};

/// Helper method used to retrieve the child type of `ty` at
/// index `i`.
///
/// # Note
///
/// Does not check if the index is valid and returns the same type
/// when indexing out-of-bounds a struct or indexing a non indexable
/// type.
fn element_or_member_type(
ty: Handle<Type>,
i: usize,
types: &mut crate::UniqueArena<Type>,
) -> Handle<Type> {
match types[ty].inner {
// The child type of a vector is a scalar of the same kind and width
TypeInner::Vector { kind, width, .. } => types.insert(
Type {
name: None,
inner: TypeInner::Scalar { kind, width },
},
Default::default(),
),
// The child type of a matrix is a vector of floats with the same
// width and the size of the matrix rows.
TypeInner::Matrix { rows, width, .. } => types.insert(
Type {
name: None,
inner: TypeInner::Vector {
size: rows,
kind: ScalarKind::Float,
width,
},
},
Default::default(),
),
// The child type of an array is the base type of the array
TypeInner::Array { base, .. } => base,
// The child type of a struct at index `i` is the type of it's
// member at that same index.
//
// In case the index is out of bounds the same type is returned
TypeInner::Struct { ref members, .. } => {
members.get(i).map(|member| member.ty).unwrap_or(ty)
}
// The type isn't indexable, the same type is returned
_ => ty,
}
}

impl<'source> ParsingContext<'source> {
pub fn parse_external_declaration(
&mut self,
Expand Down Expand Up @@ -68,8 +117,10 @@ impl<'source> ParsingContext<'source> {
// initializer_list
let mut components = Vec::new();
loop {
// TODO: Change type
components.push(self.parse_initializer(parser, ty, ctx, body)?.0);
// The type expected to be parsed inside the initializer list
let new_ty = element_or_member_type(ty, components.len(), &mut parser.module.types);

components.push(self.parse_initializer(parser, new_ty, ctx, body)?.0);

let token = self.bump(parser)?;
match token.value {
Expand Down

0 comments on commit e07fd98

Please sign in to comment.