use crate::symbol::{ParadigmSet, SemanticClass};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Literal {
Bool(bool),
Integer(i64),
Float(f64),
ShortStr(heapless::String<32>),
#[cfg(feature = "alloc")]
Str(alloc::string::String),
Time(u64),
Probability(f32),
Membership(f32),
}
impl Literal {
pub fn as_bool(&self) -> Option<bool> {
match self {
Literal::Bool(b) => Some(*b),
Literal::Integer(n) => Some(*n != 0),
_ => None,
}
}
pub fn as_f64(&self) -> Option<f64> {
match self {
Literal::Float(f) => Some(*f),
Literal::Integer(n) => Some(*n as f64),
Literal::Probability(p) => Some(*p as f64),
Literal::Membership(m) => Some(*m as f64),
_ => None,
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Expr {
Lit(Literal),
Var {
name: heapless::String<32>,
paradigms: ParadigmSet,
},
Unary {
op: SemanticClass,
operand: AstNode,
paradigms: ParadigmSet,
},
Binary {
op: SemanticClass,
left: AstNode,
right: AstNode,
paradigms: ParadigmSet,
},
Ternary {
op: SemanticClass,
first: AstNode,
second: AstNode,
third: AstNode,
paradigms: ParadigmSet,
},
Quantified {
quantifier: SemanticClass,
variable: heapless::String<32>,
body: AstNode,
paradigms: ParadigmSet,
},
Apply {
op: SemanticClass,
agent: heapless::String<16>,
body: AstNode,
paradigms: ParadigmSet,
},
DeonticStatement {
modality: SemanticClass, agent: heapless::String<16>,
action: heapless::String<32>,
deadline_ns: Option<u64>,
source: Option<heapless::String<64>>,
paradigms: ParadigmSet,
},
TemporalConstraint {
op: SemanticClass, body: AstNode,
bound_ns: Option<u64>,
paradigms: ParadigmSet,
},
}
impl Expr {
pub fn paradigms(&self) -> ParadigmSet {
match self {
Expr::Lit(_) => ParadigmSet::empty(),
Expr::Var { paradigms, .. } => *paradigms,
Expr::Unary { paradigms, .. } => *paradigms,
Expr::Binary { paradigms, .. } => *paradigms,
Expr::Ternary { paradigms, .. } => *paradigms,
Expr::Quantified { paradigms, .. } => *paradigms,
Expr::Apply { paradigms, .. } => *paradigms,
Expr::DeonticStatement { paradigms, .. } => *paradigms,
Expr::TemporalConstraint { paradigms, .. } => *paradigms,
}
}
}
#[cfg(feature = "alloc")]
pub type AstNode = alloc::boxed::Box<Expr>;
#[cfg(not(feature = "alloc"))]
#[derive(Debug, Clone)]
pub struct AstNode(pub Expr);
#[cfg(feature = "alloc")]
pub fn node(expr: Expr) -> AstNode {
alloc::boxed::Box::new(expr)
}
#[cfg(not(feature = "alloc"))]
pub fn node(expr: Expr) -> AstNode {
AstNode(expr)
}
#[derive(Debug, Clone, PartialEq)]
pub struct Token {
pub class: SemanticClass,
pub raw: heapless::String<32>,
pub offset: u32,
}
impl Token {
pub fn new(class: SemanticClass, raw: &str, offset: u32) -> Self {
let mut s = heapless::String::new();
for ch in raw.chars().take(32) {
let _ = s.push(ch);
}
Token {
class,
raw: s,
offset,
}
}
}