From fffbd14d4226ee32c02d06a4a78248fe14000103 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Sat, 6 Jun 2026 09:52:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AF=B9=E5=B0=8F=E6=95=B4=E6=95=B0?= =?UTF-8?q?=E5=81=9A=E9=A2=9D=E5=A4=96=E6=9E=9A=E4=B8=BE=E4=BB=A5=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_compiler/src/compiler.rs | 10 +++++++++- crates/oxide_compiler/src/module.rs | 1 + crates/oxide_compiler/tests/compiler_tests.rs | 4 ++-- crates/oxide_vm/src/vm.rs | 1 + crates/oxide_vm/tests/vm_tests.rs | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/oxide_compiler/src/compiler.rs b/crates/oxide_compiler/src/compiler.rs index 7322cddc..9c0628f2 100644 --- a/crates/oxide_compiler/src/compiler.rs +++ b/crates/oxide_compiler/src/compiler.rs @@ -8,6 +8,10 @@ pub use oxide_parser::{BinaryOperator, Expression, Statement, UnaryOperator}; pub struct Compiler; +fn is_int_literal(value: f64) -> bool { + value.fract() == 0.0 && value >= i32::MIN as f64 && value <= i32::MAX as f64 +} + struct CompileCtx { bytecode: Vec, constants: Vec, @@ -312,7 +316,11 @@ impl Compiler { fn emit_expression(&self, expr: &Expression, ctx: &mut CompileCtx) -> Result { match expr { Expression::NumericLiteral(n) => { - let idx = ctx.add_constant(Constant::Number(n.value)); + let idx = if is_int_literal(n.value) { + ctx.add_constant(Constant::Int(n.value as i32)) + } else { + ctx.add_constant(Constant::Number(n.value)) + }; let r = ctx.alloc_reg(); ctx.emit(opcode::encode( OpCode::LOAD_CONST, diff --git a/crates/oxide_compiler/src/module.rs b/crates/oxide_compiler/src/module.rs index ff024a4b..5d658940 100644 --- a/crates/oxide_compiler/src/module.rs +++ b/crates/oxide_compiler/src/module.rs @@ -5,6 +5,7 @@ use crate::opcode::{self, OpCode}; #[derive(Debug, Clone, PartialEq)] pub enum Constant { Number(f64), + Int(i32), String(String), Boolean(bool), Null, diff --git a/crates/oxide_compiler/tests/compiler_tests.rs b/crates/oxide_compiler/tests/compiler_tests.rs index 4aa86335..74122b39 100644 --- a/crates/oxide_compiler/tests/compiler_tests.rs +++ b/crates/oxide_compiler/tests/compiler_tests.rs @@ -34,7 +34,7 @@ fn compile_constants() { assert!(!module.constants.is_empty()); assert_eq!( module.constants[0], - oxide_compiler::compiler::Constant::Number(42.0) + oxide_compiler::compiler::Constant::Int(42) ); } @@ -120,7 +120,7 @@ fn compile_var_declaration() { assert!(!module.bytecode.is_empty()); assert_eq!( module.constants[0], - oxide_compiler::compiler::Constant::Number(42.0) + oxide_compiler::compiler::Constant::Int(42) ); } diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index 0cb505e7..37546fe1 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -113,6 +113,7 @@ impl Vm { .iter() .map(|c| match c { Constant::Number(v) => JsValue::float(*v), + Constant::Int(v) => JsValue::int(*v), Constant::String(s) => self.intern(s), Constant::Boolean(b) => JsValue::bool(*b), Constant::Null => JsValue::null(), diff --git a/crates/oxide_vm/tests/vm_tests.rs b/crates/oxide_vm/tests/vm_tests.rs index 4c52c4e6..1ffd831b 100644 --- a/crates/oxide_vm/tests/vm_tests.rs +++ b/crates/oxide_vm/tests/vm_tests.rs @@ -34,7 +34,7 @@ fn object_create_and_read() { assert!(obj.is_object()); let obj_ref = unsafe { &*obj.as_js_object_ptr() }; assert_eq!(obj_ref.prop_count(), 1, "object should have 1 property"); - assert!(obj_ref.get_inline_prop(0).is_double()); + assert!(obj_ref.get_inline_prop(0).is_int()); } #[test]