260 lines
6.1 KiB
Rust
260 lines
6.1 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
/// CNNL抽象语法树根节点
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Program {
|
|
pub clauses: Vec<Clause>,
|
|
}
|
|
|
|
/// 宪法条款
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Clause {
|
|
pub id: String,
|
|
pub level: ClauseLevel,
|
|
pub title: String,
|
|
pub depends_on: Vec<String>,
|
|
pub parameters: Vec<Parameter>,
|
|
pub predicates: Vec<Predicate>,
|
|
pub obligations: Vec<Obligation>,
|
|
}
|
|
|
|
/// 条款层级
|
|
#[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<String>,
|
|
}
|
|
|
|
/// 宪法谓词
|
|
#[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<Expression>,
|
|
right: Box<Expression>,
|
|
},
|
|
|
|
// 一元运算
|
|
Unary {
|
|
op: UnaryOp,
|
|
operand: Box<Expression>,
|
|
},
|
|
|
|
// 函数调用
|
|
Call {
|
|
name: String,
|
|
args: Vec<Expression>,
|
|
},
|
|
|
|
// if表达式
|
|
If {
|
|
condition: Box<Expression>,
|
|
then_branch: Box<Expression>,
|
|
else_branch: Option<Box<Expression>>,
|
|
},
|
|
|
|
// 代码块
|
|
Block(Vec<Statement>),
|
|
}
|
|
|
|
/// 二元运算符
|
|
#[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<Type>,
|
|
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"),
|
|
}
|
|
}
|
|
}
|