ucg/src/parse/test.rs

1152 lines
36 KiB
Rust

use super::*;
use tokenizer::{tokenize, TokenIter};
use nom::IResult;
use nom_locate::LocatedSpan;
macro_rules! assert_parse {
($parsemac:ident($i:expr), $out:expr) => {
assert_parse!($i, $parsemac, $out)
};
($i:expr, $f:expr, $out:expr) => {{
let input = LocatedSpan::new($i);
match tokenize(input) {
Err(e) => assert!(false, format!("Tokenizer Error: {:?}", e)),
Ok(val) => match $f(TokenIter {
source: val.as_slice(),
}) {
IResult::Done(_, result) => assert_eq!(result, $out),
other => assert!(false, format!("Expected Done got {:?}", other)),
},
}
};};
}
macro_rules! assert_error {
($parsemac:ident($i:expr)) => {
assert_error!($i, $parsemac)
};
($i:expr, $f:expr) => {{
let input = LocatedSpan::new($i);
match tokenize(input) {
Err(_) => assert!(true),
Ok(val) => {
let result = $f(TokenIter {
source: val.as_slice(),
});
assert!(result.is_err(), format!("Not an error: {:?}", result))
}
}
}};
}
#[test]
fn test_null_parsing() {
assert_parse!(empty_value("NULL "), Value::Empty(Position::new(1, 1)));
}
#[test]
fn test_boolean_parsing() {
assert_parse!(
boolean_value("true"),
Value::Boolean(Positioned::new(true, 1, 1))
);
assert_parse!(
boolean_value("false"),
Value::Boolean(Positioned::new(false, 1, 1))
);
assert_error!(boolean_value("truth"));
}
#[test]
fn test_symbol_parsing() {
assert_parse!(
symbol("foo"),
Value::Symbol(value_node!("foo".to_string(), 1, 1))
);
assert_parse!(
symbol("foo-bar"),
Value::Symbol(value_node!("foo-bar".to_string(), 1, 1))
);
assert_parse!(
symbol("foo_bar"),
Value::Symbol(value_node!("foo_bar".to_string(), 1, 1))
);
}
#[test]
fn test_selector_parsing() {
assert_error!(selector_value("foo."));
assert_parse!(
selector_value("foo.bar "),
Value::Selector(make_selector!(make_expr!("foo".to_string(), 1, 1) => [
make_tok!("bar", 1, 5)] =>
1, 1))
);
assert_parse!(
selector_value("foo.0 "),
Value::Selector(make_selector!(make_expr!("foo".to_string(), 1, 1) => [
make_tok!(DIGIT => "0", 1, 5)] =>
1, 1))
);
assert_parse!(
selector_value("foo.bar;"),
Value::Selector(make_selector!(make_expr!("foo", 1, 1) =>
[
make_tok!("bar", 1, 5)
] =>
1, 1))
);
assert_parse!(
selector_value("({foo=1}).foo "),
Value::Selector(
make_selector!(Expression::Grouped(Box::new(Expression::Simple(
Value::Tuple(value_node!(
vec![(make_tok!("foo", 1, 3), Expression::Simple(Value::Int(Positioned::new(1, 1, 7))))],
1, 3))
))) => [ make_tok!("foo", 1, 11) ] => 1, 2)
)
);
}
#[test]
fn test_statement_parse() {
let stmt = "import \"foo\" as foo;";
assert_parse!(
statement(stmt),
Statement::Import(ImportDef {
path: make_tok!(QUOT => "foo", 1,8),
name: make_tok!("foo", 1, 17),
})
);
assert_error!(import_statement("import \"foo\""));
assert_parse!(
statement("let foo = 1.0 ;"),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 5),
value: Expression::Simple(Value::Float(value_node!(1.0, 1, 11))),
})
);
assert_parse!(
statement("let foo = 1 + 1 * 2;"),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 5),
value: Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 11)))),
right: Box::new(Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Mul,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 15)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(2, 1, 19)))),
pos: Position::new(1, 15),
})),
pos: Position::new(1, 11),
}),
})
);
assert_parse!(
statement("let foo = (1 + 1) * 2;"),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 5),
value: Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Mul,
left: Box::new(Expression::Grouped(Box::new(Expression::Binary(
BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 12)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 16)))),
pos: Position::new(1, 12),
},
)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(2, 1, 21)))),
pos: Position::new(1, 11),
}),
})
);
assert_parse!(
statement("let foo = 1 * 1 + 2;"),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 5),
value: Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Mul,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 11)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 15)))),
pos: Position::new(1, 11),
})),
right: Box::new(Expression::Simple(Value::Int(value_node!(2, 1, 19)))),
pos: Position::new(1, 11),
}),
})
);
assert_parse!(
statement("// comment\nlet foo = 1.0 ;"),
Statement::Let(LetDef {
name: make_tok!("foo", 2, 5),
value: Expression::Simple(Value::Float(value_node!(1.0, 2, 11))),
})
);
assert_parse!(
statement("1.0;"),
Statement::Expression(Expression::Simple(Value::Float(value_node!(1.0, 1, 1))))
);
}
#[test]
fn test_import_statement_parse() {
assert_error!(import_statement("import"));
assert_error!(import_statement("import \"foo\""));
assert_error!(import_statement("import \"foo\" as"));
assert_error!(import_statement("import \"foo\" as foo"));
let import_stmt = "import \"foo\" as foo;";
assert_parse!(
import_statement(import_stmt),
Statement::Import(ImportDef {
path: make_tok!(QUOT => "foo", 1, 8),
name: make_tok!("foo", 1, 17),
})
);
}
#[test]
fn test_let_statement_parse() {
assert_error!(let_statement("foo"));
assert_error!(let_statement("let \"foo\""));
assert_error!(let_statement("let 1"));
assert_error!(let_statement("let"));
assert_error!(let_statement("let foo"));
assert_error!(let_statement("let foo ="));
assert_error!(let_statement("let foo = "));
assert_error!(let_statement("let foo = 1"));
assert_parse!(
let_statement("let foo = 1.0 ;"),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 5),
value: Expression::Simple(Value::Float(value_node!(1.0, 1, 11))),
})
);
assert_parse!(
let_statement("let foo = // comment\n1.0 ;"),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 5),
value: Expression::Simple(Value::Float(value_node!(1.0, 2, 1))),
})
);
assert_parse!(
let_statement("let foo = 1.0 // comment\n;"),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 5),
value: Expression::Simple(Value::Float(value_node!(1.0, 1, 11))),
})
);
assert_parse!(
let_statement("let foo= 1.0;"),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 5),
value: Expression::Simple(Value::Float(value_node!(1.0, 1, 10))),
})
);
assert_parse!(
let_statement("let foo =1.0;"),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 5),
value: Expression::Simple(Value::Float(value_node!(1.0, 1, 10))),
})
);
}
#[test]
fn test_expression_statement_parse() {
assert_error!(expression_statement("foo"));
assert_parse!(
expression_statement("1.0;"),
Statement::Expression(Expression::Simple(Value::Float(value_node!(1.0, 1, 1))))
);
assert_parse!(
expression_statement("1.0 ;"),
Statement::Expression(Expression::Simple(Value::Float(value_node!(1.0, 1, 1))))
);
assert_parse!(
expression_statement(" 1.0;"),
Statement::Expression(Expression::Simple(Value::Float(value_node!(1.0, 1, 2))))
);
assert_parse!(
expression_statement("foo;"),
Statement::Expression(Expression::Simple(Value::Selector(make_selector!(
make_expr!("foo", 1, 1),
1,
1
))))
);
assert_parse!(
expression_statement("foo ;"),
Statement::Expression(Expression::Simple(Value::Selector(make_selector!(
make_expr!("foo", 1, 2),
1,
1
))))
);
assert_parse!(
expression_statement(" foo;"),
Statement::Expression(Expression::Simple(Value::Selector(make_selector!(
make_expr!("foo", 1, 2),
1,
2
))))
);
assert_parse!(
expression_statement("\"foo\";"),
Statement::Expression(Expression::Simple(Value::String(value_node!(
"foo".to_string(),
1,
1
))))
);
assert_parse!(
expression_statement("\"foo\" ;"),
Statement::Expression(Expression::Simple(Value::String(value_node!(
"foo".to_string(),
1,
1
))))
);
assert_parse!(
expression_statement(" \"foo\";"),
Statement::Expression(Expression::Simple(Value::String(value_node!(
"foo".to_string(),
1,
2
))))
);
}
#[test]
fn test_expression_parse() {
assert_parse!(
expression("NULL "),
Expression::Simple(Value::Empty(Position::new(1, 1)))
);
assert_parse!(
expression("\"foo\""),
Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 1)))
);
assert_parse!(
expression("1"),
Expression::Simple(Value::Int(value_node!(1, 1, 1)))
);
assert_parse!(
expression("foo "),
Expression::Simple(Value::Selector(make_selector!(
make_expr!("foo", 1, 1),
1,
1
)))
);
assert_parse!(
expression("foo.bar "),
Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 1) =>
[ make_tok!("bar", 1, 5) ] =>
1, 1)))
);
assert_parse!(
expression("{foo=1}.foo "),
Expression::Simple(Value::Selector(
make_selector!(Expression::Simple(Value::Tuple(
value_node!(vec![
(
make_tok!("foo", 1, 2),
Expression::Simple(Value::Int(value_node!(1, 1, 6))),
),
],
1, 1),
)) =>
[ make_tok!("foo", 1, 9) ] =>
1, 1)
))
);
assert_parse!(
expression("[1, 2].1 "),
Expression::Simple(Value::Selector(
make_selector!(Expression::Simple(Value::List(
ListDef{
elems: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 2))),
Expression::Simple(Value::Int(value_node!(2, 1, 5))),
],
pos: Position::new(1, 1),
})) =>
[ make_tok!(DIGIT => "1", 1, 8) ] =>
1, 1)
))
);
assert_parse!(
expression("1 + 1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1 - 1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Sub,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
mul_expression("1 * 1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Mul,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1 / 1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Div,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("(1 / 1)"),
Expression::Grouped(Box::new(Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Div,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 2)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))),
pos: Position::new(1, 2),
})))
);
assert_parse!(
expression("1 / 1 + 1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Div,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
pos: Position::new(1, 1),
})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 9)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("(1 + 1) * 1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Mul,
left: Box::new(Expression::Grouped(Box::new(Expression::Binary(
BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 2)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))),
pos: Position::new(1, 2),
}
)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 11)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1 > 1"),
Expression::Compare(ComparisonDef {
kind: CompareType::GT,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1 < 1"),
Expression::Compare(ComparisonDef {
kind: CompareType::LT,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1 <= 1"),
Expression::Compare(ComparisonDef {
kind: CompareType::LTEqual,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1 >= 1"),
Expression::Compare(ComparisonDef {
kind: CompareType::GTEqual,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1+1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1-1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Sub,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1*1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Mul,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("1/1"),
Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Div,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("macro (arg1, arg2) => { foo = arg1 }"),
Expression::Macro(MacroDef {
argdefs: vec![
value_node!("arg1".to_string(), 1, 8),
value_node!("arg2".to_string(), 1, 14),
],
fields: vec![(
make_tok!("foo", 1, 25),
Expression::Simple(Value::Selector(make_selector!(
make_expr!("arg1", 1, 31),
1,
31
))),
)],
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("select foo, 1, { foo = 2 }"),
Expression::Select(SelectDef {
val: Box::new(Expression::Simple(Value::Selector(make_selector!(
make_expr!("foo", 1, 8),
1,
8
)))),
default: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 13)))),
tuple: vec![(
make_tok!("foo", 1, 18),
Expression::Simple(Value::Int(value_node!(2, 1, 24))),
)],
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("foo.bar (1, \"foo\")"),
Expression::Call(CallDef {
macroref: make_selector!(make_expr!("foo", 1, 1) =>
[ make_tok!("bar", 1, 5) ] =>
1, 1),
arglist: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 10))),
Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 13))),
],
pos: Position::new(1, 1),
})
);
assert_parse!(
expression("(1 + 1)"),
Expression::Grouped(Box::new(Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 2)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))),
pos: Position::new(1, 2),
})))
);
assert_parse!(
expression("[1, 1]"),
Expression::Simple(Value::List(ListDef {
elems: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 2))),
Expression::Simple(Value::Int(value_node!(1, 1, 5))),
],
pos: Position::new(1, 1),
}))
);
}
#[test]
fn test_format_parse() {
assert_error!(format_expression("\"foo"));
assert_error!(format_expression("\"foo\""));
assert_error!(format_expression("\"foo\" %"));
assert_error!(format_expression("\"foo\" % (, 2"));
assert_parse!(
format_expression("\"foo @ @\" % (1, 2)"),
Expression::Format(FormatDef {
template: "foo @ @".to_string(),
args: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 14))),
Expression::Simple(Value::Int(value_node!(2, 1, 17))),
],
pos: Position::new(1, 1),
})
);
assert_parse!(
format_expression("\"foo @ @\"%(1, 2)"),
Expression::Format(FormatDef {
template: "foo @ @".to_string(),
args: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 12))),
Expression::Simple(Value::Int(value_node!(2, 1, 15))),
],
pos: Position::new(1, 1),
})
);
}
#[test]
fn test_call_parse() {
assert_error!(call_expression("foo"));
assert_error!(call_expression("foo ("));
assert_error!(call_expression("foo (1"));
assert_error!(call_expression("foo (1,"));
assert_error!(call_expression("foo (1,2"));
assert_parse!(
call_expression("foo (1, \"foo\")"),
Expression::Call(CallDef {
macroref: make_selector!(make_expr!("foo", 1, 1), 1, 1),
arglist: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 6))),
Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 9))),
],
pos: Position::new(1, 1),
})
);
assert_parse!(
call_expression("foo.bar (1, \"foo\")"),
Expression::Call(CallDef {
macroref: make_selector!(make_expr!("foo") => [ make_tok!("bar", 1, 5) ] => 1, 1),
arglist: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 10))),
Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 13))),
],
pos: Position::new(1, 1),
})
);
}
#[test]
fn test_select_parse() {
assert_error!(select_expression("select"));
assert_error!(select_expression("select foo"));
assert_error!(select_expression("select foo, 1"));
assert_error!(select_expression("select foo, 1, {"));
assert_parse!(
select_expression("select foo, 1, { foo = 2 }"),
Expression::Select(SelectDef {
val: Box::new(Expression::Simple(Value::Selector(make_selector!(
make_expr!("foo", 1, 8),
1,
8
)))),
default: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 13)))),
tuple: vec![(
make_tok!("foo", 1, 18),
Expression::Simple(Value::Int(value_node!(2, 1, 24))),
)],
pos: Position::new(1, 1),
})
);
}
#[test]
fn test_macro_expression_parsing() {
assert_error!(macro_expression("foo"));
assert_error!(macro_expression("macro \"foo\""));
assert_error!(macro_expression("macro 1"));
assert_error!(macro_expression("macro"));
assert_error!(macro_expression("macro ("));
assert_error!(macro_expression("macro (arg"));
assert_error!(macro_expression("macro (arg, arg2"));
assert_error!(macro_expression("macro (arg1, arg2) =>"));
assert_error!(macro_expression("macro (arg1, arg2) => {"));
assert_error!(macro_expression("macro (arg1, arg2) => { foo"));
assert_error!(macro_expression("macro (arg1, arg2) => { foo ="));
assert_parse!(
macro_expression("macro (arg1, arg2) => {foo=1,bar=2}"),
Expression::Macro(MacroDef {
argdefs: vec![
value_node!("arg1".to_string(), 1, 8),
value_node!("arg2".to_string(), 1, 14),
],
fields: vec![
(
make_tok!("foo", 1, 24),
Expression::Simple(Value::Int(value_node!(1, 1, 28))),
),
(
make_tok!("bar", 1, 30),
Expression::Simple(Value::Int(value_node!(2, 1, 34))),
),
],
pos: Position::new(1, 1),
})
);
}
#[test]
fn test_copy_parse() {
assert_error!(copy_expression("{}"));
assert_error!(copy_expression("foo"));
assert_error!(copy_expression("foo{"));
assert_parse!(
copy_expression("foo{}"),
Expression::Copy(CopyDef {
selector: make_selector!(make_expr!("foo", 1, 1), 1, 1),
fields: Vec::new(),
pos: Position::new(1, 1),
})
);
assert_parse!(
copy_expression("foo{bar=1}"),
Expression::Copy(CopyDef {
selector: make_selector!(make_expr!("foo", 1, 1), 1, 1),
fields: vec![(
make_tok!("bar", 1, 5),
Expression::Simple(Value::Int(value_node!(1, 1, 9))),
)],
pos: Position::new(1, 1),
})
);
assert_parse!(
copy_expression("foo{bar=1,}"),
Expression::Copy(CopyDef {
selector: make_selector!(make_expr!("foo", 1, 1), 1, 1),
fields: vec![(
make_tok!("bar", 1, 5),
Expression::Simple(Value::Int(value_node!(1, 1, 9))),
)],
pos: Position::new(1, 1),
})
);
}
#[test]
fn test_grouped_expression_parse() {
assert_error!(grouped_expression("foo"));
assert_error!(grouped_expression("(foo"));
assert_parse!(
grouped_expression("(foo)"),
Expression::Grouped(Box::new(Expression::Simple(Value::Selector(
make_selector!(make_expr!("foo", 1, 2), 1, 2)
))))
);
assert_parse!(
grouped_expression("(1 + 1)"),
Expression::Grouped(Box::new(Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 2)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))),
pos: Position::new(1, 2),
})))
);
}
#[test]
fn test_list_value_parse() {
assert_error!(list_value("foo"));
assert_error!(list_value("[foo"));
assert_error!(list_value("// commen\n[foo"));
assert_parse!(
list_value("[foo]"),
Value::List(ListDef {
elems: vec![Expression::Simple(Value::Selector(make_selector!(
make_expr!("foo", 1, 2),
1,
2
)))],
pos: Position::new(1, 1),
})
);
assert_parse!(
list_value("[1, 1]"),
Value::List(ListDef {
elems: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 2))),
Expression::Simple(Value::Int(value_node!(1, 1, 5))),
],
pos: Position::new(1, 1),
})
);
assert_parse!(
list_value("[1, 1,]"),
Value::List(ListDef {
elems: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 2))),
Expression::Simple(Value::Int(value_node!(1, 1, 5))),
],
pos: Position::new(1, 1),
})
);
assert_parse!(
list_value("// comment\n[1, 1]"),
Value::List(ListDef {
elems: vec![
Expression::Simple(Value::Int(value_node!(1, 2, 2))),
Expression::Simple(Value::Int(value_node!(1, 2, 5))),
],
pos: Position::new(2, 1),
})
);
assert_parse!(
list_value("[// comment\n1, 1]"),
Value::List(ListDef {
elems: vec![
Expression::Simple(Value::Int(value_node!(1, 2, 2))),
Expression::Simple(Value::Int(value_node!(1, 2, 5))),
],
pos: Position::new(1, 1),
})
);
assert_parse!(
list_value("[1, // comment\n1]"),
Value::List(ListDef {
elems: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 2))),
Expression::Simple(Value::Int(value_node!(1, 2, 1))),
],
pos: Position::new(1, 1),
})
);
assert_parse!(
list_value("[1, 1 // comment\n]"),
Value::List(ListDef {
elems: vec![
Expression::Simple(Value::Int(value_node!(1, 1, 2))),
Expression::Simple(Value::Int(value_node!(1, 1, 5))),
],
pos: Position::new(1, 1),
})
);
}
#[test]
fn test_tuple_parse() {
assert_error!(tuple("{"));
assert_error!(tuple("{ foo"));
assert_error!(tuple("{ foo ="));
assert_error!(tuple("{ foo = 1"));
assert_error!(tuple("{ foo = 1,"));
assert_error!(tuple("{ foo = 1, bar ="));
assert_error!(tuple("// comment\n{ foo = 1, bar ="));
assert_parse!(tuple("{ }"), Value::Tuple(value_node!(vec![], 1, 1)));
assert_parse!(
tuple("{ foo = 1 }"),
Value::Tuple(value_node!(
vec![(
make_tok!("foo", 1, 3),
Expression::Simple(Value::Int(value_node!(1, 1, 9))),
)],
1,
1
))
);
assert_parse!(
tuple("// comment\n{ foo = 1 }"),
Value::Tuple(value_node!(
vec![(
make_tok!("foo", 2, 3),
Expression::Simple(Value::Int(value_node!(1, 2, 9))),
)],
1,
1
))
);
assert_parse!(
tuple("{// comment\n foo = 1 }"),
Value::Tuple(value_node!(
vec![(
make_tok!("foo", 2, 2),
Expression::Simple(Value::Int(value_node!(1, 2, 8))),
)],
1,
1
))
);
assert_parse!(
tuple("{ foo = 1// comment\n }"),
Value::Tuple(value_node!(
vec![(
make_tok!("foo", 1, 3),
Expression::Simple(Value::Int(value_node!(1, 1, 9))),
)],
1,
1
))
);
assert_parse!(
tuple("{ foo = 1, bar = \"1\" }"),
Value::Tuple(value_node!(
vec![
(
make_tok!("foo", 1, 3),
Expression::Simple(Value::Int(value_node!(1, 1, 9))),
),
(
make_tok!("bar", 1, 12),
Expression::Simple(Value::String(value_node!(
"1".to_string(),
Position::new(1, 18)
))),
),
],
1,
1
))
);
assert_parse!(
tuple("{ foo = 1, // comment\nbar = \"1\" }"),
Value::Tuple(value_node!(
vec![
(
make_tok!("foo", 1, 3),
Expression::Simple(Value::Int(value_node!(1, 1, 9))),
),
(
make_tok!("bar", 2, 1),
Expression::Simple(Value::String(value_node!(
"1".to_string(),
Position::new(2, 7)
))),
),
],
1,
1
))
);
assert_parse!(
tuple("{ foo = 1, bar = {} }"),
Value::Tuple(value_node!(
vec![
(
make_tok!("foo", 1, 3),
Expression::Simple(Value::Int(value_node!(1, Position::new(1, 9)))),
),
(
make_tok!("bar", 1, 12),
Expression::Simple(Value::Tuple(value_node!(Vec::new(), Position::new(1, 17)))),
),
],
1,
1
))
);
assert_parse!(
tuple("{ foo = 1, bar = {}, }"),
Value::Tuple(value_node!(
vec![
(
make_tok!("foo", 1, 3),
Expression::Simple(Value::Int(value_node!(1, Position::new(1, 9)))),
),
(
make_tok!("bar", 1, 12),
Expression::Simple(Value::Tuple(value_node!(Vec::new(), Position::new(1, 17)))),
),
],
1,
1
))
);
}
#[test]
fn test_field_list_parse() {
let mut f_list = "foo = 1, quux = 2;";
assert_parse!(
field_list(f_list),
vec![
(make_tok!("foo", 1, 1), make_expr!(1 => int, 1, 7)),
(make_tok!("quux", 1, 10), make_expr!(2 => int, 1, 17)),
]
);
f_list = "foo = 1, // comment\nquux = 2;";
assert_parse!(
field_list(f_list),
vec![
(make_tok!("foo", 1, 1), make_expr!(1 => int, 1, 7)),
(make_tok!("quux", 2, 1), make_expr!(2 => int, 2, 8)),
]
);
f_list = "foo = 1,\n// comment\nquux = 2;";
assert_parse!(
field_list(f_list),
vec![
(make_tok!("foo", 1, 1), make_expr!(1 => int, 1, 7)),
(make_tok!("quux", 3, 1), make_expr!(2 => int, 3, 8)),
]
);
}
#[test]
fn test_field_value_parse() {
assert_error!(field_value("foo"));
assert_error!(field_value("// comment\nfoo"));
assert_error!(field_value("foo ="));
assert_parse!(
field_value("foo = 1"),
(
make_tok!("foo", 1, 1),
Expression::Simple(Value::Int(value_node!(1, 1, 7)))
)
);
assert_parse!(
field_value("foo = 1 // foo comment\n"),
(
make_tok!("foo", 1, 1),
Expression::Simple(Value::Int(value_node!(1, 1, 7)))
)
);
assert_parse!(
field_value("foo // foo comment\n = 1"),
(
make_tok!("foo", 1, 1),
Expression::Simple(Value::Int(value_node!(1, 2, 4)))
)
);
assert_parse!(
field_value("// foo comment\nfoo = 1"),
(
make_tok!("foo", 2, 1),
Expression::Simple(Value::Int(value_node!(1, 2, 7)))
)
);
assert_parse!(
field_value("foo = \"1\""),
(
make_tok!("foo", 1, 1),
Expression::Simple(Value::String(value_node!("1".to_string(), 1, 7)))
)
);
assert_parse!(
field_value("foo = bar "),
(
make_tok!("foo", 1, 1),
Expression::Simple(Value::Selector(make_selector!(
make_expr!("bar", 1, 7),
1,
7
)))
)
);
assert_parse!(
field_value("foo = bar.baz "),
(
make_tok!("foo", 1, 1),
Expression::Simple(Value::Selector(
make_selector!(make_expr!("bar", 1, 7) => [ make_tok!("baz", 1, 11) ] => 1, 7),
))
)
);
}
#[test]
fn test_number_parsing() {
assert_error!(number("."));
assert_error!(number(". "));
assert_parse!(number("1.0"), Value::Float(value_node!(1.0, 1, 1)));
assert_parse!(number("1."), Value::Float(value_node!(1.0, 1, 1)));
assert_parse!(number("1"), Value::Int(value_node!(1, 1, 1)));
assert_parse!(number(".1"), Value::Float(value_node!(0.1, 1, 1)));
}
#[test]
fn test_parse() {
let bad_input = LocatedSpan::new("import mylib as lib;");
let bad_result = parse(bad_input);
assert!(bad_result.is_err());
// Valid parsing tree
let input = LocatedSpan::new("import \"mylib\" as lib;let foo = 1;1+1;");
let result = parse(input);
assert!(result.is_ok(), format!("Expected Ok, Got {:?}", result));
let tpl = result.unwrap();
assert_eq!(
tpl,
vec![
Statement::Import(ImportDef {
path: make_tok!(QUOT => "mylib", 1, 8),
name: make_tok!("lib", 1, 19),
}),
Statement::Let(LetDef {
name: make_tok!("foo", 1, 27),
value: Expression::Simple(Value::Int(value_node!(1, 1, 33))),
}),
Statement::Expression(Expression::Binary(BinaryOpDef {
kind: BinaryExprType::Add,
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 35)))),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 37)))),
pos: Position::new(1, 35),
})),
]
);
}