1use std::collections::HashMap;
11
12use crate::value::{RuntimeError, Value, aver_display};
13
14pub fn register(global: &mut HashMap<String, Value>) {
15 let mut members = HashMap::new();
16 for method in &["print", "error", "warn", "readLine"] {
17 members.insert(
18 method.to_string(),
19 Value::Builtin(format!("Console.{}", method)),
20 );
21 }
22 global.insert(
23 "Console".to_string(),
24 Value::Namespace {
25 name: "Console".to_string(),
26 members,
27 },
28 );
29}
30
31pub fn effects(name: &str) -> &'static [&'static str] {
32 match name {
33 "Console.print" => &["Console.print"],
34 "Console.error" => &["Console.error"],
35 "Console.warn" => &["Console.warn"],
36 "Console.readLine" => &["Console.readLine"],
37 _ => &[],
38 }
39}
40
41pub fn call(name: &str, args: &[Value]) -> Option<Result<Value, RuntimeError>> {
43 match name {
44 "Console.print" => Some(one_msg(name, args, |s| {
45 println!("{}", s);
46 })),
47 "Console.error" => Some(one_msg(name, args, |s| {
48 eprintln!("{}", s);
49 })),
50 "Console.warn" => Some(one_msg(name, args, |s| {
51 eprintln!("[warn] {}", s);
52 })),
53 "Console.readLine" => Some(read_line(args)),
54 _ => None,
55 }
56}
57
58fn one_msg(name: &str, args: &[Value], emit: impl Fn(&str)) -> Result<Value, RuntimeError> {
61 if args.len() != 1 {
62 return Err(RuntimeError::Error(format!(
63 "{}() takes 1 argument, got {}",
64 name,
65 args.len()
66 )));
67 }
68 if let Some(s) = aver_display(&args[0]) {
69 emit(&s);
70 }
71 Ok(Value::Unit)
72}
73
74fn read_line(args: &[Value]) -> Result<Value, RuntimeError> {
75 if !args.is_empty() {
76 return Err(RuntimeError::Error(format!(
77 "Console.readLine() takes 0 arguments, got {}",
78 args.len()
79 )));
80 }
81 match aver_rt::read_line() {
82 Ok(line) => Ok(Value::Ok(Box::new(Value::Str(line)))),
83 Err(e) => Ok(Value::Err(Box::new(Value::Str(e)))),
84 }
85}