use crate::atom::{Atom, AtomTable};
use crate::native::ProcessContext;
use crate::term::Term;
static UNIX_ATOM: std::sync::OnceLock<Atom> = std::sync::OnceLock::new();
static DARWIN_ATOM: std::sync::OnceLock<Atom> = std::sync::OnceLock::new();
pub fn init_erlang_atoms(atom_table: &AtomTable) {
let _ = UNIX_ATOM.set(atom_table.intern("unix"));
let _ = DARWIN_ATOM.set(atom_table.intern("darwin"));
}
pub fn bif_ensure_all_started(args: &[Term], context: &mut ProcessContext) -> Result<Term, Term> {
let [_app] = args else {
return Err(badarg());
};
context.alloc_tuple(&[Term::atom(Atom::OK), Term::NIL])
}
pub fn bif_os_getenv_0(args: &[Term], _context: &mut ProcessContext) -> Result<Term, Term> {
if !args.is_empty() {
return Err(badarg());
}
Ok(Term::NIL)
}
pub fn bif_os_getenv_1(args: &[Term], _context: &mut ProcessContext) -> Result<Term, Term> {
let [_name] = args else {
return Err(badarg());
};
Ok(Term::atom(Atom::FALSE))
}
pub fn bif_os_putenv(args: &[Term], _context: &mut ProcessContext) -> Result<Term, Term> {
let [_key, _value] = args else {
return Err(badarg());
};
Ok(Term::atom(Atom::TRUE))
}
pub fn bif_os_unsetenv(args: &[Term], _context: &mut ProcessContext) -> Result<Term, Term> {
let [_name] = args else {
return Err(badarg());
};
Ok(Term::atom(Atom::TRUE))
}
pub fn bif_os_type(args: &[Term], context: &mut ProcessContext) -> Result<Term, Term> {
if !args.is_empty() {
return Err(badarg());
}
let unix = UNIX_ATOM.get().copied().unwrap_or_else(|| Atom::new(9998));
let darwin = DARWIN_ATOM
.get()
.copied()
.unwrap_or_else(|| Atom::new(9997));
context.alloc_tuple(&[Term::atom(unix), Term::atom(darwin)])
}
pub fn bif_io_get_line(args: &[Term], _context: &mut ProcessContext) -> Result<Term, Term> {
let [_prompt] = args else {
return Err(badarg());
};
let heap: &mut [u64] = Box::leak(vec![0u64; 2].into_boxed_slice());
crate::term::binary::write_binary(heap, b"").ok_or_else(badarg)
}
pub fn bif_code_priv_dir(args: &[Term], context: &mut ProcessContext) -> Result<Term, Term> {
let [_app] = args else {
return Err(badarg());
};
context.alloc_tuple(&[Term::atom(Atom::ERROR), Term::atom(Atom::BADARG)])
}
pub fn bif_connect_node(args: &[Term], _context: &mut ProcessContext) -> Result<Term, Term> {
let [_node] = args else {
return Err(badarg());
};
Ok(Term::atom(Atom::FALSE))
}
pub fn bif_string_split(args: &[Term], _context: &mut ProcessContext) -> Result<Term, Term> {
let [input, _pattern] = args else {
return Err(badarg());
};
let cell = Box::leak(Box::new([0u64; 2]));
crate::term::boxed::write_cons(cell, *input, Term::NIL).ok_or_else(badarg)
}
fn badarg() -> Term {
Term::atom(Atom::BADARG)
}