//! CNNL抽象语法树(AST)定义 use serde::{Deserialize, Serialize}; /// 程序(顶层节点) #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Program { pub clauses: Vec, /// 测试块(test "..." { assert ... }) #[serde(default)] pub tests: Vec, } /// 宪法条款 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Clause { /// 条款标识符(全大写) pub id: String, /// 条款层级 pub level: ClauseLevel, /// 条款标题 pub title: String, /// 条款名称(name: 字段,可选) #[serde(skip_serializing_if = "Option::is_none")] pub name: Option, /// 版本号(version: 字段,可选) #[serde(skip_serializing_if = "Option::is_none")] pub version: Option, /// 描述(description: 字段,可选) #[serde(skip_serializing_if = "Option::is_none")] pub description: Option, /// 依赖的其他条款 pub depends_on: Vec, /// 参数列表 pub parameters: Vec, /// 谓词列表 pub predicates: Vec, /// 义务列表 pub obligations: Vec, } /// 条款层级 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ClauseLevel { /// 永恒条款(不可修改) Eternal, /// 战略条款(需要超级多数修改) Strategic, /// 战术条款(普通多数修改) Tactical, } 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"), } } } /// 参数 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Parameter { pub name: String, /// 参数类型 pub ty: Type, pub value: Literal, /// 参数描述(可选) #[serde(skip_serializing_if = "Option::is_none")] pub description: Option, } /// 谓词 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Predicate { pub name: String, pub params: Vec<(String, Type)>, pub return_type: Type, /// 函数体(AST 表达式) pub body: Expression, } /// 义务 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Obligation { pub name: String, pub frequency: ObligationFrequency, pub enforcer: String, pub penalty: String, /// 义务描述(可选) #[serde(skip_serializing_if = "Option::is_none")] pub description: Option, } /// 义务频率 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum ObligationFrequency { Continuous, // 持续 Periodic, // 周期性 OnDemand, // 按需 } impl std::fmt::Display for ObligationFrequency { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { ObligationFrequency::Continuous => write!(f, "continuous"), ObligationFrequency::Periodic => write!(f, "periodic"), ObligationFrequency::OnDemand => write!(f, "on_demand"), } } } /// 类型 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum Type { Bool, U64, U32, U128, F64, String, } 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::U128 => write!(f, "u128"), Type::F64 => write!(f, "f64"), Type::String => write!(f, "string"), } } } /// 字面量 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum Literal { Bool(bool), Int(u64), Float(f64), String(String), } impl std::fmt::Display for Literal { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { Literal::Bool(b) => write!(f, "{}", b), Literal::Int(n) => write!(f, "{}", n), Literal::Float(n) => write!(f, "{}", n), Literal::String(s) => write!(f, "\"{}\"", s), } } } /// 表达式 #[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), // 原始字符串(解析器无法完整解析时的降级表示) Raw(String), } /// 二元运算符 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum BinaryOp { // 算术运算 Add, Sub, Mul, Div, Mod, // 比较运算 Eq, Ne, Lt, Le, Gt, Ge, // 逻辑运算 And, Or, } 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, "||"), } } } /// 一元运算符 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum UnaryOp { Not, Neg, } 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, "-"), } } } /// 语句 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum Statement { // 表达式语句 Expression(Expression), // 返回语句 Return(Expression), // 变量声明 Let { name: String, ty: Option, value: Expression, }, } /// 测试块 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct TestBlock { pub description: String, pub assertions: Vec, } #[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(), name: None, version: None, description: None, 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"), } } }