mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[naga wgsl-in] Parse LHS expressions as such, not as generic expressions
Fixes #4383
This commit is contained in:
committed by
Jim Blandy
parent
7319512778
commit
4e14f2032e
@@ -151,6 +151,7 @@ enum Rule {
|
||||
Directive,
|
||||
GenericExpr,
|
||||
EnclosedExpr,
|
||||
LhsExpr,
|
||||
}
|
||||
|
||||
struct ParsedAttribute<T> {
|
||||
@@ -937,6 +938,53 @@ impl Parser {
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse a `lhs_expression`.
|
||||
///
|
||||
/// LHS expressions only support the `&` and `*` operators and
|
||||
/// the `[]` and `.` postfix selectors.
|
||||
fn lhs_expression<'a>(
|
||||
&mut self,
|
||||
lexer: &mut Lexer<'a>,
|
||||
ctx: &mut ExpressionContext<'a, '_, '_>,
|
||||
) -> Result<Handle<ast::Expression<'a>>, Error<'a>> {
|
||||
self.track_recursion(|this| {
|
||||
this.push_rule_span(Rule::LhsExpr, lexer);
|
||||
let start = lexer.start_byte_offset();
|
||||
let expr = match lexer.peek() {
|
||||
(Token::Operation('*'), _) => {
|
||||
let _ = lexer.next();
|
||||
let expr = this.lhs_expression(lexer, ctx)?;
|
||||
let expr = ast::Expression::Deref(expr);
|
||||
let span = this.peek_rule_span(lexer);
|
||||
ctx.expressions.append(expr, span)
|
||||
}
|
||||
(Token::Operation('&'), _) => {
|
||||
let _ = lexer.next();
|
||||
let expr = this.lhs_expression(lexer, ctx)?;
|
||||
let expr = ast::Expression::AddrOf(expr);
|
||||
let span = this.peek_rule_span(lexer);
|
||||
ctx.expressions.append(expr, span)
|
||||
}
|
||||
(Token::Operation('('), _) => {
|
||||
let _ = lexer.next();
|
||||
let primary_expr = this.lhs_expression(lexer, ctx)?;
|
||||
lexer.expect(Token::Paren(')'))?;
|
||||
this.postfix(start, lexer, ctx, primary_expr)?
|
||||
}
|
||||
(Token::Word(word), span) => {
|
||||
let _ = lexer.next();
|
||||
let ident = this.ident_expr(word, span, ctx);
|
||||
let primary_expr = ctx.expressions.append(ast::Expression::Ident(ident), span);
|
||||
this.postfix(start, lexer, ctx, primary_expr)?
|
||||
}
|
||||
_ => this.singular_expression(lexer, ctx)?,
|
||||
};
|
||||
|
||||
this.pop_rule_span(lexer);
|
||||
Ok(expr)
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse a `singular_expression`.
|
||||
fn singular_expression<'a>(
|
||||
&mut self,
|
||||
@@ -1781,7 +1829,7 @@ impl Parser {
|
||||
block: &mut ast::Block<'a>,
|
||||
) -> Result<(), Error<'a>> {
|
||||
let span_start = lexer.start_byte_offset();
|
||||
let target = self.general_expression(lexer, ctx)?;
|
||||
let target = self.lhs_expression(lexer, ctx)?;
|
||||
self.assignment_op_and_rhs(lexer, ctx, block, target, span_start)
|
||||
}
|
||||
|
||||
|
||||
@@ -420,6 +420,42 @@ fn parse_expressions() {
|
||||
}").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_assignment_statements() {
|
||||
parse_str(
|
||||
"
|
||||
struct Foo { x: i32 };
|
||||
|
||||
fn foo() {
|
||||
var x: u32 = 0u;
|
||||
x++;
|
||||
x--;
|
||||
x = 1u;
|
||||
x += 1u;
|
||||
var v: vec2<f32> = vec2<f32>(1.0, 1.0);
|
||||
v[0] += 1.0;
|
||||
(v)[0] += 1.0;
|
||||
var s: Foo = Foo(0);
|
||||
s.x -= 1;
|
||||
(s.x) -= 1;
|
||||
(s).x -= 1;
|
||||
_ = 5u;
|
||||
}",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let error = parse_str(
|
||||
"fn foo() {
|
||||
x|x++;
|
||||
}",
|
||||
)
|
||||
.unwrap_err();
|
||||
assert_eq!(
|
||||
error.message(),
|
||||
"expected assignment or increment/decrement, found \"|\"",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn binary_expression_mixed_scalar_and_vector_operands() {
|
||||
for (operand, expect_splat) in [
|
||||
|
||||
@@ -1759,11 +1759,11 @@ fn binary_statement() {
|
||||
3 + 5;
|
||||
}
|
||||
",
|
||||
r###"error: expected assignment or increment/decrement, found ";"
|
||||
┌─ wgsl:3:18
|
||||
r###"error: expected assignment or increment/decrement, found "+"
|
||||
┌─ wgsl:3:15
|
||||
│
|
||||
3 │ 3 + 5;
|
||||
│ ^ expected assignment or increment/decrement
|
||||
│ ^ expected assignment or increment/decrement
|
||||
|
||||
"###,
|
||||
);
|
||||
@@ -1777,11 +1777,11 @@ fn assign_to_expr() {
|
||||
3 + 5 = 10;
|
||||
}
|
||||
",
|
||||
r###"error: invalid left-hand side of assignment
|
||||
┌─ wgsl:3:13
|
||||
r###"error: expected assignment or increment/decrement, found "+"
|
||||
┌─ wgsl:3:15
|
||||
│
|
||||
3 │ 3 + 5 = 10;
|
||||
│ ^^^^^ cannot assign to this expression
|
||||
│ ^ expected assignment or increment/decrement
|
||||
|
||||
"###,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user