Functions are implemented and VM should be able to handle function calls
* VM Signals are used by running functions to dictate whether a function should return, or if it should call another function. These signals can be injected at any time allowing for user functions to inject themselves at runtime. * obj::Method is gone since it's not being used yet. * Obj impls must implement as_any(&self) -> &dyn Any now. This allows for UserFun and NativeFun to be explicitly cast (among other things, in the future). Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -1,34 +1,8 @@
|
||||
use crate::{obj::{reserved::*, prelude::*}, vm::{inst::Inst, Vm}};
|
||||
use crate::{obj::{reserved::*, prelude::*}, vm::{inst::Inst, signal::*, Vm}};
|
||||
use once_cell::sync::Lazy;
|
||||
use shredder::{GcSafeWrapper, Scan};
|
||||
use std::fmt::{Debug, Formatter, self};
|
||||
|
||||
#[derive(Debug, Scan)]
|
||||
pub struct Method {
|
||||
vtable: Vtable,
|
||||
attrs: Attrs,
|
||||
}
|
||||
|
||||
impl Method {
|
||||
pub fn new(this: ObjRef, func: ObjRef) -> Self {
|
||||
Self {
|
||||
vtable: Default::default(),
|
||||
attrs: attrs! {
|
||||
SELF_MEMBER_NAME.sym => this,
|
||||
FUNC_MEMBER_NAME.sym => func,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_obj!(Method);
|
||||
|
||||
pub static CALL_METHOD_WRAPPER_FUN: Lazy<ObjRef<NativeFun>> = Lazy::new(|| {
|
||||
NativeFun::new_obj(Box::new(|_vm, _fun, _args| {
|
||||
todo!("__call__ function")
|
||||
}))
|
||||
});
|
||||
|
||||
//
|
||||
// struct UserFun
|
||||
//
|
||||
@@ -48,6 +22,27 @@ pub struct UserFun {
|
||||
}
|
||||
|
||||
impl UserFun {
|
||||
pub fn new_obj(code: Vec<Inst>, locals: Names) -> UserFunRef {
|
||||
let obj_ref = ObjRef::new(UserFun {
|
||||
vtable: Default::default(), // this is a placeholder for the real vtable
|
||||
attrs: Default::default(),
|
||||
code,
|
||||
locals,
|
||||
});
|
||||
|
||||
// XXX replace the vtable before returning, since __call__ member points to the object
|
||||
// itself
|
||||
{
|
||||
write_obj!(let obj = obj_ref);
|
||||
obj.vtable = vtable! {
|
||||
TY_MEMBER_NAME.sym => USER_FUN_TY.clone(),
|
||||
CALL_MEMBER_NAME.sym => obj_ref.clone(),
|
||||
};
|
||||
}
|
||||
|
||||
obj_ref
|
||||
}
|
||||
|
||||
pub fn code(&self) -> &Vec<Inst> {
|
||||
&self.code
|
||||
}
|
||||
@@ -69,11 +64,14 @@ impl Debug for UserFun {
|
||||
}
|
||||
}
|
||||
|
||||
pub static USER_FUN_TY: Lazy<ObjRef<Ty>> = Lazy::new(|| Ty::new_obj(USER_FUN_NAME.sym_ref()));
|
||||
|
||||
//
|
||||
// struct NativeFun
|
||||
//
|
||||
|
||||
pub type NativeFunPtr = Box<dyn Fn(&mut Vm, ObjRef, Vec<ObjRef>) + Send + Sync>;
|
||||
pub type NativeFunPtr = Box<dyn (Fn(ObjRef, &mut Vm, Vec<ObjRef>) -> Signal) + Send + Sync>;
|
||||
pub type NativeFunRef = ObjRef<NativeFun>;
|
||||
|
||||
#[derive(Scan)]
|
||||
pub struct NativeFun {
|
||||
@@ -89,12 +87,29 @@ pub struct NativeFun {
|
||||
|
||||
impl NativeFun {
|
||||
pub fn new_obj(fun: NativeFunPtr) -> ObjRef<Self> {
|
||||
ObjRef::new(Self {
|
||||
// TODO : vtable for NativeFun
|
||||
let obj_ref = ObjRef::new(Self {
|
||||
vtable: Default::default(),
|
||||
attrs: Default::default(),
|
||||
fun: GcSafeWrapper::new(fun),
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
// XXX replace the vtable before returning, since __call__ member points to the object
|
||||
// itself
|
||||
{
|
||||
write_obj!(let obj = obj_ref);
|
||||
obj.vtable = vtable! {
|
||||
TY_MEMBER_NAME.sym => NATIVE_FUN_TY.clone(),
|
||||
CALL_MEMBER_NAME.sym => obj_ref.clone(),
|
||||
};
|
||||
}
|
||||
|
||||
obj_ref
|
||||
}
|
||||
|
||||
/// Gets the native function that can be invoked.
|
||||
pub fn fun(&self) -> &NativeFunPtr {
|
||||
&self.fun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +128,8 @@ impl Debug for NativeFun {
|
||||
|
||||
impl_obj!(NativeFun);
|
||||
|
||||
pub static NATIVE_FUN_TY: Lazy<ObjRef<Ty>> = Lazy::new(|| Ty::new_obj(NATIVE_FUN_NAME.sym_ref()));
|
||||
|
||||
//
|
||||
// Native function defs
|
||||
//
|
||||
@@ -121,7 +138,7 @@ impl_obj!(NativeFun);
|
||||
// __get_attr__ *should* always bypass the __access__ function and get an attribute directly
|
||||
|
||||
pub static GET_ATTR_MEMBER_FUN: Lazy<ObjRef<NativeFun>> = Lazy::new(|| {
|
||||
NativeFun::new_obj(Box::new(|_vm, _fun, _args| {
|
||||
NativeFun::new_obj(Box::new(|_caller, _vm, _args| {
|
||||
/*
|
||||
let sym_ref = vm.pop();
|
||||
let obj_ref = vm.pop();
|
||||
|
||||
Reference in New Issue
Block a user