1pub use std::collections::HashMap;
6use std::fmt::Debug;
7use crate::Instance;
8
9
10#[repr(C)]
12pub struct FuncTable {
13 pub intern: fn(&[u8])-> Ident,
14 pub err: fn(&str)->!,
15 pub find_var: fn(Scope, Ident)-> Option<LitrRef>,
16 pub let_var: fn(Scope, Ident, Litr),
17 pub const_var: fn(Scope, Ident),
18 pub using: fn(Scope, Ident, crate::Class),
19 pub call_local: fn(&LocalFunc, Vec<Litr>)-> Litr,
20 pub call_at: fn(Scope, *mut Litr, &LocalFunc, Vec<Litr>)-> Litr,
21 pub get_self: fn(Scope)-> *mut Litr,
22 pub get_parent: fn(Scope)-> Option<Scope>,
23 pub outlive_inc: fn(Scope),
24 pub outlive_dec: fn(Scope),
25 pub symcls: fn()-> crate::Class,
26 pub wait_inc: fn(),
27 pub wait_dec: fn(),
28 pub planet_new: fn()-> (*mut (), crate::Class),
29 pub planet_ok: fn(*mut (), Litr),
30 pub local_instance_clone: fn(&[usize;3])-> [usize;3],
31 pub local_instance_drop: fn(&mut[usize;3]),
32}
33pub static mut FUNCTABLE:*const FuncTable = std::ptr::null();
34
35pub fn intern(s:&[u8])-> Ident {
37 unsafe{ ((*FUNCTABLE).intern)(s) }
38}
39
40#[no_mangle]
41extern fn premain(table: &FuncTable) {
42 std::panic::set_hook(Box::new(|inf|{
44 let s = if let Some(s) = inf.payload().downcast_ref::<String>() {s}
45 else if let Some(s) = inf.payload().downcast_ref::<&str>() {s}else {"错误"};
46 unsafe{((*FUNCTABLE).err)(s)};
47 }));
48
49 unsafe {
50 FUNCTABLE = table;
51 }
52}
53
54#[derive(Debug, Clone, Copy)]
56pub struct Ident {
57 pub p: &'static Box<[u8]>
58}
59impl Ident {
60 pub fn str(&self)-> String {
62 String::from_utf8_lossy(&self.p).into_owned()
63 }
64 pub fn slice(&self)-> &[u8] {
66 self
67 }
68}
69impl std::ops::Deref for Ident {
70 type Target = [u8];
71 fn deref(&self) -> &Self::Target {
72 &*self.p
73 }
74}
75impl std::fmt::Display for Ident {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 f.write_str(&self.str())
78 }
79}
80
81#[derive(Debug, Clone, Copy)]
83pub struct Scope(*mut ());
84impl Scope {
85 pub fn find_var(self, s:&str)-> Option<LitrRef> {
87 unsafe{((*FUNCTABLE).find_var)(self, intern(s.as_bytes()))}
88 }
89 pub fn let_var(self, s:&str, v:Litr) {
91 unsafe{((*FUNCTABLE).let_var)(self, intern(s.as_bytes()), v)}
92 }
93 pub fn const_var(self, s:&str) {
95 unsafe{((*FUNCTABLE).const_var)(self, intern(s.as_bytes()))}
96 }
97 pub fn get_self(self)-> *mut Litr {
99 unsafe{((*FUNCTABLE).get_self)(self)}
100 }
101 pub fn get_parent(self)-> Option<Scope> {
103 unsafe{((*FUNCTABLE).get_parent)(self)}
104 }
105 pub fn using(self, name:&str, cls:crate::Class) {
109 unsafe{((*FUNCTABLE).using)(self, intern(name.as_bytes()), cls)}
110 }
111}
112
113unsafe impl Send for Scope {}
114
115#[derive(Debug, Clone, Default)]
117pub enum Litr {
118 #[default]
119 Uninit,
121
122 Int (isize),
124 Uint (usize),
126 Float (f64),
128 Bool (bool),
130
131 Func (Function),
133 Str (String),
135 Buf (Vec<u8>),
137 List (Vec<Litr>),
139 Obj (HashMap<Ident, Litr>),
141 Inst ([usize;3]),
143 Ninst (Instance)
145}
146
147unsafe impl Send for Litr {}
149unsafe impl Sync for Litr {}
150
151#[derive(Debug, Clone)]
153pub enum Function {
154 Native(crate::NativeFn),
155 Local(LocalFunc),
156 Extern([usize;4])
157}
158impl Function {
159 pub fn call(&self, args:Vec<LitrRef>, cx:Scope)-> Litr {
165 match self {
166 Function::Local(f)=> unsafe{
167 let args = args.into_iter().map(|n|n.own()).collect();
168 ((*FUNCTABLE).call_at)(cx, cx.get_self(), f, args)
169 }
170 Function::Native(f)=> f(args, cx),
171 _=> Litr::Uninit
172 }
173 }
174}
175
176#[derive(Debug)]
178#[repr(C)]
179pub struct LocalFunc {
180 ptr:*const (),
181 scope: Scope,
182}
183unsafe impl Send for LocalFunc {}
184
185impl Clone for LocalFunc {
189 fn clone(&self) -> Self {
190 let scope = self.scope;
191 crate::outlive_inc(scope);
192 LocalFunc { ptr: self.ptr, scope }
193 }
194}
195impl Drop for LocalFunc {
196 fn drop(&mut self) {
197 crate::outlive_dec(self.scope)
198 }
199}
200
201impl LocalFunc {
202 pub fn call(&self, args:Vec<Litr>)-> Litr {
204 unsafe{((*FUNCTABLE).call_local)(self, args)}
205 }
206 pub fn call_at(&self, scope:Scope, kself:*mut Litr, args:Vec<Litr>)-> Litr {
214 unsafe{((*FUNCTABLE).call_at)(scope, kself, self, args)}
215 }
216 pub fn scope(&self)-> Scope {
218 self.scope
219 }
220}
221
222struct LocalInstance([usize;3]);
223impl Clone for LocalInstance {
224 fn clone(&self) -> Self {
225 LocalInstance((unsafe{&*FUNCTABLE}.local_instance_clone)(&self.0))
226 }
227}
228impl Drop for LocalInstance {
229 fn drop(&mut self) {
230 (unsafe{&*FUNCTABLE}.local_instance_drop)(&mut self.0)
231 }
232}
233
234
235pub struct Sym;
237impl Sym {
238 pub const ITER_END:usize = 1;
239 pub fn is_sym(v:&Instance)-> bool {
240 v.cls == (unsafe{&*FUNCTABLE}.symcls)()
241 }
242 pub fn iter_end()-> Litr {
243 (unsafe{&*FUNCTABLE}.symcls)().create(Self::ITER_END, 0)
244 }
245}
246
247pub enum LitrRef {
253 Ref(*mut Litr),
254 Own(Litr)
255}
256impl LitrRef {
257 pub fn own(self)-> Litr {
259 match self {
260 LitrRef::Ref(p)=> unsafe {(*p).clone()}
261 LitrRef::Own(v)=> v
262 }
263 }
264}
265
266impl std::ops::Deref for LitrRef {
267 type Target = Litr;
268 fn deref(&self) -> &Self::Target {
269 match self {
270 LitrRef::Ref(p)=> unsafe{&**p},
271 LitrRef::Own(b)=> b
272 }
273 }
274}
275impl std::ops::DerefMut for LitrRef {
276 fn deref_mut(&mut self) -> &mut Self::Target {
277 match self {
278 LitrRef::Ref(p)=> unsafe{&mut **p},
279 LitrRef::Own(b)=> b
280 }
281 }
282}
283
284impl Debug for LitrRef {
285 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286 f.write_fmt(format_args!("{:?}", &**self))
287 }
288}
289
290pub struct PlanetCaller(*mut ());
292impl PlanetCaller {
293 pub fn ok(&self, v:Litr) {
295 unsafe {((*FUNCTABLE).planet_ok)(self.0, v)}
296 }
297}
298unsafe impl Send for PlanetCaller {}
300unsafe impl Sync for PlanetCaller {}
301
302pub struct Planet;
303impl Planet {
304 pub fn new(f:impl FnOnce(PlanetCaller))-> Litr {
308 let (planet, planet_cls) = unsafe {((*FUNCTABLE).planet_new)()};
309 f(PlanetCaller(planet));
310 Litr::Ninst(Instance {cls:planet_cls, v:planet as _, w:0})
311 }
312}