Fold runtime/ crate into this source tree
While I like the idea of having a runtime completely decoupled from the syntax and compiler, I don't think this is that big of a project for that to be necessary or even useful yet. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
129
src/obj/fun.rs
Normal file
129
src/obj/fun.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
use crate::{obj::{names::*, prelude::*}, vm::{inst::Inst, 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
|
||||
//
|
||||
#[derive(Scan)]
|
||||
pub struct UserFun {
|
||||
vtable: Vtable,
|
||||
attrs: Attrs,
|
||||
// Safe because Vec<Inst> doesn't need to be scanned
|
||||
#[shredder(unsafe_skip)]
|
||||
code: Vec<Inst>,
|
||||
// Safe because this is just an interner that points to symbols, which aren't GC'd
|
||||
#[shredder(unsafe_skip)]
|
||||
locals: Locals,
|
||||
}
|
||||
|
||||
impl UserFun {
|
||||
pub fn code(&self) -> &Vec<Inst> {
|
||||
&self.code
|
||||
}
|
||||
|
||||
pub fn locals(&self) -> &Locals {
|
||||
&self.locals
|
||||
}
|
||||
}
|
||||
|
||||
impl_obj!(UserFun);
|
||||
|
||||
impl Debug for UserFun {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
fmt.debug_struct("UserFun")
|
||||
.field("attrs", &self.attrs)
|
||||
.field("code", &self.code)
|
||||
.field("locals", &self.locals)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// struct NativeFun
|
||||
//
|
||||
|
||||
pub type NativeFunPtr = Box<dyn Fn(&mut Vm, ObjRef, Vec<ObjRef>) + Send + Sync>;
|
||||
|
||||
#[derive(Scan)]
|
||||
pub struct NativeFun {
|
||||
vtable: Vtable,
|
||||
attrs: Attrs,
|
||||
#[shredder(skip)]
|
||||
fun: GcSafeWrapper<NativeFunPtr>,
|
||||
}
|
||||
|
||||
//
|
||||
// impl NativeFun
|
||||
//
|
||||
|
||||
impl NativeFun {
|
||||
pub fn new_obj(fun: NativeFunPtr) -> ObjRef<Self> {
|
||||
ObjRef::new(Self {
|
||||
// TODO : vtable for NativeFun
|
||||
vtable: Default::default(),
|
||||
attrs: Default::default(),
|
||||
fun: GcSafeWrapper::new(fun),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// impl Debug for NativeFun
|
||||
//
|
||||
|
||||
impl Debug for NativeFun {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
fmt.debug_struct("NativeFun")
|
||||
.field("fun", &format!("(function at {:x})", &self.fun as *const _ as usize))
|
||||
.field("attrs", &self.attrs)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl_obj!(NativeFun);
|
||||
|
||||
//
|
||||
// Native function defs
|
||||
//
|
||||
|
||||
// __access__ is what the "dot" operator calls
|
||||
// __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| {
|
||||
/*
|
||||
let sym_ref = vm.pop();
|
||||
let obj_ref = vm.pop();
|
||||
obj_ref.access()
|
||||
*/
|
||||
todo!("__get_attr__ function")
|
||||
}))
|
||||
});
|
||||
Reference in New Issue
Block a user