* Methods are wrappers created with an owner and a function, which passes the owner as the first argument when the function is called. * Fix a small bug in the VM where the pc was being set at the wrong time Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
57 lines
1.4 KiB
Rust
57 lines
1.4 KiB
Rust
use crate::obj::{prelude::*, reserved::*};
|
|
use once_cell::sync::Lazy;
|
|
use shredder::Scan;
|
|
use std::fmt::{Debug, Formatter, self};
|
|
|
|
pub type IntRef = ObjRef<Int>;
|
|
|
|
#[derive(Scan)]
|
|
pub struct Int {
|
|
value: i64,
|
|
vtable: Vtable,
|
|
attrs: Attrs,
|
|
}
|
|
|
|
impl Int {
|
|
pub fn new_obj(value: i64) -> ObjRef<Self> {
|
|
// 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<NativeFunRef> = 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>(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
|
|
})
|
|
});
|