docs(objects): clarify numeric conversion and wordcode boundaries

This commit is contained in:
2026-11-15 19:40:52 +08:00
parent ca61378c92
commit 262edf4351
2 changed files with 21 additions and 8 deletions
+3 -1
View File
@@ -152,7 +152,7 @@ impl Instruction {
pub const fn new(opcode: Opcode, argument: u32) -> Self {
Self { opcode, argument }
}
/// 编译器发出无参数指令的便捷入口,把 argument 明确置零。
/// 编译器发出无参数指令的便捷入口,把 argument 明确置零;此处不检查 opcode 是否真的无参数。
pub const fn simple(opcode: Opcode) -> Self {
Self::new(opcode, 0)
}
@@ -195,6 +195,7 @@ impl Instruction {
/// EndorCode::from_instructions 调用:小操作数直接编码,大操作数最多用三个前缀。
/// 每单元两字节,前缀携带高位;不在这里重算跳转距离或校验常量/槽索引。
/// 空输入可编码为空字节串,EndorCode 的后续解码才拒绝空代码,编码成功不等于可执行。
pub fn encode_all(instructions: &[Self]) -> Result<Vec<u8>, VmError> {
// 逐条追加;报错时局部缓冲丢弃,不向调用者返回部分编码。
let mut bytes = Vec::new();
@@ -222,6 +223,7 @@ impl Instruction {
}
}
/// 解码器产出、代码校验器和 eval 消费的逻辑位置;公开字段本身不保证由验证过的代码产生。
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DecodedInstruction {
/// 逻辑指令起点(包括首个前缀),单位是双字节代码单元。
+18 -7
View File
@@ -10,6 +10,7 @@ use std::fmt;
use crate::{CompareOp, ObjectPayload, ObjectRef, VmError};
#[derive(Debug, Clone, PartialEq, Eq)]
/// 编译器字面量和精确运算的规范整数;仅保存符号和数字,构造不执行算术预算。
pub struct EndorInteger {
/// 规范化整数符号,零为 false。
negative: bool,
@@ -80,6 +81,7 @@ impl fmt::Display for EndorInteger {
}
#[derive(Debug, Clone, PartialEq, Eq)]
/// 编译器保留原拼写的十进制值;表示相等会区分 1.0 与 1.00,数学比较另走 numeric_compare。
pub struct EndorDecimal {
/// 已验证但未规范化的原十进制字面量。
literal: String,
@@ -160,7 +162,7 @@ pub struct EndorRational {
impl EndorRational {
/// Normalizes denominator sign, without reducing or rounding the fraction.
/// 宿主/Store 构造当前数值表示或载荷,具体不变量见下方构造步骤。
/// EndorNumber::rational 把已解析的整数交到这里;只校正分母符号,不执行约分或运算预算。
pub fn new(
mut numerator: EndorInteger,
mut denominator: EndorInteger,
@@ -204,8 +206,11 @@ impl fmt::Display for EndorRational {
/// Internal storage forms within one Endor number API, not language classes.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EndorReal {
/// 已规范符号和前导零的整数。
Integer(EndorInteger),
/// 保留符号、尾零和指数原拼写的十进制值。
Decimal(EndorDecimal),
/// 正分母的精确分数;构造阶段不保证已约分。
Rational(EndorRational),
/// IEEE-754 bits preserve signed zero, infinities and NaN payloads.
BinaryFloat(u64),
@@ -242,7 +247,9 @@ impl fmt::Display for EndorReal {
/// Language-level comparison and hashing are not defined by these Rust traits.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EndorNumber {
/// VM 算术、比较和图形收窄接受的实数表示。
Real(EndorReal),
/// 可保存、显示并判断真值;当前算术与数学比较均拒绝此变体。
Complex {
/// 复数实部分量。
real: EndorReal,
@@ -334,13 +341,14 @@ impl fmt::Display for EndorNumber {
}
#[derive(Debug, Clone)]
/// Store::new_number 使用的堆载荷;与直接 Value::Number 共用数值语义,但需遵守托管句柄所有权。
pub struct EndorNumberObject {
/// 拥有数值表示,不含托管对象强边。
value: EndorNumber,
}
impl EndorNumberObject {
/// 宿主/Store 构造当前数值表示或载荷,具体不变量见下方构造步骤。
/// Store::new_number 在托管分配前包装数值;本方法不分配堆槽,也不新增外部根。
pub fn new(value: EndorNumber) -> Self {
Self { value }
}
@@ -444,7 +452,8 @@ impl EndorNumber {
}
/// Explicit narrowing for graphics/FFI boundaries; exact values themselves
/// retain their representation. Non-real or non-finite values are rejected.
/// 宿主图形/FFI 显式收窄,拒绝复数、非有限值和不可转换范围。
/// Tessera 图形桥在宿主边界显式收窄,结果可能舍入,不承诺精确往返;拒绝复数、非有限值和超范围结果。
/// 精确侧转换也受 exact_real 的文本/指数预算限制,能保存的字面量不一定能在此转换。
pub fn to_f64(&self) -> Result<f64, VmError> {
use num_traits::ToPrimitive;
// 先要求 Real,不能静默丢弃复数虚部。
@@ -465,7 +474,8 @@ impl EndorNumber {
}
Ok(value)
}
/// eval 二元算术:i64 安全快路径,任一浮点选择 float,否则精确有理数运算。
/// eval 的 BinaryArithmetic 使用:i64 安全快路径,任一浮点选择 float,否则精确有理数运算。
/// 精确运算受输入预算和结果 16384 位上限限制;成功结果规范为 Integer 或约分 Rational。
pub fn arithmetic(&self, other: &Self, op: ArithmeticOp) -> Result<Self, VmError> {
// 双方为可容纳 i64 的 Integer 才用快路径;运算溢出回退,不截断。
if let (Some(a), Some(b)) = (self.as_i64(), other.as_i64()) {
@@ -506,7 +516,7 @@ impl EndorNumber {
))
}
};
// 先要求两个输入均为实数;后续按精确/浮点模式转换。
// 将已确认的两个实数转换为浮点,精确侧在这里可能因预算或范围失败。
let (a, b) = (convert(a)?, convert(b)?);
// 两种运算模式都拒绝零除,包括浮点正负零。
if matches!(op, ArithmeticOp::Divide) && b == 0. {
@@ -525,9 +535,9 @@ impl EndorNumber {
}
return Ok(Self::binary_float(result));
}
// 先要求两个输入均为实数;后续按精确/浮点模式转换。
// 无浮点操作数时转为精确分数;转换先检查各表示的输入预算。
let (a, b) = (exact_real(a)?, exact_real(b)?);
// 两种运算模式都拒绝零除,包括浮点正负零。
// 精确除法同样拒绝零分母,零的不同精确表示已在转换后统一。
if matches!(op, ArithmeticOp::Divide) && b.is_zero() {
return Err(VmError::InvalidArgument("division by zero"));
}
@@ -552,6 +562,7 @@ impl EndorNumber {
}
}
/// eval/数值载荷数学比较,拒绝复数,处理 NaN 无序与无穷,不依赖 Rust Eq。
/// 有限混合比较把二进制浮点精确转为分数,不先舍入另一侧;精确转换仍可能因输入预算报错。
pub fn numeric_compare(&self, other: &Self, op: CompareOp) -> Result<bool, VmError> {
use std::cmp::Ordering;
// 先要求两个输入均为实数;后续按精确/浮点模式转换。