NAC_Blockchain/cnnl-compiler/src/parser/ast.rs

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"),
}
}
}