#![allow(unused)]
use std::{cell::UnsafeCell, collections::HashMap, mem::transmute};
pub mod key;
use key::*;
#[repr(C)]
#[derive(Debug, Clone)]
pub struct Instance {
pub v: usize,
pub w: usize,
pub cls: Class
}
pub type NativeFn = fn(Vec<LitrRef>, Scope)-> Litr;
pub type NativeMethod = fn(&mut Instance, args:Vec<LitrRef>, Scope)-> Litr;
#[repr(C)]
#[derive(Debug, Clone)]
struct ClassInner {
name: Ident,
statics: Vec<(Ident, NativeFn)>,
methods: Vec<(Ident, NativeMethod)>,
getter: fn(&Instance, get:Ident)-> Litr,
setter: fn(&mut Instance, set:Ident, to:Litr),
index_get: fn(&Instance, LitrRef)-> Litr,
index_set: fn(&mut Instance, LitrRef, LitrRef),
next: fn(&mut Instance)-> Litr,
to_str: fn(&Instance)-> String,
onclone: fn(&Instance)-> Instance,
ondrop: fn(&mut Instance)
}
#[repr(transparent)]
#[derive(Debug)]
pub struct Class {
p: UnsafeCell<*mut ClassInner>
}
impl Clone for Class {
fn clone(&self) -> Self {
Class {p: UnsafeCell::new(unsafe{*self.p.get()})}
}
}
unsafe impl Sync for Class {}
macro_rules! impl_class_setter {($($doc:literal $f:ident($t:ty);)*) => {
$(
#[doc = $doc]
pub fn $f(&self, f:$t) {
unsafe{(**self.p.get()).$f = f;}
}
)*
}}
impl Class {
pub const fn uninit()-> Self {
Class { p: UnsafeCell::new(std::ptr::null_mut()) }
}
pub fn new(&self, name:&str) {
let v = ClassInner {
name:intern(name.as_bytes()),
getter:|_,_|Litr::Uninit,
setter:|_,_,_|(),
statics: Vec::new(),
methods: Vec::new() ,
index_get:|_,_|Litr::Uninit,
index_set:|_,_,_|(),
next:|_|Symbol::iter_end(),
to_str: |v|format!("{} {{ Native }}", unsafe{&**v.cls.p.get()}.name),
onclone:|v|v.clone(),
ondrop:|_|()
};
unsafe{*self.p.get() = Box::into_raw(Box::new(v))}
}
pub fn create(&self, v:usize, w:usize)-> Litr {
Litr::Ninst(Instance { cls: self.clone(), v, w })
}
impl_class_setter!{
"设置getter, 用来处理`.`运算符"
getter(fn(&Instance, get:Ident)-> Litr);
"设置setter, 用来处理a.b = c的写法"
setter(fn(&mut Instance, set:Ident, to:Litr));
"设置index getter, 返回a[i]的值"
index_get(fn(&Instance, LitrRef)-> Litr);
"设置index setter, 处理a[i] = b"
index_set(fn(&mut Instance, LitrRef, LitrRef));
"设置迭代器, 处理for n:instance {}"
next(fn(&mut Instance)-> Litr);
"自定义复制行为(往往是赋值和传参)"
onclone(fn(&Instance)-> Instance);
"自定义垃圾回收回收行为(只需要写额外工作,不需要drop此指针)"
ondrop(fn(&mut Instance));
"自定义Str::from得到的字符串"
to_str(fn(&Instance)-> String);
}
pub fn method(&self, name:&str, f:NativeMethod) {
unsafe{(**self.p.get()).methods.push((intern(name.as_bytes()), f));}
}
pub fn static_method(&self, name:&str, f:NativeFn) {
unsafe{(**self.p.get()).statics.push((intern(name.as_bytes()), f));}
}
}
#[repr(C)]
pub struct NativeModule {
funcs: *mut Vec<(Ident, NativeFn)>,
classes: *mut Vec<Class>
}
impl NativeModule {
pub fn export_fn(&mut self, name:&str, f:NativeFn) {
unsafe{&mut *self.funcs}.push((intern(name.as_bytes()), f))
}
pub fn export_cls(&mut self, cls:Class) {
unsafe{&mut *self.classes}.push(cls);
}
}
pub mod prelude {
pub use crate::key::{Litr, LitrRef};
pub use crate::{NativeModule, Class, kpanic};
}