diff --git a/src/common/builtins/mod.rs b/src/common/builtins/mod.rs index c767cd0..9160e6e 100644 --- a/src/common/builtins/mod.rs +++ b/src/common/builtins/mod.rs @@ -40,7 +40,7 @@ fn builtin_len(args: Vec>) -> Result, String> { match args[0].as_ref() { Object::Str(s) => Ok(Rc::new(Object::Number(s.len() as f64))), Object::Arr(a) => Ok(Rc::new(Object::Number(a.elements.len() as f64))), - _ => Err(String::from("argument to 'len' not supported")), + _ => Err(String::from("unsupported argument")), } } @@ -73,10 +73,10 @@ fn builtin_first(args: Vec>) -> Result, String> { return Ok(Rc::new(Object::Nil)); } } - _ => return Err(String::from("argument to 'first' not supported")), + _ => return Err(String::from("unsupported argument")), } } - Err(String::from("no arguments provided")) + Err(String::from("argument missing")) } fn builtin_last(args: Vec>) -> Result, String> { @@ -89,11 +89,11 @@ fn builtin_last(args: Vec>) -> Result, String> { return Ok(Rc::new(Object::Nil)); } } - _ => return Err(String::from("argument to 'last' not supported")), + _ => return Err(String::from("unsupported argument")), } } - Err(String::from("no arguments provided")) + Err(String::from("argument missing")) } fn builtin_rest(args: Vec>) -> Result, String> { @@ -108,16 +108,16 @@ fn builtin_rest(args: Vec>) -> Result, String> { }))) } } - _ => Err(String::from("argument to 'last' not supported")), + _ => Err(String::from("unsupported argument")), } } else { - Err(String::from("argument to 'last' not provided")) + Err(String::from("argument missing")) } } fn builtin_push(args: Vec>) -> Result, String> { if args.len() < 2 { - return Err(String::from("'push' needs atleast two arguments")); + return Err(String::from("takes two arguments")); } match args[0].as_ref() { Object::Arr(a) => { @@ -125,13 +125,13 @@ fn builtin_push(args: Vec>) -> Result, String> { new_array.elements.push(args[1].clone()); Ok(Rc::new(Object::Arr(new_array))) } - _ => Err(String::from("argument to 'push' not supported")), + _ => Err(String::from("unsupported argument")), } } fn builtin_str(args: Vec>) -> Result, String> { if args.len() != 1 { - return Err(String::from("'str' requires one argument")); + return Err(String::from("requires one argument")); } let obj = args[0].as_ref(); @@ -144,14 +144,14 @@ fn builtin_str(args: Vec>) -> Result, String> { | Object::Arr(_) | Object::Map(_) ) { - return Err(String::from("argument to 'str' not supported")); + return Err(String::from("unsupported argument")); } Ok(Rc::new(Object::Str(obj.to_string()))) } fn builtin_time(args: Vec>) -> Result, String> { if !args.is_empty() { - return Err(String::from("'time' takes no argument(s)")); + return Err(String::from("takes no argument(s)")); } let current_time = SystemTime::now(); let duration = current_time @@ -163,7 +163,7 @@ fn builtin_time(args: Vec>) -> Result, String> { fn flush_stdout(args: Vec>) -> Result, String> { if !args.is_empty() { - return Err(String::from("'flush_stdout' takes no argument(s)")); + return Err(String::from("takes no argument(s)")); } io::stdout().flush().expect("Failed to flush stdout"); Ok(Rc::new(Object::Nil)) @@ -171,7 +171,7 @@ fn flush_stdout(args: Vec>) -> Result, String> { fn flush_stderr(args: Vec>) -> Result, String> { if !args.is_empty() { - return Err(String::from("'flush_stderr' takes no argument(s)")); + return Err(String::from("takes no argument(s)")); } io::stderr().flush().expect("Failed to flush stderr"); Ok(Rc::new(Object::Nil)) diff --git a/src/evaluator/eval.rs b/src/evaluator/eval.rs index 87da27a..124bb77 100644 --- a/src/evaluator/eval.rs +++ b/src/evaluator/eval.rs @@ -333,7 +333,11 @@ impl Evaluator { // Invoke function match builtin_func(args) { Ok(obj) => Ok(obj), - Err(s) => Err(RTError::new(&s, 1)), + Err(s) => { + // Prefix error messaage with the function name + let msg = format!("{}: {}", func.name, s); + Err(RTError::new(&msg, 1)) + } } } diff --git a/src/evaluator/tests.rs b/src/evaluator/tests.rs index 600a3ba..8cabbb7 100644 --- a/src/evaluator/tests.rs +++ b/src/evaluator/tests.rs @@ -742,11 +742,11 @@ fn test_builtin_functions() { let error_tests = vec![ ErrorTest { input: "len(1)", - expected: RTError::new("argument to 'len' not supported", 1), + expected: RTError::new("len: unsupported argument", 1), }, ErrorTest { input: r#"len("one", "two")"#, - expected: RTError::new("wrong number of arguments. got=2, want=1", 1), + expected: RTError::new("len: wrong number of arguments. got=2, want=1", 1), }, ]; diff --git a/src/vm/interpreter.rs b/src/vm/interpreter.rs index 7a9f732..c0c37ee 100644 --- a/src/vm/interpreter.rs +++ b/src/vm/interpreter.rs @@ -532,7 +532,11 @@ impl VM { self.sp = self.sp - num_args - 1; self.push(obj, line)?; } - Err(s) => return Err(RTError::new(&s, 1)), + Err(s) => { + // Prefix error messaage with the function name + let msg = format!("{}: {}", builtin.name, s); + return Err(RTError::new(&msg, 1)); + } } self.current_frame().ip += 2; Ok(()) diff --git a/src/vm/tests.rs b/src/vm/tests.rs index 4e39d2e..75cb02e 100644 --- a/src/vm/tests.rs +++ b/src/vm/tests.rs @@ -907,27 +907,27 @@ fn test_builtin_function_failures() { let tests: Vec = vec![ VmTestCaseErr { input: r#"len(1)"#, - expected: "argument to 'len' not supported", + expected: "len: unsupported argument", }, VmTestCaseErr { input: r#"len("one", "two")"#, - expected: "wrong number of arguments. got=2, want=1", + expected: "len: wrong number of arguments. got=2, want=1", }, VmTestCaseErr { input: r#"first(1)"#, - expected: "argument to 'first' not supported", + expected: "first: unsupported argument", }, VmTestCaseErr { input: r#"last(1)"#, - expected: "argument to 'last' not supported", + expected: "last: unsupported argument", }, VmTestCaseErr { input: r#"push(1, 1)"#, - expected: "argument to 'push' not supported", + expected: "push: unsupported argument", }, VmTestCaseErr { input: "str(fn() {})", - expected: "argument to 'str' not supported", + expected: "str: unsupported argument", }, ];