use crate::algebra::MultiVectorClass; #[derive(PartialEq, Eq, Clone, Debug)] pub enum DataType<'a> { Integer, SimdVector(usize), MultiVector(&'a MultiVectorClass), } impl DataType<'_> { pub fn is_scalar(&self) -> bool { match self { Self::SimdVector(1) => true, Self::MultiVector(multi_vector_class) => multi_vector_class.is_scalar(), _ => false, } } } #[derive(PartialEq, Eq, Clone, Debug)] pub enum ExpressionContent<'a> { None, Variable(DataType<'a>, &'static str), InvokeClassMethod(&'a MultiVectorClass, &'static str, Vec<(DataType<'a>, Expression<'a>)>), InvokeInstanceMethod( DataType<'a>, Box>, &'static str, DataType<'a>, Vec<(DataType<'a>, Expression<'a>)>, ), Conversion(&'a MultiVectorClass, &'a MultiVectorClass, Box>), Select(Box>, Box>, Box>), Access(Box>, usize), Swizzle(Box>, Vec), Gather(Box>, Vec<(usize, usize)>), Constant(DataType<'a>, Vec), SquareRoot(Box>), Add(Box>, Box>), Subtract(Box>, Box>), Multiply(Box>, Box>), Divide(Box>, Box>), LessThan(Box>, Box>), Equal(Box>, Box>), LogicAnd(Box>, Box>), BitShiftRight(Box>, Box>), } #[derive(PartialEq, Eq, Clone, Debug)] pub struct Expression<'a> { pub size: usize, pub content: ExpressionContent<'a>, } impl Expression<'_> { pub fn is_scalar(&self) -> bool { if self.size > 1 { return false; } match &self.content { ExpressionContent::Variable(data_type, _) => data_type.is_scalar(), ExpressionContent::InvokeInstanceMethod(_, _, _, result_data_type, _) => result_data_type.is_scalar(), _ => false, } } } #[derive(PartialEq, Eq, Clone, Debug)] pub struct Parameter<'a> { pub name: &'static str, pub data_type: DataType<'a>, } impl<'a> Parameter<'a> { pub fn multi_vector_class(&self) -> &'a MultiVectorClass { if let DataType::MultiVector(class) = self.data_type { class } else { unreachable!() } } } #[derive(PartialEq, Eq, Clone)] pub enum AstNode<'a> { None, Preamble, ClassDefinition { class: &'a MultiVectorClass, }, ReturnStatement { expression: Box>, }, VariableAssignment { name: &'static str, data_type: Option>, expression: Box>, }, IfThenBlock { condition: Box>, body: Vec>, }, WhileLoopBlock { condition: Box>, body: Vec>, }, TraitImplementation { result: Parameter<'a>, parameters: Vec>, body: Vec>, }, }