This commit is contained in:
2026-02-05 12:46:36 +02:00
parent 660b9245fb
commit 96f8aa3bbb
13 changed files with 387 additions and 17 deletions

View File

@@ -0,0 +1,52 @@
use mclangc::{
cli::CliArgs,
common::{Loc, loc::LocBox},
parser::{self, ast::{
Ident, Keyword, Number, Punctuation, TokenType, expr::Expr, literal::Literal,
statement::{Statement, ConstVar},
}},
tokeniser::Token, validator::predefined::BuiltinType
};
#[test]
fn test_parse_const_stat() {
let mut tokens = vec![
Token::new_test(TokenType::Keyword(Keyword::Const)),
Token::new_test(TokenType::ident("MyConstant")),
Token::new_test(TokenType::Punct(Punctuation::Colon)),
Token::new_test(TokenType::ident("usize")),
Token::new_test(TokenType::Punct(Punctuation::Eq)),
Token::new_test(TokenType::number(69, 10, false)),
Token::new_test(TokenType::Punct(Punctuation::Semi)),
Token::new_test(TokenType::ident("overflow")),
Token::new_test(TokenType::ident("overflow")),
Token::new_test(TokenType::ident("overflow")),
];
tokens.reverse();
let res = parser::stat::parse_statement(&mut tokens, &CliArgs::default(), &mut super::get_prog());
assert!(res.is_ok(), "{res:?}");
match res {
Ok(res) => {
assert!(res.is_some(), "{res:?}");
match res {
Some(res) => {
assert_eq!(res.inner().clone(), Statement::ConstVar(ConstVar {
name: Ident::new("MyConstant"),
typ: LocBox::new(&Loc::default(), BuiltinType::usize()),
val: LocBox::new(&Loc::default(), Expr::Literal(String::new(), Literal::Number(Number { val: 69, base: 10, signed: false })))
}));
}
None => unreachable!()
}
}
Err(_) => unreachable!()
}
assert!(tokens.len() == 3, "leftover token count incorrect");
}

45
tests/parser/stat/mod.rs Normal file
View File

@@ -0,0 +1,45 @@
use mclangc::{
common::{Loc, loc::LocBox},
parser::{
ast::{
Ident, Program,
statement::{Enum, Struct},
typ::Type
}
},
validator::predefined::{BuiltinType, load_builtin}
};
mod constant;
mod statc;
mod type_alias;
pub 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.types.insert(Ident::new("MyType"), LocBox::new(&loc, Type::Owned(Ident::new("MyStruct"))));
prog.types.insert(Ident::new("MyType2"), LocBox::new(&loc, Type::Owned(Ident::new("MyType"))));
prog.types.insert(Ident::new("MyType3"), LocBox::new(&loc, Type::Owned(Ident::new("MyType2")).as_ref()));
prog.types.insert(Ident::new("MyTypeInf"), LocBox::new(&loc, Type::Owned(Ident::new("MyTypeInf"))));
prog.types.insert(Ident::new("MyTypeInfIndirect"), LocBox::new(&loc, Type::Owned(Ident::new("MyType4"))));
prog.types.insert(Ident::new("MyType4"), LocBox::new(&loc, Type::Owned(Ident::new("MyType5"))));
prog.types.insert(Ident::new("MyType5"), LocBox::new(&loc, Type::Owned(Ident::new("MyType4"))));
prog
}

View File

@@ -0,0 +1,48 @@
use mclangc::{
cli::CliArgs,
common::{Loc, loc::LocBox},
parser::{self, ast::{
Ident, Keyword, Number, Punctuation, TokenType, expr::Expr, literal::Literal,
statement::{Statement, StaticVar},
}},
tokeniser::Token, validator::predefined::BuiltinType
};
#[test]
fn test_parse_static_stat() {
let mut tokens = vec![
Token::new_test(TokenType::Keyword(Keyword::Static)),
Token::new_test(TokenType::ident("MyStatic")),
Token::new_test(TokenType::Punct(Punctuation::Colon)),
Token::new_test(TokenType::ident("usize")),
Token::new_test(TokenType::Punct(Punctuation::Eq)),
Token::new_test(TokenType::number(69, 10, false)),
Token::new_test(TokenType::Punct(Punctuation::Semi)),
Token::new_test(TokenType::ident("overflow")),
Token::new_test(TokenType::ident("overflow")),
Token::new_test(TokenType::ident("overflow")),
];
tokens.reverse();
let res = parser::stat::parse_statement(&mut tokens, &CliArgs::default(), &mut super::get_prog());
assert!(res.is_ok(), "{res:?}");
match res {
Ok(res) => {
assert!(res.is_some(), "{res:?}");
match res {
Some(res) => {
assert_eq!(res.inner().clone(), Statement::StaticVar(StaticVar {
name: Ident::new("MyStatic"),
typ: LocBox::new(&Loc::default(), BuiltinType::usize()),
val: LocBox::new(&Loc::default(), Expr::Literal(String::new(), Literal::Number(Number { val: 69, base: 10, signed: false })))
}));
}
None => unreachable!()
}
}
Err(_) => unreachable!()
}
assert!(tokens.len() == 3, "leftover token count incorrect");
}

View File

@@ -0,0 +1,48 @@
use mclangc::{
cli::CliArgs,
common::{Loc, loc::LocBox},
parser::{self, ast::{
Ident, Keyword, Number, Punctuation, TokenType, expr::Expr, literal::Literal,
statement::{Statement, StaticVar},
}},
tokeniser::Token, validator::predefined::BuiltinType
};
#[test]
fn test_parse_alias_stat() {
let mut tokens = vec![
Token::new_test(TokenType::Keyword(Keyword::Static)),
Token::new_test(TokenType::ident("MyStatic")),
Token::new_test(TokenType::Punct(Punctuation::Colon)),
Token::new_test(TokenType::ident("usize")),
Token::new_test(TokenType::Punct(Punctuation::Eq)),
Token::new_test(TokenType::number(69, 10, false)),
Token::new_test(TokenType::Punct(Punctuation::Semi)),
Token::new_test(TokenType::ident("overflow")),
Token::new_test(TokenType::ident("overflow")),
Token::new_test(TokenType::ident("overflow")),
];
tokens.reverse();
let res = parser::stat::parse_statement(&mut tokens, &CliArgs::default(), &mut super::get_prog());
assert!(res.is_ok(), "{res:?}");
match res {
Ok(res) => {
assert!(res.is_some(), "{res:?}");
match res {
Some(res) => {
assert_eq!(res.inner().clone(), Statement::StaticVar(StaticVar {
name: Ident::new("MyStatic"),
typ: LocBox::new(&Loc::default(), BuiltinType::usize()),
val: LocBox::new(&Loc::default(), Expr::Literal(String::new(), Literal::Number(Number { val: 69, base: 10, signed: false })))
}));
}
None => unreachable!()
}
}
Err(_) => unreachable!()
}
assert!(tokens.len() == 3, "leftover token count incorrect");
}