From f91e95b22e4cde9537d58443a6f7fe8930451621 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Fri, 17 Sep 2021 18:24:01 -0700 Subject: [PATCH] [glsl-in]: Register new types as necessary during constant solving. --- src/front/glsl/constants.rs | 50 ++++++++++++++++++++++++------------- src/front/glsl/types.rs | 2 +- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/front/glsl/constants.rs b/src/front/glsl/constants.rs index 4d2a1a9008..e39a596217 100644 --- a/src/front/glsl/constants.rs +++ b/src/front/glsl/constants.rs @@ -6,7 +6,7 @@ use crate::{ #[derive(Debug)] pub struct ConstantSolver<'a> { - pub types: &'a Arena, + pub types: &'a mut Arena, pub expressions: &'a Arena, pub constants: &'a mut Arena, } @@ -53,8 +53,10 @@ pub enum ConstantSolvingError { InvalidBinaryOpArgs, #[error("Cannot apply math function to type")] InvalidMathArg, - #[error("Splat/swizzle type is not registered")] - DestinationTypeNotFound, + #[error("Splat is defined only on scalar values")] + SplatScalarOnly, + #[error("Can only swizzle vector constants")] + SwizzleVectorOnly, #[error("Not implemented: {0}")] NotImplemented(String), } @@ -81,14 +83,19 @@ impl<'a> ConstantSolver<'a> { let ty = match self.constants[value_constant].inner { ConstantInner::Scalar { ref value, width } => { let kind = value.scalar_kind(); - self.types - .fetch_if(|t| t.inner == crate::TypeInner::Vector { size, kind, width }) + self.types.fetch_or_append( + Type { + name: None, + inner: TypeInner::Vector { size, kind, width }, + }, + span, + ) + } + ConstantInner::Composite { .. } => { + return Err(ConstantSolvingError::SplatScalarOnly); } - ConstantInner::Composite { .. } => None, }; - //TODO: register the new type if needed - let ty = ty.ok_or(ConstantSolvingError::DestinationTypeNotFound)?; Ok(self.constants.fetch_or_append( Constant { name: None, @@ -108,7 +115,9 @@ impl<'a> ConstantSolver<'a> { } => { let src_constant = self.solve(src_vector)?; let (ty, src_components) = match self.constants[src_constant].inner { - ConstantInner::Scalar { .. } => (None, &[][..]), + ConstantInner::Scalar { .. } => { + return Err(ConstantSolvingError::SwizzleVectorOnly); + } ConstantInner::Composite { ty, components: ref src_components, @@ -118,16 +127,21 @@ impl<'a> ConstantSolver<'a> { kind, width, } => { - let dst_ty = self.types.fetch_if(|t| { - t.inner == crate::TypeInner::Vector { size, kind, width } - }); + let dst_ty = self.types.fetch_or_append( + Type { + name: None, + inner: crate::TypeInner::Vector { size, kind, width }, + }, + span, + ); (dst_ty, &src_components[..]) } - _ => (None, &[][..]), + _ => { + return Err(ConstantSolvingError::SwizzleVectorOnly); + } }, }; - //TODO: register the new type if needed - let ty = ty.ok_or(ConstantSolvingError::DestinationTypeNotFound)?; + let components = pattern .iter() .map(|&sc| src_components[sc as usize]) @@ -604,7 +618,7 @@ mod tests { ); let mut solver = ConstantSolver { - types: &types, + types: &mut types, expressions: &expressions, constants: &mut constants, }; @@ -684,7 +698,7 @@ mod tests { ); let mut solver = ConstantSolver { - types: &Arena::new(), + types: &mut Arena::new(), expressions: &expressions, constants: &mut constants, }; @@ -815,7 +829,7 @@ mod tests { ); let mut solver = ConstantSolver { - types: &types, + types: &mut types, expressions: &expressions, constants: &mut constants, }; diff --git a/src/front/glsl/types.rs b/src/front/glsl/types.rs index 803901764c..dd0942db9c 100644 --- a/src/front/glsl/types.rs +++ b/src/front/glsl/types.rs @@ -242,7 +242,7 @@ impl Parser { meta: Span, ) -> Result> { let mut solver = ConstantSolver { - types: &self.module.types, + types: &mut self.module.types, expressions: &ctx.expressions, constants: &mut self.module.constants, };