use basic::lang::{ast::*, lex, parse}; fn parse_str(s: &str) -> Option { let (lin, tokens) = lex(s); match parse(lin, &tokens) { Ok(mut v) => v.pop(), Err(_) => None, } } #[test] fn test_let_foo_eq_bar() { let answer = Statement::Let( 0..3, Variable::Unary(4..7, Ident::Plain("TER".into())), Expression::Variable(Variable::Unary(8..11, Ident::Plain("BAR".into()))), ); assert_eq!(parse_str("letter=bar:"), Some(answer)); let answer = Statement::Let( 0..3, Variable::Unary(0..3, Ident::Plain("TER".into())), Expression::Variable(Variable::Unary(4..7, Ident::Plain("BAR".into()))), ); assert_eq!(parse_str("ter=bar:"), Some(answer)); } #[test] fn test_literals() { let answer = Statement::Let( 0..1, Variable::Unary(0..1, Ident::Plain("A".into())), Expression::Integer(2..4, 12), ); assert_eq!(parse_str("A=12"), Some(answer)); let answer = Statement::Let( 0..1, Variable::Unary(0..1, Ident::Plain("A".into())), Expression::Single(2..5, 12.0), ); assert_eq!(parse_str("A=12!"), Some(answer)); let answer = Statement::Let( 0..1, Variable::Unary(0..1, Ident::Plain("A".into())), Expression::Double(2..6, 12e4), ); assert_eq!(parse_str("A=12d4"), Some(answer)); let answer = Statement::Let( 0..1, Variable::Unary(0..1, Ident::Plain("A".into())), Expression::String(2..8, "food".into()), ); assert_eq!(parse_str("A=\"food\""), Some(answer)); let answer = Statement::Let( 0..1, Variable::Unary(0..1, Ident::Plain("A".into())), Expression::Double(2..58, 0.0), ); assert_eq!( parse_str("A=798347598234765983475983248592d-234721398742391847982344"), Some(answer) ); } #[test] fn test_unary() { let answer = Statement::Let( 0..1, Variable::Unary(0..1, Ident::Plain("A".into())), Expression::Negation( 2..3, Box::new(Expression::Add( 5..6, Box::new(Expression::Integer(4..5, 1)), Box::new(Expression::Integer(7..8, 1)), )), ), ); assert_eq!(parse_str("A=-(1++1)"), Some(answer)); } #[test] fn test_functions() { let answer = Statement::Let( 0..1, Variable::Unary(0..1, Ident::Plain("A".into())), Expression::Variable(Variable::Array( 2..11, Ident::Plain("COS".into()), vec![Expression::Single(6..10, 3.11)], )), ); assert_eq!(parse_str("A=cos(3.11)"), Some(answer)); } #[test] fn test_precedence_and_paren() { let answer = Statement::Let( 0..3, Variable::Unary(4..5, Ident::Plain("A".into())), Expression::Subtract( 8..9, Box::new(Expression::Integer(7..8, 2)), Box::new(Expression::Multiply( 22..23, Box::new(Expression::Add( 11..12, Box::new(Expression::Integer(10..11, 3)), Box::new(Expression::Variable(Variable::Array( 12..21, Ident::Plain("COS".into()), vec![Expression::Single(16..20, 3.11)], ))), )), Box::new(Expression::Integer(23..24, 4)), )), ), ); assert_eq!(parse_str("let A=(2-(3+cos(3.11))*4)"), Some(answer)); } #[test] fn test_printer_list() { let (lin, tokens) = lex("? 1 2,3;:?0.0"); assert_eq!( parse(lin, &tokens).ok(), Some(vec!( Statement::Print( 0..5, vec![ Expression::Integer(6..7, 1), Expression::Integer(8..9, 2), Expression::Variable(Variable::Array( 9..10, Ident::String("TAB".into()), vec![Expression::Integer(9..10, -14)] )), Expression::Integer(10..11, 3), ] ), Statement::Print( 13..18, vec![ Expression::Single(19..22, 0.0), Expression::String(22..22, "\n".into()) ] ) )) ); } #[test] fn test_remarks() { let (lin, tokens) = lex("10 PRINT REMARK"); assert_eq!( parse(lin, &tokens).ok(), Some(vec!(Statement::Print( 0..5, vec![Expression::String(6..6, "\n".into())] ))) ); let (lin, tokens) = lex("10 PRINT 'REMARK"); assert_eq!( parse(lin, &tokens).ok(), Some(vec!(Statement::Print( 0..5, vec![Expression::String(6..6, "\n".into())] ))) ); }