1use crate::{ContextError, Module, Panic, Protocol, Stack, Value, VmError};
4use std::fmt;
5use std::fmt::Write as _;
6use std::io;
7use std::io::Write as _;
8
9pub fn module(stdio: bool) -> Result<Module, ContextError> {
11 let mut module = Module::with_crate_item("std", &["io"]);
12
13 module.ty::<io::Error>()?;
14 module.inst_fn(Protocol::STRING_DISPLAY, format_io_error)?;
15
16 if stdio {
17 module.function(&["print"], print_impl)?;
18 module.function(&["println"], println_impl)?;
19 module.raw_fn(&["dbg"], dbg_impl)?;
20 }
21
22 Ok(module)
23}
24
25fn format_io_error(error: &std::io::Error, buf: &mut String) -> fmt::Result {
26 write!(buf, "{}", error)
27}
28
29fn dbg_impl(stack: &mut Stack, args: usize) -> Result<(), VmError> {
30 let stdout = io::stdout();
31 let mut stdout = stdout.lock();
32
33 for value in stack.drain_stack_top(args)? {
34 writeln!(stdout, "{:?}", value).map_err(VmError::panic)?;
35 }
36
37 stack.push(Value::Unit);
38 Ok(())
39}
40
41fn print_impl(m: &str) -> Result<(), Panic> {
42 let stdout = io::stdout();
43 let mut stdout = stdout.lock();
44 write!(stdout, "{}", m).map_err(Panic::custom)
45}
46
47fn println_impl(m: &str) -> Result<(), Panic> {
48 let stdout = io::stdout();
49 let mut stdout = stdout.lock();
50 writeln!(stdout, "{}", m).map_err(Panic::custom)
51}