feat: num-bigint 接入任意精度 BigInt(字面量、算术、toString、asIntN/asUintN)

This commit is contained in:
2026-08-12 03:15:18 +08:00
parent 4474702735
commit 1824ef0df1
18 changed files with 227 additions and 212 deletions
+1
View File
@@ -13,4 +13,5 @@ oxide_ir = { path = "../oxide_ir" }
oxide_log = { path = "../oxide_log" }
regex.workspace = true
regress.workspace = true
num-bigint = "0.4"
+3 -8
View File
@@ -242,7 +242,7 @@ impl ParamSpec<'_> {
enum ConstantKey {
Number(u64),
Int(i32),
BigInt(i128),
BigInt(num_bigint::BigInt),
String(String),
Boolean(bool),
Null,
@@ -643,7 +643,7 @@ impl ConstantKey {
match value {
Constant::Number(v) => Some(Self::Number(v.to_bits())),
Constant::Int(v) => Some(Self::Int(*v)),
Constant::BigInt(v) => Some(Self::BigInt(*v)),
Constant::BigInt(v) => Some(Self::BigInt(v.clone())),
Constant::String(v) => Some(Self::String(v.clone())),
Constant::Boolean(v) => Some(Self::Boolean(*v)),
Constant::Null => Some(Self::Null),
@@ -673,12 +673,7 @@ impl Emitter {
let msg_idx = ctx.add_constant(Constant::String(msg.to_string()));
ctx.inst(Inst::load_const(Operand::Reg(msg_reg), msg_idx));
let exc_reg = ctx.alloc_reg();
ctx.inst(Inst::new_expression(
Operand::Reg(exc_reg),
Operand::Reg(ctor),
Operand::Reg(msg_reg),
1,
));
ctx.inst(Inst::new_expression(Operand::Reg(exc_reg), Operand::Reg(ctor), Operand::Reg(msg_reg), 1));
ctx.inst(Inst::new(OpCode::THROW, Operand::Reg(exc_reg), Operand::None, Operand::None));
let dummy = ctx.alloc_reg();
let undef_idx = ctx.add_constant(Constant::Undefined);
+6 -4
View File
@@ -37,10 +37,12 @@ impl Emitter {
fn emit_bigint_literal_expression(
&self, b: &oxide_parser::BigIntLiteral, ctx: &mut CompileCtx,
) -> Result<u32, String> {
let value = b
.value
.parse::<i128>()
.map_err(|_| format!("BigInt literal out of range: {}", b.value))?;
let value = if let Ok(v) = b.value.parse::<i128>() {
num_bigint::BigInt::from(v)
} else {
num_bigint::BigInt::parse_bytes(b.value.as_bytes(), 10)
.ok_or_else(|| format!("BigInt literal out of range: {}", b.value))?
};
let idx = ctx.add_constant(Constant::BigInt(value));
let r = ctx.alloc_reg();
ctx.inst(Inst::load_const(Operand::Reg(r), idx));