Skip to content
Snippets Groups Projects
Select Git revision
  • 46f125d3de646f431e8ba5d0b90f1b5f8c870a3a
  • master default protected
2 results

test_parser.rs

Blame
  • test_parser.rs 4.67 KiB
    // This will also allow us to change all tests when syntax changes.
    
    use erode::ast::*;
    use erode::grammar::*;
    
    #[test]
    fn test_path() {
        // path cannot be empty
        assert!(PathParser::new().parse("").is_err());
    
        // path cannot hold a singe Id
        assert!(PathParser::new().parse("A").is_err());
    
        // path Id::Id is ok
        assert!(PathParser::new().parse("A::B_").is_ok());
    
        println!("{:?}", PathParser::new().parse("A::B_"));
        println!("{}", PathParser::new().parse("A::B_").unwrap());
    }
    
    #[test]
    fn test_expr() {
        // unary op
        let expr = ExprParser::new().parse("-    (+ 3)").unwrap();
        assert_eq!(&format!("{}", expr), "(- (+ 3))");
    
        let expr = ExprParser::new().parse("true").unwrap();
        assert_eq!(*expr, Expr::Bool(true));
    
        // ref
        let expr = ExprParser::new().parse("& (1 + 2)").unwrap();
        assert_eq!(&format!("{}", expr), "&(1 + 2)");
    
        // mutable reference
        assert!(ExprParser::new().parse("- *&mut 3 + 1 + 5").is_ok());
    
        // convert as
        assert!(ExprParser::new().parse("a as u32").is_ok());
    
        // call in expression
        assert!(ExprParser::new().parse("a(1,2,3)").is_ok());
    
        // call in expression
        assert!(ExprParser::new().parse("a(1,2,3,)").is_err());
    }
    
    #[test]
    fn test_exprs() {
        // comma separated expression sequence
        assert!(ExprsParser::new().parse("(1, 2, a(1,2,3))").is_ok());
    
        // comma separated expression sequence, is_err
        assert!(ExprsParser::new().parse("1, 2, a(1,2,3),").is_err());
    }
    
    #[test]
    fn test_stmts() {
        // test empty sequence
        assert!(BlockParser::new().parse("{}").is_ok());
    
        // test let with no assignment and inferred type
        assert!(BlockParser::new().parse("{ let a }").is_ok());
    
        // test let with no assignment and excplicit type
        assert!(BlockParser::new().parse("{ let a : u32 }").is_ok());
    
        // test let with inferred type
        assert!(BlockParser::new().parse("{ let a = 0 }").is_ok());
    
        // test let with explicit type
        assert!(BlockParser::new().parse("{ let a : u16 = 1 + 2 }").is_ok());
    
        // test assignment
        assert!(BlockParser::new().parse("{ a = 1 + 2 }").is_ok());
    
        // test assignment
        assert!(BlockParser::new().parse("{ *a = 1 + 2}").is_ok());
    
        // test if then
        assert!(BlockParser::new().parse("{ if a { b = 5 } }").is_ok());
    
        // test if then else
        assert!(BlockParser::new()
            .parse("{ if a { b = 5 } else { b = 7 } }")
            .is_ok());
    
        // test hello
        assert!(BlockParser::new()
            .parse("{ while hello(b) { b = b - 5 } }")
            .is_ok());
    }
    
    #[test]
    fn test_fn_explicit_return_type() {
        // test FnDecl with explicit return value
        assert!(FnDeclParser::new().parse("fn main() -> u32 {}").is_ok());
    }
    
    #[test]
    fn test_fn_no_arg_implicit_return_type() {
        // test FnDecl with explicit return value
        assert!(FnDeclParser::new().parse("fn main() {}").is_ok());
    }
    
    #[test]
    fn test_fn_arg_implicit_return_type() {
        // test FnDecl with explicit return value
        assert!(FnDeclParser::new().parse("fn main(a:u32) {}").is_ok());
    }
    
    #[test]
    fn test_fn_arg_explict_return_type() {
        // test FnDecl with unit return value
        assert!(FnDeclParser::new()
            .parse("fn a(x:u8, y:u8) -> u8 {}")
            .is_ok());
    }
    
    #[test]
    fn test_fn_with_all_statements() {
        // test FnDecl with unit return value
        assert!(FnDeclParser::new()
            .parse(
                "
                fn a(x:u8, y:u8) -> u8 {
                    let a;
                    let b = 5;
                    let mut a : u8 = 0;
                    let c : u8;
                    {
                        c = 5;
                    };
                    while true {
                        let v: u8 = 0;
                    }          
                }
            "
            )
            .is_ok());
    }
    
    #[test]
    fn test_types() {
        assert!(TypeDeclParser::new()
            .parse("struct A { x: u32, b: nisse }")
            .is_ok());
    
        assert!(TypeDeclParser::new()
            .parse("enum Greetings { Hello, Goodbye(u32) }")
            .is_ok());
    }
    
    #[test]
    fn test_programs() {
        // simple program with only main
        assert!(ProgramParser::new().parse("fn main() {}").is_ok());
    
        // program with multiple types and FnDecls
        assert!(ProgramParser::new()
            .parse(
                "enum Stmt {
                    Let(String, id),
                    Plepps(u8),
                    Hej
                }
    
                fn main() {
                    hello = 7;
                }
    
                fn main() -> u8 {
                    hello(5);
                    if hello(7) {
                        let a = 5;
                    } else {
                        let b = 8;
                    }
                }
    
                enum Tjong {
                    Let(String, id),
                    Plepps(u8),
                    Hej
                }      
            ",
            )
            .is_ok());
    }