use std::fmt;
use super::{builtins::MacroCall, context::ExprPos, Span};
use crate::{
BinaryOperator, Binding, Constant, Expression, Function, GlobalVariable, Handle, Interpolation,
Sampling, StorageAccess, StorageClass, Type, UnaryOperator,
};
#[derive(Debug, Clone, Copy)]
pub enum GlobalLookupKind {
Variable(Handle<GlobalVariable>),
Constant(Handle<Constant>, Handle<Type>),
BlockSelect(Handle<GlobalVariable>, u32),
}
#[derive(Debug, Clone, Copy)]
pub struct GlobalLookup {
pub kind: GlobalLookupKind,
pub entry_arg: Option<usize>,
pub mutable: bool,
}
#[derive(Debug, Clone)]
pub struct ParameterInfo {
pub qualifier: ParameterQualifier,
pub depth: bool,
}
#[derive(Clone, Copy)]
pub enum FunctionKind {
Call(Handle<Function>),
Macro(MacroCall),
}
impl fmt::Debug for FunctionKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Self::Call(_) => write!(f, "Call"),
Self::Macro(_) => write!(f, "Macro"),
}
}
}
#[derive(Debug)]
pub struct Overload {
pub parameters: Vec<Handle<Type>>,
pub parameters_info: Vec<ParameterInfo>,
pub kind: FunctionKind,
pub defined: bool,
pub void: bool,
}
#[derive(Debug, Default)]
pub struct FunctionDeclaration {
pub overloads: Vec<Overload>,
pub builtin: bool,
pub double: bool,
}
#[derive(Debug)]
pub struct EntryArg {
pub name: Option<String>,
pub binding: Binding,
pub handle: Handle<GlobalVariable>,
pub storage: StorageQualifier,
}
#[derive(Debug, Clone)]
pub struct VariableReference {
pub expr: Handle<Expression>,
pub load: bool,
pub mutable: bool,
pub constant: Option<(Handle<Constant>, Handle<Type>)>,
pub entry_arg: Option<usize>,
}
#[derive(Debug, Clone)]
pub struct HirExpr {
pub kind: HirExprKind,
pub meta: Span,
}
#[derive(Debug, Clone)]
pub enum HirExprKind {
Access {
base: Handle<HirExpr>,
index: Handle<HirExpr>,
},
Select {
base: Handle<HirExpr>,
field: String,
},
Constant(Handle<Constant>),
Binary {
left: Handle<HirExpr>,
op: BinaryOperator,
right: Handle<HirExpr>,
},
Unary {
op: UnaryOperator,
expr: Handle<HirExpr>,
},
Variable(VariableReference),
Call(FunctionCall),
Conditional {
condition: Handle<HirExpr>,
accept: Handle<HirExpr>,
reject: Handle<HirExpr>,
},
Assign {
tgt: Handle<HirExpr>,
value: Handle<HirExpr>,
},
PrePostfix {
op: BinaryOperator,
postfix: bool,
expr: Handle<HirExpr>,
},
}
#[derive(Debug)]
pub enum TypeQualifier {
StorageQualifier(StorageQualifier),
Interpolation(Interpolation),
Set(u32),
Binding(u32),
Location(u32),
WorkGroupSize(usize, u32),
Sampling(Sampling),
Layout(StructLayout),
Precision(Precision),
EarlyFragmentTests,
StorageAccess(StorageAccess),
}
#[derive(Debug, Clone)]
pub enum FunctionCallKind {
TypeConstructor(Handle<Type>),
Function(String),
}
#[derive(Debug, Clone)]
pub struct FunctionCall {
pub kind: FunctionCallKind,
pub args: Vec<Handle<HirExpr>>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum StorageQualifier {
StorageClass(StorageClass),
Input,
Output,
Const,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StructLayout {
Std140,
Std430,
}
#[derive(Debug, Clone, PartialEq, Copy)]
pub enum Precision {
Low,
Medium,
High,
}
#[derive(Debug, Clone, PartialEq, Copy)]
pub enum ParameterQualifier {
In,
Out,
InOut,
Const,
}
impl ParameterQualifier {
pub fn is_lhs(&self) -> bool {
match *self {
ParameterQualifier::Out | ParameterQualifier::InOut => true,
_ => false,
}
}
pub fn as_pos(&self) -> ExprPos {
match *self {
ParameterQualifier::Out | ParameterQualifier::InOut => ExprPos::Lhs,
_ => ExprPos::Rhs,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Profile {
Core,
}