// MoonDatalog —— 值类型(Value)
//
// Datalog 程序中的基本数据值。经典 Datalog 只有符号常量,
// 本引擎额外支持字符串、整数与浮点数,以覆盖更广泛的
// 数据处理与查询场景(图分析、配置校验、数据管道等)。
///|
/// 一个 Datalog 数据值。
///
/// 四种构造子按全序排列:符号常量 < 字符串 < 整数 < 浮点数。
/// 该顺序保证元组与关系具备确定的字典序,便于排序与去重。
pub enum Value {
/// 符号常量,如 `alice`(由小写标识符构成)
Sym(String)
/// 字符串常量,如 `"hello"`(带引号字面量)
Str(String)
/// 64 位有符号整数,如 `42`、`-7`
Int(Int64)
/// IEEE-754 双精度浮点数,如 `3.14`、`1e-9`
Float(Double)
} derive(Eq, Hash, Compare, @debug.Debug)
///|
/// 将值渲染为 Datalog 字面量文本:
/// 符号原样输出,字符串加引号并转义,整数十进制,浮点数保留小数形式。
pub impl Show for Value with fn to_string(self : Value) -> String {
match self {
Sym(s) => s
Str(s) => quote_string(s)
Int(i) => i.to_string()
Float(f) => format_double(f)
}
}
///|
/// 为字符串字面量加引号并转义 `"` 与 `\`。
fn quote_string(s : String) -> String {
let b = StringBuilder::new()
b.write_char('"')
for c in s.iter() {
match c {
'"' => b.write_string("\\\"")
'\\' => b.write_string("\\\\")
'\n' => b.write_string("\\n")
'\r' => b.write_string("\\r")
'\t' => b.write_string("\\t")
_ => b.write_char(c)
}
}
b.write_char('"')
b.to_string()
}
///|
/// 浮点数的确定化输出:整数型浮点输出为 `3.0` 形式,避免与整数歧义;
/// 其余按核心库默认表示(含指数或小数)。
fn format_double(f : Double) -> String {
if f.is_nan() || f.is_inf() {
return f.to_string()
}
let s = f.to_string()
if s.contains_char('.') || s.contains_char('e') || s.contains_char('E') {
return s
}
s + ".0"
}
///|
/// 解析一个十进制整数字面量(可为负)。失败返回 `None`。
pub fn parse_int(s : String) -> Value? {
let parsed : Int64? = Some(@string.parse_int64(s)) catch { _ => None }
match parsed {
Some(i) => Some(Int(i))
None => None
}
}
///|
/// 解析一个十进制浮点字面量(可为负、可含指数)。失败返回 `None`。
pub fn parse_float(s : String) -> Value? {
let parsed : Double? = Some(@string.parse_double(s)) catch { _ => None }
match parsed {
Some(f) => Some(Float(f))
None => None
}
}
///|
/// 将任意字面量文本(数字或标识符)规约为 Value:
/// 可解析为整数则取整数,否则可解析为浮点则取浮点,否则视为符号常量。
pub fn from_literal(s : String) -> Value {
match parse_int(s) {
Some(v) => v
None =>
match parse_float(s) {
Some(v) => v
None => Sym(s)
}
}
}
///|
/// 值的确定化全序比较:
/// - 同类数值按数值比较(Int/Float 混合按浮点);
/// - 符号 / 字符串按字典序(`lexical_compare`,注意非 `String::compare`);
/// - 跨类别按 符号 < 字符串 < 整数 < 浮点 的固定序。
pub fn compare_values(a : Value, b : Value) -> Int {
match (a, b) {
(Int(x), Int(y)) => x.compare(y)
(Float(x), Float(y)) => x.compare(y)
(Int(x), Float(y)) => x.to_double().compare(y)
(Float(x), Int(y)) => x.compare(y.to_double())
(Sym(x), Sym(y)) => x.lexical_compare(y)
(Str(x), Str(y)) => x.lexical_compare(y)
(Sym(_), _) => -1
(_, Sym(_)) => 1
(Str(_), _) => -1
(_, Str(_)) => 1
}
}
///|
/// 构造符号常量(供外部使用,等价于公开枚举构造子)。
pub fn sym(s : String) -> Value {
Sym(s)
}
///|
/// 构造字符串常量。
pub fn str_const(s : String) -> Value {
Str(s)
}
///|
/// 构造整数常量。
pub fn int_const(i : Int64) -> Value {
Int(i)
}
///|
/// 构造浮点常量。
pub fn float_const(f : Double) -> Value {
Float(f)
}