use crate::cell::Cell;
use crate::error::Error;
use crate::pretty;
use crate::vm::builtin::pop_argc;
use crate::vm::vcell::VCell;
use crate::vm::Vm;
pub fn load_builtins(vm: &mut Vm) {
vm.load_builtin("display", display);
vm.load_builtin("write", write);
vm.load_builtin("pretty-print", pretty_print);
vm.load_builtin("term-rows", term_rows);
vm.load_builtin("term-cols", term_cols);
vm.load_builtin("time-utc", time_utc);
vm.load_builtin("eof-object", eof_object);
vm.load_builtin("eof-object?", eof_object_p);
vm.load_builtin("read-char", read_char);
vm.load_builtin("peek-char", peek_char);
vm.load_builtin("char-ready?", char_ready);
}
pub fn display(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 1, Some(1), "display")?;
let obj = vm.heap.get_as_cell(vm.stack.pop()?);
vm.display(&obj);
Ok(VCell::Void)
}
pub fn write(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 1, Some(1), "write")?;
let obj = vm.heap.get_as_cell(vm.stack.pop()?);
vm.write(&obj);
Ok(VCell::Void)
}
pub fn pretty_print(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 1, Some(1), "pretty-print")?;
let obj = vm.heap.get_as_cell(vm.stack.pop()?);
let width = vm.term_cols();
let width = if width == 0 { 80 } else { width };
let mut formatted = pretty::format(&obj, width);
formatted.push('\n');
vm.display(&Cell::String(formatted));
Ok(VCell::Void)
}
pub fn term_rows(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 0, Some(0), "term-rows")?;
Ok(VCell::Number(vm.term_rows().into()))
}
pub fn term_cols(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 0, Some(0), "term-cols")?;
Ok(VCell::Number(vm.term_cols().into()))
}
pub fn time_utc(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 0, Some(0), "time-utc")?;
Ok(VCell::Number(vm.time_utc().into()))
}
pub fn eof_object(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 0, Some(0), "eof-object")?;
Ok(VCell::Eof)
}
pub fn eof_object_p(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 1, Some(1), "eof-object?")?;
let val = vm.heap.get(vm.stack.pop()?);
Ok(VCell::Bool(val.is_eof()))
}
pub fn read_char(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 0, Some(0), "read-char")?;
Ok(match vm.read_char() {
Some(c) => VCell::Char(c),
None => VCell::Eof,
})
}
pub fn peek_char(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 0, Some(0), "peek-char")?;
Ok(match vm.peek_char() {
Some(c) => VCell::Char(c),
None => VCell::Eof,
})
}
pub fn char_ready(vm: &mut Vm) -> Result<VCell, Error> {
pop_argc(vm, 0, Some(0), "char-ready?")?;
Ok(VCell::Bool(vm.char_ready()))
}