use std::vec; use mclangc::{common::{Loc, loc::LocBox}, parser::{self, ast::{Ident, Keyword, Program, Punctuation, TokenType, statement::{Enum, Struct}, typ::Type}}, tokeniser::Token, validator::predefined::{BuiltinType, get_builtin_from_name, load_builtin}}; fn get_prog() -> Program { let mut prog = Program::default(); load_builtin(&mut prog); let loc = Loc::default(); prog.structs.insert(Ident::new("MyStruct"), LocBox::new(&loc, Struct { name: Ident::new("MyStruct"), fields: vec![ (Ident::new("foo"), LocBox::new(&loc, BuiltinType::usize())), (Ident::new("bar"), LocBox::new(&loc, BuiltinType::bool())), (Ident::new("baz"), LocBox::new(&loc, Type::Owned(Ident::new("str")).as_ref())), ] })); prog.enums.insert(Ident::new("MyEnum"), LocBox::new(&loc, Enum { name: Ident::new("MyEnum"), fields: vec![], })); prog } #[test] fn parse_type_named_struct() { let mut tokens = vec![ Token::new_test(TokenType::Ident(Ident::new("MyStruct"))) ]; let ret = parser::typ::parse_type(&mut tokens); assert!(ret.is_ok()); assert_eq!(ret.unwrap(), LocBox::new(&Loc::default(), Type::Owned(Ident::new("MyStruct")))) } #[test] fn parse_type_named_enum() { let mut tokens = vec![ Token::new_test(TokenType::Ident(Ident::new("MyEnum"))) ]; let ret = parser::typ::parse_type(&mut tokens); assert!(ret.is_ok()); assert_eq!(ret.unwrap(), LocBox::new(&Loc::default(), Type::Owned(Ident::new("MyEnum")))) } #[test] fn parse_type_ref() { let mut tokens = vec![ Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Ident(Ident::new("MyStruct"))) ]; tokens.reverse(); let ret = parser::typ::parse_type(&mut tokens); assert!(ret.is_ok()); assert_eq!(ret.unwrap(), LocBox::new(&Loc::default(), Type::Owned(Ident::new("MyStruct")).as_ref())) } #[test] fn parse_type_ref2() { let mut tokens = vec![ Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Ident(Ident::new("MyStruct"))) ]; tokens.reverse(); let ret = parser::typ::parse_type(&mut tokens); assert!(ret.is_ok()); assert_eq!(ret.unwrap(), LocBox::new(&Loc::default(), Type::Owned(Ident::new("MyStruct")).as_ref().as_ref())) } #[test] fn parse_type_ref3() { let mut tokens = vec![ Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Ident(Ident::new("MyStruct"))) ]; tokens.reverse(); let ret = parser::typ::parse_type(&mut tokens); assert!(ret.is_ok()); assert_eq!(ret.unwrap(), LocBox::new(&Loc::default(), Type::Owned(Ident::new("MyStruct")).as_ref().as_ref().as_ref())) } #[test] fn parse_type_mut_ref() { let mut tokens = vec![ Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Keyword(Keyword::Mut)), Token::new_test(TokenType::Ident(Ident::new("MyStruct"))) ]; tokens.reverse(); let ret = parser::typ::parse_type(&mut tokens); assert!(ret.is_ok()); assert_eq!(ret.unwrap(), LocBox::new(&Loc::default(), Type::Owned(Ident::new("MyStruct")).as_ref_mut())) } #[test] fn parse_type_mut_ref2() { let mut tokens = vec![ Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Keyword(Keyword::Mut)), Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Keyword(Keyword::Mut)), Token::new_test(TokenType::Ident(Ident::new("MyStruct"))) ]; tokens.reverse(); let ret = parser::typ::parse_type(&mut tokens); assert!(ret.is_ok()); assert_eq!(ret.unwrap(), LocBox::new(&Loc::default(), Type::Owned(Ident::new("MyStruct")).as_ref_mut().as_ref_mut())) } #[test] fn parse_type_mut_ref3() { let mut tokens = vec![ Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Keyword(Keyword::Mut)), Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Keyword(Keyword::Mut)), Token::new_test(TokenType::Punct(Punctuation::Ampersand)), Token::new_test(TokenType::Keyword(Keyword::Mut)), Token::new_test(TokenType::Ident(Ident::new("MyStruct"))) ]; tokens.reverse(); let ret = parser::typ::parse_type(&mut tokens); assert!(ret.is_ok()); assert_eq!(ret.unwrap(), LocBox::new(&Loc::default(), Type::Owned(Ident::new("MyStruct")).as_ref_mut().as_ref_mut().as_ref_mut())) } fn test_builtin(s: &str) { let mut tokens = vec![ Token::new_test(TokenType::Ident(Ident::new(s))) ]; let ret = parser::typ::parse_type(&mut tokens); assert!(ret.is_ok()); assert_eq!(ret.unwrap(), LocBox::new(&Loc::default(), get_builtin_from_name(s).unwrap())) } #[test] fn parse_type_builtin_usize() { test_builtin("usize"); } #[test] fn parse_type_builtin_isize() { test_builtin("isize"); } #[test] fn parse_type_builtin_u8() { test_builtin("u8"); } #[test] fn parse_type_builtin_i8() { test_builtin("i8"); } #[test] fn parse_type_builtin_u16() { test_builtin("u16"); } #[test] fn parse_type_builtin_i16() { test_builtin("i16"); } #[test] fn parse_type_builtin_u32() { test_builtin("u32"); } #[test] fn parse_type_builtin_i32() { test_builtin("i32"); } #[test] fn parse_type_builtin_u64() { test_builtin("u64"); } #[test] fn parse_type_builtin_i64() { test_builtin("i64"); } #[test] fn parse_type_builtin_void() { test_builtin("void"); } #[test] fn parse_type_builtin_char() { test_builtin("char"); } #[test] fn parse_type_builtin_bool() { test_builtin("bool"); }