Skip to content

Commit

Permalink
refactor error reporting for builtin functions
Browse files Browse the repository at this point in the history
  • Loading branch information
binoyjayan committed Sep 25, 2023
1 parent dbcb06c commit 30428a5
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 24 deletions.
28 changes: 14 additions & 14 deletions src/common/builtins/mod.rs
Expand Up @@ -40,7 +40,7 @@ fn builtin_len(args: Vec<Rc<Object>>) -> Result<Rc<Object>, 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")),
}
}

Expand Down Expand Up @@ -73,10 +73,10 @@ fn builtin_first(args: Vec<Rc<Object>>) -> Result<Rc<Object>, 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<Rc<Object>>) -> Result<Rc<Object>, String> {
Expand All @@ -89,11 +89,11 @@ fn builtin_last(args: Vec<Rc<Object>>) -> Result<Rc<Object>, 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<Rc<Object>>) -> Result<Rc<Object>, String> {
Expand All @@ -108,30 +108,30 @@ fn builtin_rest(args: Vec<Rc<Object>>) -> Result<Rc<Object>, 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<Rc<Object>>) -> Result<Rc<Object>, 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) => {
let mut new_array = a.clone();
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<Rc<Object>>) -> Result<Rc<Object>, 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();
Expand All @@ -144,14 +144,14 @@ fn builtin_str(args: Vec<Rc<Object>>) -> Result<Rc<Object>, 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<Rc<Object>>) -> Result<Rc<Object>, 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
Expand All @@ -163,15 +163,15 @@ fn builtin_time(args: Vec<Rc<Object>>) -> Result<Rc<Object>, String> {

fn flush_stdout(args: Vec<Rc<Object>>) -> Result<Rc<Object>, 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))
}

fn flush_stderr(args: Vec<Rc<Object>>) -> Result<Rc<Object>, 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))
Expand Down
6 changes: 5 additions & 1 deletion src/evaluator/eval.rs
Expand Up @@ -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))
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/evaluator/tests.rs
Expand Up @@ -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),
},
];

Expand Down
6 changes: 5 additions & 1 deletion src/vm/interpreter.rs
Expand Up @@ -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(())
Expand Down
12 changes: 6 additions & 6 deletions src/vm/tests.rs
Expand Up @@ -907,27 +907,27 @@ fn test_builtin_function_failures() {
let tests: Vec<VmTestCaseErr> = 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",
},
];

Expand Down

0 comments on commit 30428a5

Please sign in to comment.