use basic::lang::{lex, token::*, Line}; fn token(s: &str) -> Option { let s = format!("?{}", s); let (_, mut tokens) = lex(&s); let mut t = tokens.drain(2..3); t.next() } #[test] fn test_eq_gt() { let (ln, v) = lex("10 1=<>=<>2"); assert_eq!(ln, Some(10)); let mut x = v.iter(); assert_eq!( x.next(), Some(&Token::Literal(Literal::Integer("1".to_string()))) ); assert_eq!(x.next(), Some(&Token::Operator(Operator::LessEqual))); assert_eq!(x.next(), Some(&Token::Operator(Operator::GreaterEqual))); assert_eq!(x.next(), Some(&Token::Operator(Operator::NotEqual))); assert_eq!( x.next(), Some(&Token::Literal(Literal::Integer("2".to_string()))) ); assert_eq!(x.next(), None); } #[test] fn test_go_to_1() { let (ln, v) = lex("10 go to"); assert_eq!(ln, Some(10)); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Word(Word::Goto))); assert_eq!(x.next(), None); } #[test] fn test_go_to_2() { assert_eq!(token("GO TO"), Some(Token::Word(Word::Goto))); } #[test] fn test_go_sub_2() { assert_eq!(token("GO SUB"), Some(Token::Word(Word::Gosub))); } #[test] fn test_print_1() { let (ln, v) = lex("10 ?"); assert_eq!(ln, Some(10)); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Word(Word::Print))); assert_eq!(x.next(), None); } #[test] fn test_print_2() { assert_eq!(token("?"), Some(Token::Word(Word::Print))); } #[test] fn test_numbers() { assert_eq!( token("3.141593"), Some(Token::Literal(Literal::Single("3.141593".to_string()))) ); assert_eq!( token("3.1415926"), Some(Token::Literal(Literal::Double("3.1415926".to_string()))) ); assert_eq!( token("32767"), Some(Token::Literal(Literal::Integer("32767".to_string()))) ); assert_eq!( token("32768"), Some(Token::Literal(Literal::Single("32768".to_string()))) ); assert_eq!( token("24e9"), Some(Token::Literal(Literal::Single("24E9".to_string()))) ); } #[test] fn test_annotated_numbers() { assert_eq!( token("12334567890!"), Some(Token::Literal(Literal::Single("12334567890!".to_string()))) ); assert_eq!( token("0#"), Some(Token::Literal(Literal::Double("0#".to_string()))) ); assert_eq!( token("24e9%"), Some(Token::Literal(Literal::Integer("24E9%".to_string()))) ); } #[test] fn test_remark1() { let (ln, v) = lex("100 REM A fortunate comment"); assert_eq!(ln, Some(100)); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Word(Word::Rem1))); assert_eq!( x.next(), Some(&Token::Unknown(" A fortunate comment".to_string())) ); assert_eq!(x.next(), None); } #[test] fn test_remark2() { let (ln, v) = lex("100 'The comment "); assert_eq!(ln, Some(100)); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Whitespace(1))); assert_eq!(x.next(), Some(&Token::Word(Word::Rem2))); assert_eq!(x.next(), Some(&Token::Unknown("The comment".to_string()))); assert_eq!(x.next(), None); } #[test] fn test_ident_with_word() { let (ln, v) = lex("BANDS"); assert_eq!(ln, None); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Ident(Ident::Plain("B".into())))); assert_eq!(x.next(), Some(&Token::Whitespace(1))); assert_eq!(x.next(), Some(&Token::Operator(Operator::And))); assert_eq!(x.next(), Some(&Token::Whitespace(1))); assert_eq!(x.next(), Some(&Token::Ident(Ident::Plain("S".into())))); assert_eq!(x.next(), None); } #[test] fn test_for_loop() { let (ln, v) = lex("forI%=1to30"); assert_eq!(ln, None); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Word(Word::For))); assert_eq!(x.next(), Some(&Token::Whitespace(1))); assert_eq!( x.next(), Some(&Token::Ident(Ident::Integer("I%".to_string()))) ); assert_eq!(x.next(), Some(&Token::Operator(Operator::Equal))); assert_eq!( x.next(), Some(&Token::Literal(Literal::Integer("1".to_string()))) ); assert_eq!(x.next(), Some(&Token::Whitespace(1))); assert_eq!(x.next(), Some(&Token::Word(Word::To))); assert_eq!(x.next(), Some(&Token::Whitespace(1))); assert_eq!( x.next(), Some(&Token::Literal(Literal::Integer("30".to_string()))) ); assert_eq!(x.next(), None); } #[test] fn test_trim_start() { let (ln, v) = lex(" 10 PRINT 10"); assert_eq!(ln, Some(10)); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Word(Word::Print))); assert_eq!(x.next(), Some(&Token::Whitespace(1))); } #[test] fn test_do_not_trim_start() { let (ln, v) = lex(" PRINT 10"); assert_eq!(ln, None); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Whitespace(2))); assert_eq!(x.next(), Some(&Token::Word(Word::Print))); assert_eq!(x.next(), Some(&Token::Whitespace(1))); } #[test] fn test_empty() { let (ln, v) = lex(""); assert_eq!(ln, None); let mut x = v.iter(); assert_eq!(x.next(), None); } #[test] fn test_line_number_only() { let (ln, v) = lex("10"); assert_eq!(ln, Some(10)); let mut x = v.iter(); assert_eq!(x.next(), None); } #[test] fn test_string_at_start() { let (ln, v) = lex("\"HELLO\""); assert_eq!(ln, None); let mut x = v.iter(); assert_eq!( x.next(), Some(&Token::Literal(Literal::String("HELLO".to_string()))) ); } #[test] fn test_unknown() { let (ln, v) = lex("10 for %w"); assert_eq!(ln, Some(10)); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Word(Word::For))); assert_eq!(x.next(), Some(&Token::Whitespace(1))); assert_eq!(x.next(), Some(&Token::Unknown("%".to_string()))); assert_eq!(x.next(), Some(&Token::Ident(Ident::Plain("W".to_string())))); assert_eq!(x.next(), None); } #[test] fn test_insert_spacing() { let (ln, v) = lex("10 printJ:printK"); assert_eq!(ln, Some(10)); let mut x = v.iter(); assert_eq!(x.next(), Some(&Token::Word(Word::Print))); assert_eq!(x.next(), Some(&Token::Whitespace(1))); assert_eq!(x.next(), Some(&Token::Ident(Ident::Plain("J".to_string())))); assert_eq!(x.next(), Some(&Token::Colon)); assert_eq!(x.next(), Some(&Token::Word(Word::Print))); assert_eq!(x.next(), Some(&Token::Whitespace(1))); assert_eq!(x.next(), Some(&Token::Ident(Ident::Plain("K".to_string())))); assert_eq!(x.next(), None); } #[test] fn test_direct() { let l = Line::new("run"); assert_eq!(&l.to_string(), "RUN"); } #[test] fn test_indirect() { let l = Line::new("100 end"); assert_eq!(&l.to_string(), "100 END"); assert_eq!(l.number(), Some(100)); } #[test] fn test_dangling_exponent() { let l = Line::new("10if10then10else10"); assert_eq!(&l.to_string(), "10 IF 10 THEN 10 ELSE 10"); assert_eq!(l.number(), Some(10)); }