use std::cell::RefCell; use std::error::Error; use std::rc::Rc; use brainterpreter::compiler::Compiler; use brainterpreter::lexer::Lexer; use brainterpreter::parser::Parser; use brainterpreter::vm::Vm; #[test] fn expression_with_negative_numbers() { let io = interpret("print -1;").unwrap(); assert_eq!(io.as_slice(), "-1\n".as_bytes()); } #[test] fn calculation_precedence() { let io = interpret("print 2 + 2 * 2 - (3 + 3);").unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "0\n"); } #[test] fn conditionals() { let io = interpret( r#" let input = 11; if (input > 10) { print 3; } else if (input > 5) { print 2; } else { print 1; } "#, ) .unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "3\n"); let io = interpret( r#" let input = 6; if (input > 10) { print 3; } else if (input > 5) { print 2; } else { print 1; } "#, ) .unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "2\n"); let io = interpret( r#" let input = 3; if (input > 10) { print 3; } else if (input > 5) { print 2; } else { print 1; } "#, ) .unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "1\n"); } #[test] fn while_loop() { let source = r#" let i = 5; while (i > 0) { print i; i = i - 1; } print 100; "#; let io = interpret(source).unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "5\n4\n3\n2\n1\n100\n"); } #[test] fn function_call() { let source = r#" fun add(a, b) { return a + b; } print add(1, 2); "#; let io = interpret(source).unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "3\n"); } #[test] fn assign_variables() { let source = r#" let a = 1; print a; let a = a + 1; print a; { let a = 3; print a; } print a; "#; let io = interpret(source).unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "1\n2\n3\n2\n"); } #[test] fn read_string_index() { let source = r#" let w = "Rust"; print w[0]; "#; let io = interpret(source).unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "R\n"); } #[test] fn change_string_index() { let source = r#" let w = "Rust"; w[0] = "D"; print w; "#; let io = interpret(source).unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "Dust\n"); } #[test] fn built_in_function() { let source = r#" let str = "Rust"; let l = len(str); print l; "#; let io = interpret(source).unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "4\n"); } #[test] fn iterate_over_characters() { let source = r#" let str = "Rust"; let i = 0; while (i < len(str)) { print str[i]; i = i + 1; } "#; let io = interpret(source).unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "R\nu\ns\nt\n"); } #[test] fn report_number_of_characters() { let source = r#" fun report_number_of_characters(str) { return str + " has " + as_string(len(str)) + " characters."; } print report_number_of_characters("Rust"); "#; let io = interpret(source).unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "Rust has 4 characters.\n"); } #[test] fn number_array() { let source = r#" let memory = [0;10]; print memory[0]; memory[0] = 1; print memory[0]; print memory[1]; "#; let io = interpret(source).unwrap(); let out = String::from_utf8(io).unwrap(); assert_eq!(out, "0\n1\n0\n"); } pub fn interpret(source: &str) -> Result, Box> { let io = Rc::new(RefCell::new(vec![])); { let lexer = Lexer::new(source); let mut parser = Parser::new(lexer); let ast = parser.parse_program()?; let mut compiler = Compiler::default(); let script = compiler.compile_script(ast)?; let mut vm = Vm::with_io(io.clone()); vm.run_script(script)?; } let output = io.borrow(); Ok(output.clone()) }