schala/schala-lang/language/src/parsing/test.rs

174 lines
4.8 KiB
Rust
Raw Normal View History

#![cfg(test)]
2021-10-19 22:24:27 -07:00
#![allow(clippy::upper_case_acronyms)]
2021-10-19 22:29:41 -07:00
#![allow(clippy::vec_init_then_push)]
2021-10-19 22:24:27 -07:00
2021-10-30 20:27:16 -07:00
use pretty_assertions::assert_eq;
use std::rc::Rc;
use crate::tokenizing::Location;
use super::{Parser, ParseResult, tokenize};
2019-10-22 03:15:41 -07:00
use crate::ast::*;
use super::Declaration::*;
use super::Signature;
use super::TypeIdentifier::*;
use super::TypeSingletonName;
use super::ExpressionKind::*;
2021-10-21 19:53:50 -07:00
use super::VariantKind::*;
fn make_parser(input: &str) -> Parser {
let tokens: Vec<crate::tokenizing::Token> = tokenize(input);
let mut parser = super::Parser::new();
parser.add_new_tokens(tokens);
parser
}
fn parse(input: &str) -> ParseResult<AST> {
let mut parser = make_parser(input);
parser.parse()
}
//TODO maybe can be const?
fn make_statement(kind: StatementKind) -> Statement {
Statement {
location: Location::default(),
id: ItemId::default(),
kind,
}
}
2021-10-14 17:42:04 -07:00
macro_rules! bx {
($e:expr) => {
Box::new($e)
};
}
macro_rules! parse_test {
2019-09-18 09:56:11 -07:00
($string:expr, $correct:expr) => {
2019-09-18 01:58:38 -07:00
assert_eq!(parse($string).unwrap(), $correct)
};
}
macro_rules! parse_test_wrap_ast {
2021-10-26 14:05:27 -07:00
($string:expr, $correct:expr) => { parse_test!($string, AST { id: Default::default(), statements: vec![$correct].into() }) }
}
2019-09-19 01:34:21 -07:00
macro_rules! qname {
( $( $component:expr),* ) => {
{
let mut components = vec![];
$(
components.push(rc!($component));
)*
2021-10-18 17:39:20 -07:00
QualifiedName { components, id: Default::default() }
2019-09-19 01:34:21 -07:00
}
};
}
macro_rules! val {
2021-10-18 17:39:20 -07:00
($var:expr) => { Value(QualifiedName { components: vec![Rc::new($var.to_string())], id: Default::default() }) };
}
macro_rules! ty {
($name:expr) => { Singleton(tys!($name)) }
}
macro_rules! tys {
($name:expr) => { TypeSingletonName { name: Rc::new($name.to_string()), params: vec![] } };
}
2019-09-17 02:25:11 -07:00
macro_rules! decl {
($expr_type:expr) => {
make_statement(StatementKind::Declaration($expr_type))
2019-09-17 02:25:11 -07:00
};
}
macro_rules! ex {
2021-10-18 17:39:20 -07:00
($expr_type:expr) => { Expression::new(Default::default(), $expr_type) };
($expr_type:expr, $type_anno:expr) => { Expression::with_anno(Default::default(), $expr_type, $type_anno) };
(s $expr_text:expr) => {
{
let mut parser = make_parser($expr_text);
parser.expression().unwrap()
}
};
}
macro_rules! exst {
2021-10-18 17:39:20 -07:00
($expr_type:expr) => { make_statement(StatementKind::Expression(Expression::new(Default::default(), $expr_type).into())) };
($expr_type:expr, $type_anno:expr) => { make_statement(StatementKind::Expression(Expression::with_anno(Default::default(), $expr_type, $type_anno).into())) };
($op:expr, $lhs:expr, $rhs:expr) => { make_statement(StatementKind::Expression(ex!(binexp!($op, $lhs, $rhs)))) };
(s $statement_text:expr) => {
{
let mut parser = make_parser($statement_text);
2019-09-20 10:10:57 -07:00
parser.statement().unwrap()
}
}
}
#[test]
fn parsing_block_expressions() {
2019-09-11 19:06:00 -07:00
parse_test_wrap_ast! {
"if a() then { b(); c() }", exst!(
IfExpression {
2019-10-10 18:17:59 -07:00
discriminator: Some(bx! {
ex!(Call { f: bx!(ex!(val!("a"))), arguments: vec![]})
}),
body: bx! {
2019-10-10 18:17:59 -07:00
IfExpressionBody::SimpleConditional {
2021-10-26 14:05:27 -07:00
then_case: vec![exst!(Call { f: bx!(ex!(val!("b"))), arguments: vec![]}), exst!(Call { f: bx!(ex!(val!("c"))), arguments: vec![] })].into(),
2019-10-10 18:17:59 -07:00
else_case: None,
}
}
}
2019-09-11 19:06:00 -07:00
)
};
2019-09-11 19:06:00 -07:00
parse_test_wrap_ast! {
"if a() then { b(); c() } else { q }", exst!(
IfExpression {
2019-10-10 18:17:59 -07:00
discriminator: Some(bx! {
ex!(Call { f: bx!(ex!(val!("a"))), arguments: vec![]})
}),
body: bx! {
2019-10-10 18:17:59 -07:00
IfExpressionBody::SimpleConditional {
2021-10-26 14:05:27 -07:00
then_case: vec![exst!(Call { f: bx!(ex!(val!("b"))), arguments: vec![]}), exst!(Call { f: bx!(ex!(val!("c"))), arguments: vec![] })].into(),
else_case: Some(vec![exst!(val!("q"))].into()),
2019-10-10 18:17:59 -07:00
}
}
}
2019-09-11 19:06:00 -07:00
)
};
/*
parse_test!("if a() then { b(); c() }", AST(vec![exst!(
IfExpression(bx!(ex!(Call { f: bx!(ex!(val!("a"))), arguments: vec![]})),
vec![exst!(Call { f: bx!(ex!(val!("b"))), arguments: vec![]}), exst!(Call { f: bx!(ex!(val!("c"))), arguments: vec![] })],
None)
)]));
parse_test!(r#"
if true then {
const a = 10
b
} else {
c
}"#,
AST(vec![exst!(IfExpression(bx!(ex!(BoolLiteral(true))),
2019-09-17 02:25:11 -07:00
vec![decl!(Binding { name: rc!(a), constant: true, expr: ex!(NatLiteral(10)) }),
exst!(val!(rc!(b)))],
Some(vec![exst!(val!(rc!(c)))])))])
);
parse_test!("if a { b } else { c }", AST(vec![exst!(
IfExpression(bx!(ex!(val!("a"))),
vec![exst!(val!("b"))],
Some(vec![exst!(val!("c"))])))]));
parse_test!("if (A {a: 1}) { b } else { c }", AST(vec![exst!(
IfExpression(bx!(ex!(NamedStruct { name: rc!(A), fields: vec![(rc!(a), ex!(NatLiteral(1)))]})),
vec![exst!(val!("b"))],
Some(vec![exst!(val!("c"))])))]));
parse_error!("if A {a: 1} { b } else { c }");
*/
}
#[test]
fn parsing_impls() {
2021-10-26 00:39:24 -07:00
}