Skip to content

Commit 0994648

Browse files
feat(wgsl-in): create skeleton for parsing directives
1 parent a72064f commit 0994648

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

naga/src/front/wgsl/error.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,14 @@ pub(crate) enum Error<'a> {
265265
PipelineConstantIDValue(Span),
266266
NotBool(Span),
267267
ConstAssertFailed(Span),
268+
DirectiveNotYetImplemented {
269+
kind: &'static str,
270+
span: Span,
271+
tracking_issue_num: u16,
272+
},
273+
DirectiveAfterFirstGlobalDecl {
274+
directive_span: Span,
275+
},
268276
}
269277

270278
#[derive(Clone, Debug)]
@@ -861,6 +869,41 @@ impl<'a> Error<'a> {
861869
labels: vec![(span, "evaluates to false".into())],
862870
notes: vec![],
863871
},
872+
Error::DirectiveNotYetImplemented {
873+
kind,
874+
span,
875+
tracking_issue_num,
876+
} => ParseError {
877+
message: format!("`{kind}` global directives are not yet supported (sorry!)"),
878+
labels: vec![(
879+
span,
880+
concat!(
881+
"this directive specifies standard functionality ",
882+
"which is not yet implemented in Naga"
883+
)
884+
.into(),
885+
)],
886+
notes: vec![format!(
887+
concat!(
888+
"Let Naga maintainers know that you ran into this at ",
889+
"<https://github.com/gfx-rs/wgpu/issues/{}>, ",
890+
"so they can prioritize it!"
891+
),
892+
tracking_issue_num
893+
)],
894+
},
895+
Error::DirectiveAfterFirstGlobalDecl { directive_span } => ParseError {
896+
message: "expected global declaration, but found a global directive".into(),
897+
labels: vec![(
898+
directive_span,
899+
"this directive was written after global declaration parsing started".into(),
900+
)],
901+
notes: vec![concat!(
902+
"global directives are only allowed before global declarations; ",
903+
"maybe hoist this closer to the top of the shader?"
904+
)
905+
.into()],
906+
},
864907
}
865908
}
866909
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
2+
pub enum DirectiveKind {
3+
Unimplemented(UnimplementedDirectiveKind),
4+
}
5+
6+
impl DirectiveKind {
7+
pub fn from_ident(s: &str) -> Option<(Self, &'static str)> {
8+
Some(match s {
9+
"diagnostic" => (
10+
Self::Unimplemented(UnimplementedDirectiveKind::Diagnostic),
11+
"diagnostic",
12+
),
13+
"enable" => (
14+
Self::Unimplemented(UnimplementedDirectiveKind::Enable),
15+
"enable",
16+
),
17+
"requires" => (
18+
Self::Unimplemented(UnimplementedDirectiveKind::Requires),
19+
"requires",
20+
),
21+
_ => return None,
22+
})
23+
}
24+
}
25+
26+
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
27+
pub enum UnimplementedDirectiveKind {
28+
Diagnostic,
29+
Enable,
30+
Requires,
31+
}
32+
33+
impl UnimplementedDirectiveKind {
34+
pub const fn tracking_issue_num(self) -> u16 {
35+
match self {
36+
Self::Diagnostic => 5320,
37+
Self::Requires => 6350,
38+
Self::Enable => 5476,
39+
}
40+
}
41+
}

naga/src/front/wgsl/parse/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::front::wgsl::error::{Error, ExpectedToken};
2+
use crate::front::wgsl::parse::directive::DirectiveKind;
23
use crate::front::wgsl::parse::lexer::{Lexer, Token};
34
use crate::front::wgsl::parse::number::Number;
45
use crate::front::wgsl::Scalar;
@@ -7,6 +8,7 @@ use crate::{Arena, FastIndexSet, Handle, ShaderStage, Span};
78

89
pub mod ast;
910
pub mod conv;
11+
pub mod directive;
1012
pub mod lexer;
1113
pub mod number;
1214

@@ -136,6 +138,7 @@ enum Rule {
136138
SingularExpr,
137139
UnaryExpr,
138140
GeneralExpr,
141+
Directive,
139142
}
140143

141144
struct ParsedAttribute<T> {
@@ -2357,6 +2360,9 @@ impl Parser {
23572360
let start = lexer.start_byte_offset();
23582361
let kind = match lexer.next() {
23592362
(Token::Separator(';'), _) => None,
2363+
(Token::Word(word), directive_span) if DirectiveKind::from_ident(word).is_some() => {
2364+
return Err(Error::DirectiveAfterFirstGlobalDecl { directive_span });
2365+
}
23602366
(Token::Word("struct"), _) => {
23612367
let name = lexer.next_ident()?;
23622368

@@ -2474,6 +2480,29 @@ impl Parser {
24742480

24752481
let mut lexer = Lexer::new(source);
24762482
let mut tu = ast::TranslationUnit::default();
2483+
2484+
// Parse directives.
2485+
#[allow(clippy::never_loop)]
2486+
loop {
2487+
if let Ok(ident) = lexer.peek_ident() {
2488+
self.push_rule_span(Rule::Directive, &mut lexer);
2489+
if let Some((kind, name)) = DirectiveKind::from_ident(ident.name) {
2490+
match kind {
2491+
DirectiveKind::Unimplemented(unimplemented) => {
2492+
return Err(Error::DirectiveNotYetImplemented {
2493+
kind: name,
2494+
span: ident.span,
2495+
tracking_issue_num: unimplemented.tracking_issue_num(),
2496+
})
2497+
}
2498+
}
2499+
}
2500+
// TODO: add directives to set of expected things in errors later
2501+
self.pop_rule_span(&lexer);
2502+
}
2503+
break;
2504+
}
2505+
24772506
loop {
24782507
match self.global_decl(&mut lexer, &mut tu) {
24792508
Err(error) => return Err(error),

0 commit comments

Comments
 (0)