use crate::obj::{prelude::*, reserved::*}; use once_cell::sync::Lazy; use shredder::Scan; use std::fmt::{Debug, Formatter, self}; pub type IntRef = ObjRef; #[derive(Scan)] pub struct Int { value: i64, vtable: Vtable, attrs: Attrs, } impl Int { pub fn new_obj(value: i64) -> ObjRef { // TODO : cache int values self_referring_obj! { Self { value, vtable: Default::default(), attrs: Default::default(), }, vtable: |obj_ref: ObjRef| vtable! { // TODO needs Method type so this function is given an argument when called STR_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), INT_STR_FUN.clone()), } } } pub fn value(&self) -> i64 { self.value } } impl_obj_readonly!(Int); impl Debug for Int { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fmt.debug_struct("Int") .field("value", &self.value) .finish() } } static INT_STR_FUN: Lazy = Lazy::new(|| { NativeFun::new_obj(|_callee, vm, args| { read_obj!(let int_obj = &args[0]); if let Some(int_obj) = std::any::Any::downcast_ref::(int_obj.as_any()) { vm.push(Str::new_obj(int_obj.value.to_string())); } else { panic!("{:?} is not an int", int_obj) } crate::vm::signal::Signal::Return }) });