use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct NodusId(pub u64);
impl NodusId {
#[inline]
pub const fn new(id: u64) -> Self {
NodusId(id)
}
#[cfg(feature = "std")]
pub fn generate() -> Self {
use core::sync::atomic::{AtomicU64, Ordering};
static COUNTER: AtomicU64 = AtomicU64::new(1);
NodusId(COUNTER.fetch_add(1, Ordering::SeqCst))
}
}
#[derive(Debug, Clone, Default)]
pub struct MetadataNodi {
pub nomen: Option<String>,
pub locus: Option<String>,
pub indicium_sumptus: Option<IndiciumSumptus>,
}
#[derive(Debug, Clone, Copy)]
pub struct IndiciumSumptus {
pub cycli_cpu: u64,
pub bytes_memoriae: u64,
pub parallelizabilis: bool,
pub vectorizabilis: bool,
}
impl Default for IndiciumSumptus {
fn default() -> Self {
IndiciumSumptus {
cycli_cpu: 1,
bytes_memoriae: 0,
parallelizabilis: true,
vectorizabilis: false,
}
}
}
#[derive(Debug, Clone)]
pub enum Expressio {
Identitas,
Constans(ValorConstans),
Variabilis(usize),
VariabilisNominatus(String),
Compositio(Box<Expressio>, Box<Expressio>),
Lambda {
parametrum: Option<String>,
corpus: Box<Expressio>,
},
Applicatio(Box<Expressio>, Box<Expressio>),
Arithmetica(OperatioArithmetica, Box<Expressio>, Box<Expressio>),
ArithmeticaUnaria(OperatioUnariaArithmetica, Box<Expressio>),
Comparatio(OperatioComparationis, Box<Expressio>, Box<Expressio>),
Logica(OperatioLogica, Box<Expressio>, Box<Expressio>),
LogicaUnaria(OperatioUnariaLogica, Box<Expressio>),
Condicio {
condicio: Box<Expressio>,
tunc: Box<Expressio>,
aliter: Box<Expressio>,
},
Ager(Box<Expressio>, String),
Proiectio(Box<Expressio>, usize),
Tupla(Vec<Expressio>),
Recordum(Vec<(String, Expressio)>),
Ligatio {
nomen: String,
valor: Box<Expressio>,
corpus: Box<Expressio>,
},
Conformatio {
scrutinium: Box<Expressio>,
rami: Vec<RamusConformationis>,
},
}
#[derive(Debug, Clone)]
pub struct RamusConformationis {
pub exemplar: Exemplar,
pub custos: Option<Box<Expressio>>,
pub corpus: Expressio,
}
#[derive(Debug, Clone)]
pub enum Exemplar {
Quodlibet,
Variabilis(String),
Constans(ValorConstans),
Tupla(Vec<Exemplar>),
Constructor {
nomen: String,
parametra: Vec<Exemplar>,
},
}
#[derive(Debug, Clone)]
pub enum ValorConstans {
Unitas,
Verum(bool),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
F32(u32),
F64(u64),
Character(char),
Filum(String),
Bytes(Vec<u8>),
}
impl ValorConstans {
#[inline]
pub fn from_f32(v: f32) -> Self {
ValorConstans::F32(v.to_bits())
}
#[inline]
pub fn from_f64(v: f64) -> Self {
ValorConstans::F64(v.to_bits())
}
#[inline]
pub fn as_f32(&self) -> Option<f32> {
match self {
ValorConstans::F32(bits) => Some(f32::from_bits(*bits)),
_ => None,
}
}
#[inline]
pub fn as_f64(&self) -> Option<f64> {
match self {
ValorConstans::F64(bits) => Some(f64::from_bits(*bits)),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OperatioArithmetica {
Additio,
Subtractio,
Multiplicatio,
Divisio,
Residuum,
Et,
Vel,
Aut,
Sinistrorsum,
Dextrorsum,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OperatioUnariaArithmetica {
Negatio,
Inversio,
Absolutum,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OperatioComparationis {
Aequale,
NonAequale,
Minus,
MinusVelAequale,
Maius,
MaiusVelAequale,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OperatioLogica {
Et,
Vel,
Aut,
Implicatio,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OperatioUnariaLogica {
Non,
}
#[derive(Debug, Clone)]
pub enum NodusSerializabilis {
Vacuus,
Semel(ValorConstans),
Repetitio(ValorConstans),
Intervallum {
initium: i64,
finis: i64,
gradus: i64,
},
Externus {
genus: String,
configuratio: String,
},
Mappa {
fons: Box<NodusSerializabilis>,
functio: Expressio,
meta: MetadataNodi,
},
Filtrum {
fons: Box<NodusSerializabilis>,
praedicatum: Expressio,
meta: MetadataNodi,
},
FiltrumMappa {
fons: Box<NodusSerializabilis>,
functio: Expressio,
meta: MetadataNodi,
},
Lustrum {
fons: Box<NodusSerializabilis>,
initium: ValorConstans,
functio: Expressio,
meta: MetadataNodi,
},
MappaPlana {
fons: Box<NodusSerializabilis>,
functio: Expressio,
meta: MetadataNodi,
},
Cape {
fons: Box<NodusSerializabilis>,
numerus: usize,
},
Omitte {
fons: Box<NodusSerializabilis>,
numerus: usize,
},
Plica {
fons: Box<NodusSerializabilis>,
initium: ValorConstans,
functio: Expressio,
meta: MetadataNodi,
},
Reductio {
fons: Box<NodusSerializabilis>,
functio: Expressio,
meta: MetadataNodi,
},
Numera {
fons: Box<NodusSerializabilis>,
},
Aggregatio {
fons: Box<NodusSerializabilis>,
operatio: OperatioAggregationis,
},
Iunge {
sinister: Box<NodusSerializabilis>,
dexter: Box<NodusSerializabilis>,
meta: MetadataNodi,
},
Catena {
primus: Box<NodusSerializabilis>,
secundus: Box<NodusSerializabilis>,
meta: MetadataNodi,
},
GregaPer {
fons: Box<NodusSerializabilis>,
clavis: Expressio,
meta: MetadataNodi,
},
Fragmentum {
fons: Box<NodusSerializabilis>,
magnitudo: usize,
},
Fenestra {
fons: Box<NodusSerializabilis>,
magnitudo: usize,
gradus: usize,
},
Parallela {
sinister: Box<NodusSerializabilis>,
dexter: Box<NodusSerializabilis>,
meta: MetadataNodi,
},
Certamen {
sinister: Box<NodusSerializabilis>,
dexter: Box<NodusSerializabilis>,
meta: MetadataNodi,
},
Ramus {
condicio: Box<NodusSerializabilis>,
tunc: Box<NodusSerializabilis>,
aliter: Box<NodusSerializabilis>,
meta: MetadataNodi,
},
Circuitus {
corpus: Box<NodusSerializabilis>,
condicio: CondicioCircuitus,
meta: MetadataNodi,
},
Effice {
fons: Box<NodusSerializabilis>,
effectus_id: u64,
operatio: Expressio,
meta: MetadataNodi,
},
Tracta {
fons: Box<NodusSerializabilis>,
tractator: TractatorSerializabilis,
meta: MetadataNodi,
},
Fusio(Box<NodusSerializabilis>),
Vectoriza(Box<NodusSerializabilis>),
GpuIndica(Box<NodusSerializabilis>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OperatioAggregationis {
Summa,
Productum,
Minimum,
Maximum,
Media,
Primus,
Ultimus,
}
#[derive(Debug, Clone)]
pub enum CondicioCircuitus {
Infinitus,
Numerus(usize),
Dum(Expressio),
Donec(Expressio),
}
#[derive(Debug, Clone)]
pub struct TractatorSerializabilis {
pub effectus_id: u64,
pub implementatio: Expressio,
pub profundus: bool,
}
pub trait AdSerializabilis {
type Serializabilis;
fn ad_serializabilis(&self) -> Self::Serializabilis;
}
pub trait ExSerializabilis: Sized {
type Serializabilis;
type Error;
fn ex_serializabilis(ser: Self::Serializabilis) -> Result<Self, Self::Error>;
}
pub struct Ambitus {
variabiles: Vec<ValorConstans>,
nominati: Vec<(String, ValorConstans)>,
}
impl Ambitus {
#[inline]
pub fn new() -> Self {
Ambitus {
variabiles: Vec::with_capacity(8),
nominati: Vec::with_capacity(8),
}
}
#[inline]
pub fn push(&mut self, valor: ValorConstans) {
self.variabiles.push(valor);
}
#[inline]
pub fn pop(&mut self) -> Option<ValorConstans> {
self.variabiles.pop()
}
#[inline]
pub fn get(&self, index: usize) -> Option<&ValorConstans> {
let len = self.variabiles.len();
if index < len {
Some(&self.variabiles[len - 1 - index])
} else {
None
}
}
#[inline]
pub fn bind(&mut self, nomen: String, valor: ValorConstans) {
self.nominati.push((nomen, valor));
}
#[inline]
pub fn lookup(&self, nomen: &str) -> Option<&ValorConstans> {
for (n, v) in self.nominati.iter().rev() {
if n == nomen {
return Some(v);
}
}
None
}
}
impl Default for Ambitus {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub enum ErrorEvaluationis {
VariabilisNonInventa(String),
TypusDiscrepans {
expectatus: String,
inventus: String,
},
DivisioPerNullum,
ConformatioDefecit,
OperatioInvalida(String),
}
impl fmt::Display for ErrorEvaluationis {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ErrorEvaluationis::VariabilisNonInventa(name) => {
write!(f, "Variable not found: {name}")
}
ErrorEvaluationis::TypusDiscrepans {
expectatus,
inventus,
} => {
write!(f, "Type mismatch: expected {expectatus}, found {inventus}")
}
ErrorEvaluationis::DivisioPerNullum => {
write!(f, "Division by zero")
}
ErrorEvaluationis::ConformatioDefecit => {
write!(f, "Pattern match failed")
}
ErrorEvaluationis::OperatioInvalida(msg) => {
write!(f, "Invalid operation: {msg}")
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_nodus_id() {
let id1 = NodusId::new(1);
let id2 = NodusId::new(2);
assert_ne!(id1, id2);
assert_eq!(id1, NodusId::new(1));
}
#[test]
fn test_valor_constans_f64() {
let v = ValorConstans::from_f64(2.5);
let f = v
.as_f64()
.expect("ValorConstans::from_f64 should produce an F64 variant");
assert!((f - 2.5).abs() < f64::EPSILON);
}
#[test]
fn test_expressio_identity() {
let expr = Expressio::Identitas;
assert!(matches!(expr, Expressio::Identitas));
}
#[test]
fn test_expressio_arithmetic() {
let expr = Expressio::Arithmetica(
OperatioArithmetica::Additio,
Box::new(Expressio::Constans(ValorConstans::I32(1))),
Box::new(Expressio::Constans(ValorConstans::I32(2))),
);
assert!(matches!(
expr,
Expressio::Arithmetica(OperatioArithmetica::Additio, _, _)
));
}
#[test]
fn test_ambitus() {
let mut env = Ambitus::new();
env.push(ValorConstans::I32(42));
assert_eq!(
env.get(0).and_then(|v| match v {
ValorConstans::I32(n) => Some(*n),
_ => None,
}),
Some(42)
);
}
#[test]
fn test_nodus_serializabilis_range() {
let node = NodusSerializabilis::Intervallum {
initium: 0,
finis: 100,
gradus: 1,
};
assert!(matches!(node, NodusSerializabilis::Intervallum { .. }));
}
}