add support for ConstantComposite

This commit is contained in:
Timo de Kort 2020-03-27 00:58:09 +01:00 committed by Dzmitry Malyshau
parent f09f87bb25
commit 1a1f6a47b0
4 changed files with 85 additions and 40 deletions

View File

@ -403,29 +403,7 @@ impl<W: Write> Writer<W> {
}
}
crate::Expression::Constant(handle) => {
let kind = match module.constants[handle].inner {
crate::ConstantInner::Sint(value) => {
write!(self.out, "{}", value)?;
crate::ScalarKind::Sint
}
crate::ConstantInner::Uint(value) => {
write!(self.out, "{}", value)?;
crate::ScalarKind::Uint
}
crate::ConstantInner::Float(value) => {
write!(self.out, "{}", value)?;
if value.fract() == 0.0 {
self.out.write_str(".0")?;
}
crate::ScalarKind::Float
}
crate::ConstantInner::Bool(value) => {
write!(self.out, "{}", value)?;
crate::ScalarKind::Bool
}
};
let width = 32; //TODO: not sure how to get that...
Ok(MaybeOwned::Owned(crate::TypeInner::Scalar { kind, width }))
self.put_constant(handle, module)
}
crate::Expression::Compose { ty, ref components } => {
let inner = &module.types[ty].inner;
@ -601,6 +579,46 @@ impl<W: Write> Writer<W> {
}
}
fn put_constant<'a>(
&mut self,
handle: Handle<crate::Constant>,
module: &'a crate::Module,
) -> Result<MaybeOwned<'a, crate::TypeInner>, Error> {
let constant = &module.constants[handle];
let ty = &module.types[constant.ty];
match constant.inner {
crate::ConstantInner::Sint(value) => {
write!(self.out, "{}", value)?;
}
crate::ConstantInner::Uint(value) => {
write!(self.out, "{}", value)?;
}
crate::ConstantInner::Float(value) => {
write!(self.out, "{}", value)?;
if value.fract() == 0.0 {
self.out.write_str(".0")?;
}
}
crate::ConstantInner::Bool(value) => {
write!(self.out, "{}", value)?;
}
crate::ConstantInner::Composite(ref constituents) => {
let ty_name = ty.name.or_index(constant.ty);
write!(self.out, "{}(", ty_name)?;
for (i, handle) in constituents.iter().enumerate() {
if i != 0 {
write!(self.out, ", ")?;
}
self.put_constant(*handle, module)?;
}
write!(self.out, ")")?;
}
}
Ok(MaybeOwned::Borrowed(&ty.inner))
}
fn put_statement<'a>(
&mut self,
level: Level,

View File

@ -715,6 +715,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
Op::TypeSampledImage => self.parse_type_sampled_image(inst),
Op::TypeSampler => self.parse_type_sampler(inst, &mut module),
Op::Constant | Op::SpecConstant => self.parse_constant(inst, &mut module),
Op::ConstantComposite => self.parse_composite_constant(inst, &mut module),
Op::Variable => self.parse_variable(inst, &mut module),
Op::Function => self.parse_function(inst, &mut module),
_ => Err(Error::UnsupportedInstruction(self.state, inst.op)), //TODO
@ -1305,6 +1306,42 @@ impl<I: Iterator<Item = u32>> Parser<I> {
Ok(())
}
fn parse_composite_constant(
&mut self,
inst: Instruction,
module: &mut crate::Module,
) -> Result<(), Error> {
self.switch(ModuleState::Type, inst.op)?;
inst.expect_at_least(3)?;
let type_id = self.next()?;
let type_lookup = self.lookup_type.lookup(type_id)?;
let ty = type_lookup.handle;
let id = self.next()?;
let constituents_count = inst.wc - 3;
let mut constituents = Vec::with_capacity(constituents_count as usize);
for _ in 0..constituents_count {
let constituent_id = self.next()?;
let constant = self.lookup_constant.lookup(constituent_id)?;
constituents.push(constant.handle);
}
self.lookup_constant.insert(id, LookupConstant {
handle: module.constants.append(crate::Constant {
name: self.future_decor
.remove(&id)
.and_then(|dec|dec.name),
specialization: None,
inner: crate::ConstantInner::Composite(constituents),
ty
}),
type_id
});
Ok(())
}
fn parse_variable(
&mut self,
inst: Instruction,

View File

@ -404,16 +404,16 @@ impl Parser {
}
}
fn get_constant_inner(word: &str) -> Result<crate::ConstantInner, Error<'_>> {
fn get_constant_inner(word: &str) -> Result<(crate::ConstantInner, crate::ScalarKind), Error<'_>> {
if word.contains('.') {
word
.parse()
.map(crate::ConstantInner::Float)
.map(|f|(crate::ConstantInner::Float(f), crate::ScalarKind::Float))
.map_err(|err| Error::BadFloat(word, err))
} else {
word
.parse()
.map(crate::ConstantInner::Sint)
.map(|i|(crate::ConstantInner::Sint(i), crate::ScalarKind::Sint))
.map_err(|err| Error::BadInteger(word, err))
}
}
@ -436,7 +436,8 @@ impl Parser {
}
Token::Number(word) => {
let _ = lexer.next();
Self::get_constant_inner(word)?
let (inner, _) = Self::get_constant_inner(word)?;
inner
}
_ => {
let _ty = self.parse_type_decl(lexer, type_arena);
@ -496,8 +497,7 @@ impl Parser {
crate::Expression::Constant(handle)
}
Token::Number(word) => {
let inner = Self::get_constant_inner(word)?;
let kind = inner.scalar_kind();
let (inner, kind) = Self::get_constant_inner(word)?;
let handle = ctx.constants.append(crate::Constant {
name: None,
specialization: None,

View File

@ -97,17 +97,7 @@ pub enum ConstantInner {
Uint(u64),
Float(f64),
Bool(bool),
}
impl ConstantInner {
pub fn scalar_kind(&self) -> ScalarKind {
match *self {
ConstantInner::Sint(_) => ScalarKind::Sint,
ConstantInner::Uint(_) => ScalarKind::Uint,
ConstantInner::Float(_) => ScalarKind::Float,
ConstantInner::Bool(_) => ScalarKind::Bool,
}
}
Composite(Vec<Handle<Constant>>),
}
#[derive(Clone, Debug, PartialEq)]