use alloc::vec::Vec;
use core::hash::Hash;
use crate::diagnostic_filter::DiagnosticFilterNode;
use crate::front::wgsl::parse::directive::enable_extension::EnableExtensions;
use crate::front::wgsl::parse::number::Number;
use crate::{Arena, FastIndexSet, Handle, Span};
#[derive(Debug, Default)]
pub struct TranslationUnit<'a> {
pub enable_extensions: EnableExtensions,
pub decls: Arena<GlobalDecl<'a>>,
pub expressions: Arena<Expression<'a>>,
pub diagnostic_filters: Arena<DiagnosticFilterNode>,
pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
pub doc_comments: Vec<&'a str>,
}
#[derive(Debug, Clone, Copy)]
pub struct Ident<'a> {
pub name: &'a str,
pub span: Span,
}
#[derive(Debug)]
pub enum IdentExpr<'a> {
Unresolved(&'a str),
Local(Handle<Local>),
}
#[derive(Debug)]
pub struct TemplateElaboratedIdent<'a> {
pub ident: IdentExpr<'a>,
pub ident_span: Span,
pub template_list: Vec<Handle<Expression<'a>>>,
pub template_list_span: Span,
}
#[derive(Debug)]
pub struct CallPhrase<'a> {
pub function: TemplateElaboratedIdent<'a>,
pub arguments: Vec<Handle<Expression<'a>>>,
}
#[derive(Debug)]
pub struct Dependency<'a> {
pub ident: &'a str,
pub usage: Span,
}
impl Hash for Dependency<'_> {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.ident.hash(state);
}
}
impl PartialEq for Dependency<'_> {
fn eq(&self, other: &Self) -> bool {
self.ident == other.ident
}
}
impl Eq for Dependency<'_> {}
#[derive(Debug)]
pub struct GlobalDecl<'a> {
pub kind: GlobalDeclKind<'a>,
pub dependencies: FastIndexSet<Dependency<'a>>,
}
#[derive(Debug)]
pub enum GlobalDeclKind<'a> {
Fn(Function<'a>),
Var(GlobalVariable<'a>),
Const(Const<'a>),
Override(Override<'a>),
Struct(Struct<'a>),
Type(TypeAlias<'a>),
ConstAssert(Handle<Expression<'a>>),
}
#[derive(Debug)]
pub struct FunctionArgument<'a> {
pub name: Ident<'a>,
pub ty: TemplateElaboratedIdent<'a>,
pub binding: Option<Binding<'a>>,
pub handle: Handle<Local>,
}
#[derive(Debug)]
pub struct FunctionResult<'a> {
pub ty: TemplateElaboratedIdent<'a>,
pub binding: Option<Binding<'a>>,
pub must_use: bool,
}
#[derive(Debug)]
pub struct EntryPoint<'a> {
pub stage: crate::ShaderStage,
pub early_depth_test: Option<crate::EarlyDepthTest>,
pub workgroup_size: Option<[Option<Handle<Expression<'a>>>; 3]>,
pub mesh_output_variable: Option<(&'a str, Span)>,
pub task_payload: Option<(&'a str, Span)>,
pub ray_incoming_payload: Option<(&'a str, Span)>,
}
#[cfg(doc)]
use crate::front::wgsl::lower::{LocalExpressionContext, StatementContext};
#[derive(Debug)]
pub struct Function<'a> {
pub entry_point: Option<EntryPoint<'a>>,
pub name: Ident<'a>,
pub arguments: Vec<FunctionArgument<'a>>,
pub result: Option<FunctionResult<'a>>,
pub body: Block<'a>,
pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
pub doc_comments: Vec<&'a str>,
}
#[derive(Debug)]
pub enum Binding<'a> {
BuiltIn(crate::BuiltIn),
Location {
location: Handle<Expression<'a>>,
interpolation: Option<crate::Interpolation>,
sampling: Option<crate::Sampling>,
blend_src: Option<Handle<Expression<'a>>>,
per_primitive: bool,
},
}
#[derive(Debug)]
pub struct ResourceBinding<'a> {
pub group: Handle<Expression<'a>>,
pub binding: Handle<Expression<'a>>,
}
#[derive(Debug)]
pub struct GlobalVariable<'a> {
pub name: Ident<'a>,
pub template_list: Vec<Handle<Expression<'a>>>,
pub binding: Option<ResourceBinding<'a>>,
pub ty: Option<TemplateElaboratedIdent<'a>>,
pub init: Option<Handle<Expression<'a>>>,
pub doc_comments: Vec<&'a str>,
pub memory_decorations: crate::MemoryDecorations,
}
#[derive(Debug)]
pub struct StructMember<'a> {
pub name: Ident<'a>,
pub ty: TemplateElaboratedIdent<'a>,
pub binding: Option<Binding<'a>>,
pub align: Option<Handle<Expression<'a>>>,
pub size: Option<Handle<Expression<'a>>>,
pub doc_comments: Vec<&'a str>,
}
#[derive(Debug)]
pub struct Struct<'a> {
pub name: Ident<'a>,
pub members: Vec<StructMember<'a>>,
pub doc_comments: Vec<&'a str>,
}
#[derive(Debug)]
pub struct TypeAlias<'a> {
pub name: Ident<'a>,
pub ty: TemplateElaboratedIdent<'a>,
}
#[derive(Debug)]
pub struct Const<'a> {
pub name: Ident<'a>,
pub ty: Option<TemplateElaboratedIdent<'a>>,
pub init: Handle<Expression<'a>>,
pub doc_comments: Vec<&'a str>,
}
#[derive(Debug)]
pub struct Override<'a> {
pub name: Ident<'a>,
pub id: Option<Handle<Expression<'a>>>,
pub ty: Option<TemplateElaboratedIdent<'a>>,
pub init: Option<Handle<Expression<'a>>>,
}
#[derive(Debug, Default)]
pub struct Block<'a> {
pub stmts: Vec<Statement<'a>>,
}
#[derive(Debug)]
pub struct Statement<'a> {
pub kind: StatementKind<'a>,
pub span: Span,
}
#[derive(Debug)]
pub enum StatementKind<'a> {
LocalDecl(LocalDecl<'a>),
Block(Block<'a>),
If {
condition: Handle<Expression<'a>>,
accept: Block<'a>,
reject: Block<'a>,
},
Switch {
selector: Handle<Expression<'a>>,
cases: Vec<SwitchCase<'a>>,
},
Loop {
body: Block<'a>,
continuing: Block<'a>,
break_if: Option<Handle<Expression<'a>>>,
},
Break,
Continue,
Return {
value: Option<Handle<Expression<'a>>>,
},
Kill,
Call(CallPhrase<'a>),
Assign {
target: Handle<Expression<'a>>,
op: Option<crate::BinaryOperator>,
value: Handle<Expression<'a>>,
},
Increment(Handle<Expression<'a>>),
Decrement(Handle<Expression<'a>>),
Phony(Handle<Expression<'a>>),
ConstAssert(Handle<Expression<'a>>),
}
#[derive(Debug)]
pub enum SwitchValue<'a> {
Expr(Handle<Expression<'a>>),
Default,
}
#[derive(Debug)]
pub struct SwitchCase<'a> {
pub value: SwitchValue<'a>,
pub body: Block<'a>,
pub fall_through: bool,
}
#[derive(Debug, Copy, Clone)]
pub enum Literal {
Bool(bool),
Number(Number),
}
#[cfg(doc)]
use crate::front::wgsl::lower::Lowerer;
#[derive(Debug)]
pub enum Expression<'a> {
Literal(Literal),
Ident(TemplateElaboratedIdent<'a>),
Unary {
op: crate::UnaryOperator,
expr: Handle<Expression<'a>>,
},
AddrOf(Handle<Expression<'a>>),
Deref(Handle<Expression<'a>>),
Binary {
op: crate::BinaryOperator,
left: Handle<Expression<'a>>,
right: Handle<Expression<'a>>,
},
Call(CallPhrase<'a>),
Index {
base: Handle<Expression<'a>>,
index: Handle<Expression<'a>>,
},
Member {
base: Handle<Expression<'a>>,
field: Ident<'a>,
},
}
#[derive(Debug)]
pub struct LocalVariable<'a> {
pub name: Ident<'a>,
pub ty: Option<TemplateElaboratedIdent<'a>>,
pub init: Option<Handle<Expression<'a>>>,
pub handle: Handle<Local>,
}
#[derive(Debug)]
pub struct Let<'a> {
pub name: Ident<'a>,
pub ty: Option<TemplateElaboratedIdent<'a>>,
pub init: Handle<Expression<'a>>,
pub handle: Handle<Local>,
}
#[derive(Debug)]
pub struct LocalConst<'a> {
pub name: Ident<'a>,
pub ty: Option<TemplateElaboratedIdent<'a>>,
pub init: Handle<Expression<'a>>,
pub handle: Handle<Local>,
}
#[derive(Debug)]
pub enum LocalDecl<'a> {
Var(LocalVariable<'a>),
Let(Let<'a>),
Const(LocalConst<'a>),
}
#[derive(Debug)]
pub struct Local;