spl 0.4.2

Stack Pogramming Language: A simple, concise scripting language.
Documentation
mod rw;
mod server;
pub use rw::*;
pub use server::*;

use std::sync::{Arc, LazyLock};

use crate::{mutex::Mut, runtime::*};

static IS_INITIALIZED: LazyLock<Arc<Mut<bool>>> = LazyLock::new(|| Arc::new(Mut::new(false)));

#[derive(Default)]
pub struct StreamExtraData {
    peer: Option<(String, u16)>,
}

pub fn register(r: &mut Stack, o: Arc<Frame>) {
    if !*IS_INITIALIZED.lock_ro() {
        register_stream_type("file", stream_file);
        register_stream_type("tcp", stream_tcp);
        register_stream_type("udp", stream_udp);
        register_stream_type("cmd", stream_cmd);
        register_server_stream_type("tcp", server_stream_tcp);
        *IS_INITIALIZED.lock() = true;
    }

    type Fn = fn(&mut Stack) -> OError;
    let fns: [(&str, Fn, u32); 12] = [
        ("new-stream", new_stream, 1),
        ("write-stream", write_stream, 1),
        ("write-all-stream", write_all_stream, 0),
        ("flush-stream", flush_stream, 0),
        ("read-stream", read_stream, 1),
        ("read-all-stream", read_all_stream, 0),
        ("close-stream", close_stream, 0),
        ("new-server-stream", new_server_stream, 1),
        ("accept-server-stream", accept_server_stream, 1),
        ("close-server-stream", close_server_stream, 0),
        ("get-stream-peer", get_stream_peer, 2),
        ("shutdown-input-stream", shutdown_input_stream, 0),
    ];
    for f in fns {
        r.define_func(
            f.0.to_owned(),
            AFunc::new(Func {
                ret_count: f.2,
                to_call: FuncImpl::Native(f.1),
                run_as_base: false,
                origin: o.clone(),
                fname: None,
                name: f.0.to_owned(),
            }),
        );
    }
}