use crate::atom::{Atom, AtomTable};
use crate::native::ProcessContext;
use crate::term::Term;
use crate::term::binary_ref::BinaryRef;
use crate::term::format::format_term;
pub fn bif_print(args: &[Term], context: &mut ProcessContext) -> Result<Term, Term> {
write_print_args(args, context, false)
}
pub fn bif_print_error(args: &[Term], context: &mut ProcessContext) -> Result<Term, Term> {
write_print_args(args, context, false)
}
pub fn bif_println(args: &[Term], context: &mut ProcessContext) -> Result<Term, Term> {
write_print_args(args, context, true)
}
pub fn bif_println_error(args: &[Term], context: &mut ProcessContext) -> Result<Term, Term> {
write_print_args(args, context, true)
}
fn write_print_args(
args: &[Term],
context: &mut ProcessContext,
newline: bool,
) -> Result<Term, Term> {
let [value] = args else {
return Err(badarg());
};
let mut bytes = print_bytes(*value, context);
if newline {
bytes.push(b'\n');
}
context.io_sink().write(&bytes);
Ok(Term::atom(Atom::NIL))
}
fn print_bytes(value: Term, context: &ProcessContext) -> Vec<u8> {
BinaryRef::new(value)
.map(|binary| binary.as_bytes().to_vec())
.unwrap_or_else(|| render_term(value, context).into_bytes())
}
fn render_term(term: Term, context: &ProcessContext) -> String {
let fallback = AtomTable::with_common_atoms();
let atom_table = context.atom_table().unwrap_or(&fallback);
format_term(term, atom_table)
}
fn badarg() -> Term {
Term::atom(Atom::BADARG)
}