use super::*;
use core::ptr::eq;
mod display;
mod logic;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ValkyrieOperator {
Placeholder,
Not,
Positive,
Negative,
CovariantType,
ContravariantType,
Box,
Unbox,
Unpack {
level: u8,
},
Reciprocal,
Roots(u8),
Assign {
monadic: bool,
},
Plus,
PlusAssign,
Concat,
Less {
equal: bool,
},
Greater {
equal: bool,
},
MuchGreater,
MuchLess,
VeryMuchGreater,
VeryMuchLess,
Equal {
negative: bool,
},
StrictlyEqual {
negative: bool,
},
RangeTo {
equal: bool,
},
Is {
negative: bool,
},
In {
negative: bool,
},
Contains {
negative: bool,
},
Minus,
MinusAssign,
Multiply,
Divide,
Remainder,
Modulo,
DivideRemainder,
DivideFloor,
Power,
Surd,
LogicMatrix {
mask: LogicMatrix,
},
Map,
Optional,
QuickRaise,
Celsius,
Fahrenheit,
DivideByDecimal {
power: u8,
},
Transpose,
Transjugate,
Hermitian,
}
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum LogicMatrix {
False = 0b0,
And = 0b1,
AndNot = 0b10,
P = 0b11,
NotAnd = 0b100,
Q = 0b101,
Xor = 0b110,
Or = 0b111,
Nor = 0b1000,
Xnor = 0b1001,
NotQ = 0b1010,
OrNot = 0b1011,
NotP = 0b1100,
NotOr = 0b1101,
Nand = 0b1110,
True = 0b1111,
}
impl From<LogicMatrix> for ValkyrieOperator {
fn from(logic: LogicMatrix) -> Self {
Self::LogicMatrix { mask: logic }
}
}
impl ValkyrieOperator {
pub fn precedence(&self) -> Precedence {
let n = match self {
Self::Placeholder => 0,
Self::Concat => 14000,
Self::Is { .. } => 14000,
Self::In { .. } => 14000,
Self::Contains { .. } => 14000,
Self::Assign { .. } => 14000,
Self::RangeTo { .. } => 14000,
Self::PlusAssign => 14100,
Self::MinusAssign => 14100,
Self::LogicMatrix { .. } => 14700,
Self::Equal { .. } => 14700,
Self::StrictlyEqual { .. } => 14700,
Self::Map => 14700,
Self::Less { .. } | Self::Greater { .. } => 14800,
Self::MuchLess | Self::MuchGreater => 14900,
Self::VeryMuchLess | Self::VeryMuchGreater => 14950,
Self::Plus => 15000,
Self::Minus => 15000,
Self::Multiply => 15100,
Self::Divide => 15100,
Self::Remainder => 15100,
Self::Modulo => 15100,
Self::DivideRemainder => 15100,
Self::DivideFloor => 15100,
Self::Power => 15200,
Self::Surd => 15200,
Self::Not => 25000,
Self::Positive | Self::Negative => 25000,
Self::CovariantType | Self::ContravariantType => 25000,
Self::Box => 25000,
Self::Unbox => 25000,
Self::Unpack { .. } => 25000,
Self::Reciprocal => 25000,
Self::Roots(_) => 25000,
Self::Optional => 45000,
Self::QuickRaise => 45000,
Self::Celsius => 45000,
Self::Fahrenheit => 45000,
Self::Transpose => 45000,
Self::Transjugate => 45000,
Self::Hermitian => 45000,
Self::DivideByDecimal { .. } => 45000,
};
Precedence(n)
}
pub fn as_str(&self) -> &'static str {
match self {
Self::Placeholder => "???",
Self::Not => "!",
Self::Concat => "++",
Self::Positive => "+",
Self::Negative => "-",
Self::CovariantType => "+",
Self::ContravariantType => "-",
Self::Plus => "+",
Self::PlusAssign => "+=",
Self::Minus => "-",
Self::MinusAssign => "-=",
Self::Multiply => "*",
Self::Divide => "/",
Self::Remainder => "%",
Self::Modulo => "⁒",
Self::DivideRemainder => "÷",
Self::DivideFloor => "/_",
Self::Power => "^",
Self::Surd => "√",
Self::Optional => "?",
Self::QuickRaise => "!",
Self::Celsius => "℃",
Self::Fahrenheit => "℉",
Self::Transpose => "ᵀ",
Self::Transjugate => "ᴴ",
Self::Hermitian => "Hermitian",
Self::Box => "&",
Self::Unbox => "*",
Self::Unpack { level } => match level {
2 => "⁑",
_ => "⁂",
},
Self::Greater { equal } => match equal {
true => "⩾",
false => ">",
},
Self::MuchGreater => "≫",
Self::VeryMuchGreater => "⋙",
Self::Less { equal } => match equal {
true => "⩽",
false => "<",
},
Self::MuchLess => "≪",
Self::VeryMuchLess => "⋘",
Self::Is { negative } => match negative {
true => "⋢",
false => "⊑",
},
Self::In { negative } => match negative {
true => "∉",
false => "∈",
},
Self::Contains { negative } => match negative {
true => "∌",
false => "∋",
},
Self::RangeTo { equal } => match equal {
true => "..=",
false => "..<",
},
Self::Equal { negative } => match negative {
true => "≠",
false => "==",
},
Self::StrictlyEqual { negative } => match negative {
true => "≢",
false => "≡",
},
Self::Reciprocal => "⅟",
Self::Roots(v) => match v {
3 => "∛",
4 => "∜",
_ => "√",
},
Self::DivideByDecimal { power } => match power {
1 => "⁒",
3 => "‰",
4 => "‱",
_ => "%",
},
Self::Assign { monadic } => match monadic {
true => "?=",
false => "=",
},
Self::LogicMatrix { mask } => mask.as_str(),
Self::Map => "/@",
}
}
pub fn associativity(&self) -> Associativity {
match self {
ValkyrieOperator::Power => Associativity::Right,
ValkyrieOperator::Surd => Associativity::Right,
_ => Associativity::Left,
}
}
pub fn accept_arguments(&self) -> usize {
match self {
Self::Plus | Self::Multiply => 0,
_ => 1,
}
}
pub fn overrideable(&self) -> bool {
match self {
Self::Equal { negative: true } => false,
Self::StrictlyEqual { negative: true } => false,
_ => true,
}
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct UnaryNode {
pub operator: OperatorNode,
pub base: ExpressionKind,
}
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BinaryNode {
pub infix: OperatorNode,
pub lhs: ExpressionKind,
pub rhs: ExpressionKind,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct OperatorNode {
pub kind: ValkyrieOperator,
pub span: Range<u32>,
}
impl ValkyrieNode for UnaryNode {
fn get_range(&self) -> Range<usize> {
Range { start: self.operator.span.start as usize, end: self.base.get_end() }
}
}
impl ValkyrieNode for BinaryNode {
fn get_range(&self) -> Range<usize> {
let head = self.lhs.get_range().start;
let tail = self.rhs.get_range().end;
head..tail
}
}