1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
mod build; mod lex; mod split; mod util; pub use build::build; pub use lex::distribute_lex as lex; pub use split::split; use std::rc::Rc; pub use util::*; pub fn parse(src: &str) -> Vec<Result<Rc<Expr>, ParseErr>> { let symbols = split(src); if let Err(e) = symbols { return vec![Err(e)]; } let tokens = lex(&symbols.unwrap()); if let Err(e) = tokens { return vec![Err(e)]; } build(&tokens.unwrap()) } #[cfg(test)] #[cfg_attr(tarpaulin, skip)] mod integrate { const ASSETS: [&str; 9] = [ "sort", "set-construct", "word-count", "printer", "interprete", "unification", "timer", "sprintf", "matrix", ]; use super::*; use crate::source; #[test] fn read_sources() { for file in ASSETS.iter() { let prog = source(&("assets/".to_owned() + *file)).unwrap(); let symbols = split(&prog[..]); if let Err(e) = symbols { panic!("Could not split {} properly: {:?}", file, e); } let symbols = symbols.ok().unwrap(); let tokens = lex(&symbols); if let Err(e) = tokens { panic!("Could not tokenize {} properly: {:?}", file, e); } let tokens = tokens.ok().unwrap(); let exprs = build(&tokens); for expr in exprs.iter() { if let Err(e) = expr { match e { ParseErr::MismatchedOpenBrace(n) | ParseErr::MismatchedOpenParen(n) | ParseErr::MismatchedCloseBrace(n) | ParseErr::MismatchedCloseParen(n) => panic!( "Could not build {} properly: {:?}\nContext: {:?}", file, e, &tokens[n - 5..n + 5] ), e => panic!("Could not build {} properly: {:?}", file, e), } } } } } #[test] fn failures() { assert_eq!( *parse("(")[0].as_ref().err().unwrap(), ParseErr::MismatchedOpenParen(0) ); assert_eq!( *parse("#")[0].as_ref().err().unwrap(), ParseErr::LoneNumbersign ); assert_eq!(source("nofile"), None); assert_eq!( *parse("abc |# x")[0].as_ref().err().unwrap(), ParseErr::NoCommentStart ); assert_eq!( *parse("x #| abc")[0].as_ref().err().unwrap(), ParseErr::UnterminatedComment ); assert_eq!( *parse("\"abc")[0].as_ref().err().unwrap(), ParseErr::UnterminatedString(1) ); } }