neige_lua/api/
push.rs

1use neige_infra::LUA_RIDX_GLOBALS;
2
3use crate::{
4    state::LuaState,
5    value::{closure::RustFn, value::LuaValue},
6};
7
8use super::SetApi;
9
10pub trait PushApi {
11    fn push_nil(&mut self);
12    fn push_boolean(&mut self, b: bool);
13    fn push_integer(&mut self, i: i64);
14    fn push_number(&mut self, f: f64);
15    fn push_string(&mut self, s: &str);
16    fn push_rust_fn(&mut self, f: RustFn);
17    fn register(&mut self, name: &str, f: RustFn);
18    fn push_global_table(&mut self);
19    fn push_rust_closure(&mut self, f: RustFn, n: usize);
20}
21
22impl PushApi for LuaState {
23    fn push_nil(&mut self) {
24        self.stack_push(LuaValue::Nil)
25    }
26
27    fn push_boolean(&mut self, b: bool) {
28        self.stack_push(LuaValue::Boolean(b))
29    }
30
31    fn push_integer(&mut self, i: i64) {
32        self.stack_push(LuaValue::Integer(i))
33    }
34
35    fn push_number(&mut self, f: f64) {
36        self.stack_push(LuaValue::Number(f))
37    }
38
39    fn push_string(&mut self, s: &str) {
40        self.stack_push(LuaValue::Str(s.into()))
41    }
42
43    fn push_rust_fn(&mut self, f: RustFn) {
44        self.stack_push(LuaValue::new_rust_closure(f, 0))
45    }
46
47    fn register(&mut self, name: &str, f: RustFn) {
48        self.push_rust_fn(f);
49        self.set_global(name);
50    }
51
52    fn push_global_table(&mut self) {
53        let global = self.registry_get(&LuaValue::Integer(LUA_RIDX_GLOBALS));
54        self.stack_push(global)
55    }
56
57    fn push_rust_closure(&mut self, f: RustFn, mut n: usize) {
58        let closure = LuaValue::new_rust_closure(f, n);
59        while n > 0 {
60            let val = self.stack_pop();
61            if let LuaValue::Function(c) = &closure {
62                c.upvals.borrow_mut()[n - 1].set_val(val);
63            }
64            n -= 1
65        }
66        self.stack_push(closure)
67    }
68}