diff --git a/crates/oxide_compiler/src/compiler.rs b/crates/oxide_compiler/src/compiler.rs index 7322cdd..9c0628f 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 ff024a4..5d65894 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 4aa8633..74122b3 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 0cb505e..37546fe 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 4c52c4e..1ffd831 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]