use serde::{Deserialize, Serialize}; /// CNNL抽象语法树根节点 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Program { pub clauses: Vec, } /// 宪法条款 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Clause { pub id: String, pub level: ClauseLevel, pub title: String, pub depends_on: Vec, pub parameters: Vec, pub predicates: Vec, pub obligations: Vec, } /// 条款层级 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum ClauseLevel { Eternal, // 永恒条款 Strategic, // 战略条款 Tactical, // 战术条款 } /// 宪法参数 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Parameter { pub name: String, pub ty: Type, pub value: Literal, pub description: Option, } /// 宪法谓词 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Predicate { pub name: String, pub params: Vec<(String, Type)>, pub return_type: Type, pub body: Expression, } /// 宪法义务 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Obligation { pub name: String, pub frequency: ObligationFrequency, pub enforcer: String, pub penalty: String, } /// 义务频率 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum ObligationFrequency { Continuous, // 持续 Periodic, // 周期性 OnDemand, // 按需 } /// 类型 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum Type { Bool, U64, U32, F64, String, } /// 字面量 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum Literal { Bool(bool), Int(u64), Float(f64), String(String), } /// 表达式 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum Expression { // 字面量 Literal(Literal), // 变量引用 Variable(String), // 二元运算 Binary { op: BinaryOp, left: Box, right: Box, }, // 一元运算 Unary { op: UnaryOp, operand: Box, }, // 函数调用 Call { name: String, args: Vec, }, // if表达式 If { condition: Box, then_branch: Box, else_branch: Option>, }, // 代码块 Block(Vec), } /// 二元运算符 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum BinaryOp { // 算术运算 Add, Sub, Mul, Div, Mod, // 比较运算 Eq, Ne, Lt, Le, Gt, Ge, // 逻辑运算 And, Or, } /// 一元运算符 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum UnaryOp { Not, Neg, } /// 语句 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum Statement { // 表达式语句 Expression(Expression), // 返回语句 Return(Expression), // 变量声明 Let { name: String, ty: Option, value: Expression, }, } impl std::fmt::Display for ClauseLevel { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { ClauseLevel::Eternal => write!(f, "eternal"), ClauseLevel::Strategic => write!(f, "strategic"), ClauseLevel::Tactical => write!(f, "tactical"), } } } impl std::fmt::Display for Type { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { Type::Bool => write!(f, "bool"), Type::U64 => write!(f, "u64"), Type::U32 => write!(f, "u32"), Type::F64 => write!(f, "f64"), Type::String => write!(f, "string"), } } } impl std::fmt::Display for BinaryOp { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { BinaryOp::Add => write!(f, "+"), BinaryOp::Sub => write!(f, "-"), BinaryOp::Mul => write!(f, "*"), BinaryOp::Div => write!(f, "/"), BinaryOp::Mod => write!(f, "%"), BinaryOp::Eq => write!(f, "=="), BinaryOp::Ne => write!(f, "!="), BinaryOp::Lt => write!(f, "<"), BinaryOp::Le => write!(f, "<="), BinaryOp::Gt => write!(f, ">"), BinaryOp::Ge => write!(f, ">="), BinaryOp::And => write!(f, "&&"), BinaryOp::Or => write!(f, "||"), } } } impl std::fmt::Display for UnaryOp { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { UnaryOp::Not => write!(f, "!"), UnaryOp::Neg => write!(f, "-"), } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_clause_creation() { let clause = Clause { id: "XTZH_GOLD_COVERAGE".to_string(), level: ClauseLevel::Eternal, title: "黄金储备覆盖率底线".to_string(), depends_on: vec![], parameters: vec![Parameter { name: "XTZH_GOLD_COVERAGE_MIN".to_string(), ty: Type::F64, value: Literal::Float(1.25), description: Some("最低黄金覆盖率".to_string()), }], predicates: vec![], obligations: vec![], }; assert_eq!(clause.id, "XTZH_GOLD_COVERAGE"); assert_eq!(clause.level, ClauseLevel::Eternal); assert_eq!(clause.parameters.len(), 1); } #[test] fn test_expression_creation() { let expr = Expression::Binary { op: BinaryOp::Ge, left: Box::new(Expression::Variable("coverage".to_string())), right: Box::new(Expression::Literal(Literal::Float(1.25))), }; match expr { Expression::Binary { op, .. } => assert_eq!(op, BinaryOp::Ge), _ => panic!("Expected Binary expression"), } } }