[wgsl] support vector type casts

This commit is contained in:
Dzmitry Malyshau
2021-01-26 23:29:40 -05:00
committed by Dzmitry Malyshau
parent 9c74468f81
commit ab2cf8b842
3 changed files with 30 additions and 18 deletions

View File

@@ -62,6 +62,8 @@ pub enum Error<'a> {
BadTexture(&'a str),
#[error("bad texture coordinate")]
BadCoordinate,
#[error("invalid type cast to `{0}`")]
BadTypeCast(&'a str),
#[error(transparent)]
InvalidResolve(ResolveError),
#[error("unknown import: `{0}`")]
@@ -435,15 +437,6 @@ impl Parser {
let expr = self.parse_general_expression(lexer, ctx.reborrow())?;
lexer.expect(Token::Paren(')'))?;
Some(crate::Expression::Derivative { axis, expr })
} else if let Some((kind, _width)) = conv::get_scalar_type(name) {
lexer.expect(Token::Paren('('))?;
let expr = self.parse_general_expression(lexer, ctx.reborrow())?;
lexer.expect(Token::Paren(')'))?;
Some(crate::Expression::As {
expr,
kind,
convert: true,
})
} else if let Some(fun) = conv::map_standard_fun(name) {
lexer.expect(Token::Paren('('))?;
let arg_count = fun.argument_count();
@@ -833,18 +826,28 @@ impl Parser {
ctx.types,
ctx.constants,
)?;
let kind = inner.scalar_kind();
let ty = ctx.types.fetch_or_append(crate::Type { name: None, inner });
lexer.expect(Token::Paren('('))?;
let mut components = Vec::new();
while !lexer.skip(Token::Paren(')')) {
if !components.is_empty() {
lexer.expect(Token::Separator(','))?;
}
let sub_expr = self.parse_general_expression(lexer, ctx.reborrow())?;
components.push(sub_expr);
let mut last_component =
self.parse_general_expression(lexer, ctx.reborrow())?;
while lexer.skip(Token::Separator(',')) {
components.push(last_component);
last_component = self.parse_general_expression(lexer, ctx.reborrow())?;
}
lexer.expect(Token::Paren(')'))?;
if components.is_empty() {
crate::Expression::As {
expr: last_component,
kind: kind.ok_or(Error::BadTypeCast(word))?,
convert: true,
}
} else {
components.push(last_component);
crate::Expression::Compose { ty, components }
}
crate::Expression::Compose { ty, components }
}
}
other => return other.unexpected("primary expression"),

View File

@@ -37,6 +37,15 @@ fn parse_type_cast() {
",
)
.unwrap();
parse_str(
"
fn main() {
const x: vec2<f32> = vec2<f32>(1.0, 2.0);
const y: vec2<u32> = vec2<u32>(x);
}
",
)
.unwrap();
}
#[test]

View File

@@ -20,9 +20,9 @@ struct Data {
typedef int type4;
typedef metal::float3x3 type5;
typedef float type5;
typedef float type6;
typedef metal::float3x3 type6;
typedef metal::texturecube<float, metal::access::sample> type7;