diff --git a/src/interpreter.rs b/src/interpreter.rs index f02e93e..bb4b5c6 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -12,16 +12,25 @@ pub enum Value { String(Rc), } +#[derive(Default)] pub struct Interpreter { + capture_output: bool, + output: Vec, // Variable table stores the runtime values of variables vartable: HashMap, } impl Interpreter { pub fn new() -> Self { - Self { - vartable: HashMap::new(), - } + Self::default() + } + + pub fn set_capture_output(&mut self, enabled: bool) { + self.capture_output = enabled; + } + + pub fn output(&self) -> &[Value] { + &self.output } pub fn run_str(&mut self, code: &str, print_tokens: bool, print_ast: bool) { @@ -62,7 +71,12 @@ impl Interpreter { Statement::Print(expr) => { let result = self.resolve_expr(expr); - print!("{}", result); + + if self.capture_output { + self.output.push(result) + } else { + print!("{}", result); + } } Statement::If(If { diff --git a/src/lib.rs b/src/lib.rs index d0fca0c..08bb042 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,96 @@ -pub mod lexer; -pub mod token; -pub mod parser; pub mod ast; pub mod interpreter; +pub mod lexer; +pub mod parser; +pub mod token; + +#[cfg(test)] +mod tests { + use crate::interpreter::{Interpreter, Value}; + use std::fs::read_to_string; + + #[test] + fn test_euler1() { + let filename = "euler1.nek"; + let correct_result = 233168; + + let mut interpreter = Interpreter::new(); + interpreter.set_capture_output(true); + + let code = read_to_string(format!("examples/{filename}")).unwrap(); + + interpreter.run_str(&code, false, false); + + let expected_output = [Value::I64(correct_result)]; + + assert_eq!(interpreter.output(), &expected_output); + } + + #[test] + fn test_euler2() { + let filename = "euler2.nek"; + let correct_result = 4613732; + + let mut interpreter = Interpreter::new(); + interpreter.set_capture_output(true); + + let code = read_to_string(format!("examples/{filename}")).unwrap(); + + interpreter.run_str(&code, false, false); + + let expected_output = [Value::I64(correct_result)]; + + assert_eq!(interpreter.output(), &expected_output); + } + + #[test] + fn test_euler3() { + let filename = "euler3.nek"; + let correct_result = 6857; + + let mut interpreter = Interpreter::new(); + interpreter.set_capture_output(true); + + let code = read_to_string(format!("examples/{filename}")).unwrap(); + + interpreter.run_str(&code, false, false); + + let expected_output = [Value::I64(correct_result)]; + + assert_eq!(interpreter.output(), &expected_output); + } + + #[test] + fn test_euler4() { + let filename = "euler4.nek"; + let correct_result = 906609; + + let mut interpreter = Interpreter::new(); + interpreter.set_capture_output(true); + + let code = read_to_string(format!("examples/{filename}")).unwrap(); + + interpreter.run_str(&code, false, false); + + let expected_output = [Value::I64(correct_result)]; + + assert_eq!(interpreter.output(), &expected_output); + } + + #[test] + fn test_euler5() { + let filename = "euler5.nek"; + let correct_result = 232792560; + + let mut interpreter = Interpreter::new(); + interpreter.set_capture_output(true); + + let code = read_to_string(format!("examples/{filename}")).unwrap(); + + interpreter.run_str(&code, false, false); + + let expected_output = [Value::I64(correct_result)]; + + assert_eq!(interpreter.output(), &expected_output); + } +}