use crate::context::Context;
use crate::parser::{parse, ErrorAt};
use crate::scope::Scope;
use crate::tokenizer::tokenize;
pub fn run(code: &str) -> Result<Vec<String>, ErrorAt> {
let tokens = tokenize(code)?;
let commands = parse(tokens)?;
let mut scope = Scope::new();
scope.commands = commands.into();
let mut context = Context::default();
let res = context.evaluate(&mut scope);
res.map_err(|e| (e, context.last_command.unwrap().start))
}
#[cfg(test)]
mod tests {
use crate::run::run;
#[test]
fn or() {
assert_eq!(run("1 or 2").unwrap(), vec!["1"]);
}
#[test]
fn number() {
assert_eq!(run("1").unwrap(), vec!["1"]);
}
#[test]
fn simple_function() {
assert_eq!(run("a(b):b a 5").unwrap(), vec!["5"]);
}
#[test]
fn seperate() {
assert_eq!(
run("0 0 10 0 0 20 30 0 0 40 seperated-by (0 0) (sum)").unwrap(),
vec!["10", "50", "40"]
);
}
#[test]
fn comment() {
assert_eq!(run("# a(b):b a 5").unwrap(), Vec::<String>::new());
}
#[test]
fn error() {
assert_eq!(run("error 'message"), Err(("message".to_string(), (1, 7))));
}
#[test]
fn expected_parameter() {
assert_eq!(
run("on-error 'message"),
Err((
"Expected parameter then for built-in on-error".to_string(),
(1, 7)
))
);
}
#[test]
fn unclosed_string() {
assert_eq!(run("\""), Err(("Unfinished String".to_string(), (1, 7))));
}
#[test]
fn unexpected_closing() {
assert_eq!(
run("(()()))"),
Err(("Unexpected closing parenthesis".to_string(), (1, 7)))
);
}
#[test]
fn open_close() {
assert_eq!(run("()").unwrap(), Vec::<String>::new());
}
#[test]
fn catch_error() {
assert_eq!(
run("on-error 'mes (error 'message) ()").unwrap(),
Vec::<String>::new()
);
}
}