mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-02-22 20:03:11 +00:00
[glsl-in] Allow code after terminator statements (#1308)
* [glsl-in] Allow code after terminator statements * [glsl-in] Track finished state in the context * [glsl-in] Cull statements after terminators
This commit is contained in:
parent
995a7752a9
commit
bd411c28c2
@ -643,6 +643,8 @@ impl Parser {
|
|||||||
.0;
|
.0;
|
||||||
|
|
||||||
ctx.emit_flush(body);
|
ctx.emit_flush(body);
|
||||||
|
ctx.emit_start();
|
||||||
|
|
||||||
body.push(
|
body.push(
|
||||||
Statement::Store {
|
Statement::Store {
|
||||||
pointer: target,
|
pointer: target,
|
||||||
@ -650,7 +652,6 @@ impl Parser {
|
|||||||
},
|
},
|
||||||
meta.as_span(),
|
meta.as_span(),
|
||||||
);
|
);
|
||||||
ctx.emit_start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
@ -40,6 +40,7 @@ impl<'source> ParsingContext<'source> {
|
|||||||
parser: &mut Parser,
|
parser: &mut Parser,
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
body: &mut Block,
|
body: &mut Block,
|
||||||
|
terminator: &mut Option<usize>,
|
||||||
) -> Result<Option<SourceMetadata>> {
|
) -> Result<Option<SourceMetadata>> {
|
||||||
// TODO: This prevents snippets like the following from working
|
// TODO: This prevents snippets like the following from working
|
||||||
// ```glsl
|
// ```glsl
|
||||||
@ -62,11 +63,15 @@ impl<'source> ParsingContext<'source> {
|
|||||||
|
|
||||||
let meta_rest = match *value {
|
let meta_rest = match *value {
|
||||||
TokenValue::Continue => {
|
TokenValue::Continue => {
|
||||||
body.push(Statement::Continue, self.bump(parser)?.meta.as_span());
|
let meta = self.bump(parser)?.meta;
|
||||||
|
body.push(Statement::Continue, meta.as_span());
|
||||||
|
terminator.get_or_insert(body.len());
|
||||||
self.expect(parser, TokenValue::Semicolon)?.meta
|
self.expect(parser, TokenValue::Semicolon)?.meta
|
||||||
}
|
}
|
||||||
TokenValue::Break => {
|
TokenValue::Break => {
|
||||||
body.push(Statement::Break, self.bump(parser)?.meta.as_span());
|
let meta = self.bump(parser)?.meta;
|
||||||
|
body.push(Statement::Break, meta.as_span());
|
||||||
|
terminator.get_or_insert(body.len());
|
||||||
self.expect(parser, TokenValue::Semicolon)?.meta
|
self.expect(parser, TokenValue::Semicolon)?.meta
|
||||||
}
|
}
|
||||||
TokenValue::Return => {
|
TokenValue::Return => {
|
||||||
@ -88,10 +93,15 @@ impl<'source> ParsingContext<'source> {
|
|||||||
ctx.emit_start();
|
ctx.emit_start();
|
||||||
|
|
||||||
body.push(Statement::Return { value }, meta.as_span());
|
body.push(Statement::Return { value }, meta.as_span());
|
||||||
|
terminator.get_or_insert(body.len());
|
||||||
|
|
||||||
meta
|
meta
|
||||||
}
|
}
|
||||||
TokenValue::Discard => {
|
TokenValue::Discard => {
|
||||||
body.push(Statement::Kill, self.bump(parser)?.meta.as_span());
|
let meta = self.bump(parser)?.meta;
|
||||||
|
body.push(Statement::Kill, meta.as_span());
|
||||||
|
terminator.get_or_insert(body.len());
|
||||||
|
|
||||||
self.expect(parser, TokenValue::Semicolon)?.meta
|
self.expect(parser, TokenValue::Semicolon)?.meta
|
||||||
}
|
}
|
||||||
TokenValue::If => {
|
TokenValue::If => {
|
||||||
@ -112,13 +122,17 @@ impl<'source> ParsingContext<'source> {
|
|||||||
ctx.emit_start();
|
ctx.emit_start();
|
||||||
|
|
||||||
let mut accept = Block::new();
|
let mut accept = Block::new();
|
||||||
if let Some(more_meta) = self.parse_statement(parser, ctx, &mut accept)? {
|
if let Some(more_meta) =
|
||||||
|
self.parse_statement(parser, ctx, &mut accept, &mut None)?
|
||||||
|
{
|
||||||
meta = meta.union(&more_meta)
|
meta = meta.union(&more_meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut reject = Block::new();
|
let mut reject = Block::new();
|
||||||
if self.bump_if(parser, TokenValue::Else).is_some() {
|
if self.bump_if(parser, TokenValue::Else).is_some() {
|
||||||
if let Some(more_meta) = self.parse_statement(parser, ctx, &mut reject)? {
|
if let Some(more_meta) =
|
||||||
|
self.parse_statement(parser, ctx, &mut reject, &mut None)?
|
||||||
|
{
|
||||||
meta = meta.union(&more_meta);
|
meta = meta.union(&more_meta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,6 +145,7 @@ impl<'source> ParsingContext<'source> {
|
|||||||
},
|
},
|
||||||
meta.as_span(),
|
meta.as_span(),
|
||||||
);
|
);
|
||||||
|
|
||||||
meta
|
meta
|
||||||
}
|
}
|
||||||
TokenValue::Switch => {
|
TokenValue::Switch => {
|
||||||
@ -190,25 +205,32 @@ impl<'source> ParsingContext<'source> {
|
|||||||
|
|
||||||
let mut body = Block::new();
|
let mut body = Block::new();
|
||||||
|
|
||||||
|
let mut case_terminator = None;
|
||||||
loop {
|
loop {
|
||||||
match self.expect_peek(parser)?.value {
|
match self.expect_peek(parser)?.value {
|
||||||
TokenValue::Case
|
TokenValue::Case
|
||||||
| TokenValue::Default
|
| TokenValue::Default
|
||||||
| TokenValue::RightBrace => break,
|
| TokenValue::RightBrace => break,
|
||||||
_ => {
|
_ => {
|
||||||
self.parse_statement(parser, ctx, &mut body)?;
|
self.parse_statement(
|
||||||
|
parser,
|
||||||
|
ctx,
|
||||||
|
&mut body,
|
||||||
|
&mut case_terminator,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut fall_through = true;
|
let mut fall_through = true;
|
||||||
|
|
||||||
for (i, stmt) in body.iter().enumerate() {
|
if let Some(mut idx) = case_terminator {
|
||||||
if let Statement::Break = *stmt {
|
if let Statement::Break = body[idx - 1] {
|
||||||
fall_through = false;
|
fall_through = false;
|
||||||
body.cull(i..);
|
idx -= 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.cull(idx..)
|
||||||
}
|
}
|
||||||
|
|
||||||
cases.push(SwitchCase {
|
cases.push(SwitchCase {
|
||||||
@ -231,21 +253,20 @@ impl<'source> ParsingContext<'source> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut default_terminator = None;
|
||||||
loop {
|
loop {
|
||||||
match self.expect_peek(parser)?.value {
|
match self.expect_peek(parser)?.value {
|
||||||
TokenValue::Case | TokenValue::RightBrace => break,
|
TokenValue::Case | TokenValue::RightBrace => break,
|
||||||
_ => {
|
_ => {
|
||||||
self.parse_statement(parser, ctx, &mut default)?;
|
self.parse_statement(
|
||||||
|
parser,
|
||||||
|
ctx,
|
||||||
|
&mut default,
|
||||||
|
&mut default_terminator,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, stmt) in default.iter().enumerate() {
|
|
||||||
if let Statement::Break = *stmt {
|
|
||||||
default.cull(i..);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
TokenValue::RightBrace => {
|
TokenValue::RightBrace => {
|
||||||
end_meta = self.bump(parser)?.meta;
|
end_meta = self.bump(parser)?.meta;
|
||||||
@ -269,6 +290,7 @@ impl<'source> ParsingContext<'source> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let meta = start_meta.union(&end_meta);
|
let meta = start_meta.union(&end_meta);
|
||||||
|
|
||||||
body.push(
|
body.push(
|
||||||
Statement::Switch {
|
Statement::Switch {
|
||||||
selector,
|
selector,
|
||||||
@ -277,6 +299,7 @@ impl<'source> ParsingContext<'source> {
|
|||||||
},
|
},
|
||||||
meta.as_span(),
|
meta.as_span(),
|
||||||
);
|
);
|
||||||
|
|
||||||
meta
|
meta
|
||||||
}
|
}
|
||||||
TokenValue::While => {
|
TokenValue::While => {
|
||||||
@ -314,7 +337,9 @@ impl<'source> ParsingContext<'source> {
|
|||||||
|
|
||||||
let mut meta = meta.union(&expr_meta);
|
let mut meta = meta.union(&expr_meta);
|
||||||
|
|
||||||
if let Some(body_meta) = self.parse_statement(parser, ctx, &mut loop_body)? {
|
if let Some(body_meta) =
|
||||||
|
self.parse_statement(parser, ctx, &mut loop_body, &mut None)?
|
||||||
|
{
|
||||||
meta = meta.union(&body_meta);
|
meta = meta.union(&body_meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,13 +350,15 @@ impl<'source> ParsingContext<'source> {
|
|||||||
},
|
},
|
||||||
meta.as_span(),
|
meta.as_span(),
|
||||||
);
|
);
|
||||||
|
|
||||||
meta
|
meta
|
||||||
}
|
}
|
||||||
TokenValue::Do => {
|
TokenValue::Do => {
|
||||||
let start_meta = self.bump(parser)?.meta;
|
let start_meta = self.bump(parser)?.meta;
|
||||||
|
|
||||||
let mut loop_body = Block::new();
|
let mut loop_body = Block::new();
|
||||||
self.parse_statement(parser, ctx, &mut loop_body)?;
|
|
||||||
|
self.parse_statement(parser, ctx, &mut loop_body, &mut None)?;
|
||||||
|
|
||||||
let mut stmt = ctx.stmt_ctx();
|
let mut stmt = ctx.stmt_ctx();
|
||||||
|
|
||||||
@ -372,6 +399,7 @@ impl<'source> ParsingContext<'source> {
|
|||||||
},
|
},
|
||||||
meta.as_span(),
|
meta.as_span(),
|
||||||
);
|
);
|
||||||
|
|
||||||
meta
|
meta
|
||||||
}
|
}
|
||||||
TokenValue::For => {
|
TokenValue::For => {
|
||||||
@ -464,7 +492,7 @@ impl<'source> ParsingContext<'source> {
|
|||||||
|
|
||||||
let mut meta = meta.union(&self.expect(parser, TokenValue::RightParen)?.meta);
|
let mut meta = meta.union(&self.expect(parser, TokenValue::RightParen)?.meta);
|
||||||
|
|
||||||
if let Some(stmt_meta) = self.parse_statement(parser, ctx, &mut block)? {
|
if let Some(stmt_meta) = self.parse_statement(parser, ctx, &mut block, &mut None)? {
|
||||||
meta = meta.union(&stmt_meta);
|
meta = meta.union(&stmt_meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,6 +517,7 @@ impl<'source> ParsingContext<'source> {
|
|||||||
let meta = self.parse_compound_statement(meta, parser, ctx, &mut block)?;
|
let meta = self.parse_compound_statement(meta, parser, ctx, &mut block)?;
|
||||||
|
|
||||||
ctx.remove_current_scope();
|
ctx.remove_current_scope();
|
||||||
|
|
||||||
body.push(Statement::Block(block), meta.as_span());
|
body.push(Statement::Block(block), meta.as_span());
|
||||||
|
|
||||||
meta
|
meta
|
||||||
@ -515,6 +544,7 @@ impl<'source> ParsingContext<'source> {
|
|||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
body: &mut Block,
|
body: &mut Block,
|
||||||
) -> Result<SourceMetadata> {
|
) -> Result<SourceMetadata> {
|
||||||
|
let mut terminator = None;
|
||||||
loop {
|
loop {
|
||||||
if let Some(Token {
|
if let Some(Token {
|
||||||
meta: brace_meta, ..
|
meta: brace_meta, ..
|
||||||
@ -524,11 +554,17 @@ impl<'source> ParsingContext<'source> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(stmt_meta) = self.parse_statement(parser, ctx, body)? {
|
let stmt = self.parse_statement(parser, ctx, body, &mut terminator)?;
|
||||||
|
|
||||||
|
if let Some(stmt_meta) = stmt {
|
||||||
meta = meta.union(&stmt_meta);
|
meta = meta.union(&stmt_meta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(idx) = terminator {
|
||||||
|
body.cull(idx..)
|
||||||
|
}
|
||||||
|
|
||||||
Ok(meta)
|
Ok(meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user