mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
Add grouped expression support for binary operators.
This commit is contained in:
parent
4265b0177b
commit
0d0f66f9c7
144
src/parse.rs
144
src/parse.rs
@ -239,11 +239,11 @@ named!(simple_expression<TokenIter, Expression, error::Error>,
|
|||||||
);
|
);
|
||||||
|
|
||||||
fn tuple_to_binary_expression(
|
fn tuple_to_binary_expression(
|
||||||
tpl: (Position, BinaryExprType, Value, Expression),
|
tpl: (Position, BinaryExprType, Expression, Expression),
|
||||||
) -> ParseResult<Expression> {
|
) -> ParseResult<Expression> {
|
||||||
Ok(Expression::Binary(BinaryOpDef {
|
Ok(Expression::Binary(BinaryOpDef {
|
||||||
kind: tpl.1,
|
kind: tpl.1,
|
||||||
left: tpl.2,
|
left: Box::new(tpl.2),
|
||||||
right: Box::new(tpl.3),
|
right: Box::new(tpl.3),
|
||||||
pos: Position::new(tpl.0.line as usize, tpl.0.column as usize),
|
pos: Position::new(tpl.0.line as usize, tpl.0.column as usize),
|
||||||
}))
|
}))
|
||||||
@ -251,14 +251,10 @@ fn tuple_to_binary_expression(
|
|||||||
|
|
||||||
macro_rules! do_binary_expr {
|
macro_rules! do_binary_expr {
|
||||||
($i:expr, $subrule:ident!( $($args:tt)* ), $typ:expr) => {
|
($i:expr, $subrule:ident!( $($args:tt)* ), $typ:expr) => {
|
||||||
// NOTE(jwall): Nom macros do magic with their inputs. They in fact
|
|
||||||
// rewrite your macro argumets for you. Which means we require this $i
|
|
||||||
// paramater even though we don't explicitely pass it below. I don't
|
|
||||||
// particularly like this but I'm living with it for now.
|
|
||||||
map_res!($i,
|
map_res!($i,
|
||||||
do_parse!(
|
do_parse!(
|
||||||
pos: pos >>
|
pos: pos >>
|
||||||
left: value >>
|
left: alt!(simple_expression | grouped_expression) >>
|
||||||
$subrule!($($args)*) >>
|
$subrule!($($args)*) >>
|
||||||
right: expression >>
|
right: expression >>
|
||||||
(pos, $typ, left, right)
|
(pos, $typ, left, right)
|
||||||
@ -286,28 +282,54 @@ named!(div_expression<TokenIter, Expression, error::Error>,
|
|||||||
do_binary_expr!(punct!("/"), BinaryExprType::Div)
|
do_binary_expr!(punct!("/"), BinaryExprType::Div)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fn tuple_to_compare_expression(
|
||||||
|
tpl: (Position, CompareType, Expression, Expression),
|
||||||
|
) -> ParseResult<Expression> {
|
||||||
|
Ok(Expression::Compare(ComparisonDef {
|
||||||
|
kind: tpl.1,
|
||||||
|
left: Box::new(tpl.2),
|
||||||
|
right: Box::new(tpl.3),
|
||||||
|
pos: Position::new(tpl.0.line as usize, tpl.0.column as usize),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! do_compare_expr {
|
||||||
|
($i:expr, $subrule:ident!( $($args:tt)* ), $typ:expr) => {
|
||||||
|
map_res!($i,
|
||||||
|
do_parse!(
|
||||||
|
pos: pos >>
|
||||||
|
left: alt!(simple_expression | grouped_expression) >>
|
||||||
|
$subrule!($($args)*) >>
|
||||||
|
right: expression >>
|
||||||
|
(pos, $typ, left, right)
|
||||||
|
),
|
||||||
|
tuple_to_compare_expression
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
named!(eqeq_expression<TokenIter, Expression, error::Error>,
|
named!(eqeq_expression<TokenIter, Expression, error::Error>,
|
||||||
do_binary_expr!(punct!("=="), BinaryExprType::Equal)
|
do_compare_expr!(punct!("=="), CompareType::Equal)
|
||||||
);
|
);
|
||||||
|
|
||||||
named!(not_eqeq_expression<TokenIter, Expression, error::Error>,
|
named!(not_eqeq_expression<TokenIter, Expression, error::Error>,
|
||||||
do_binary_expr!(punct!("!="), BinaryExprType::NotEqual)
|
do_compare_expr!(punct!("!="), CompareType::NotEqual)
|
||||||
);
|
);
|
||||||
|
|
||||||
named!(lt_eqeq_expression<TokenIter, Expression, error::Error>,
|
named!(lt_eqeq_expression<TokenIter, Expression, error::Error>,
|
||||||
do_binary_expr!(punct!("<="), BinaryExprType::LTEqual)
|
do_compare_expr!(punct!("<="), CompareType::LTEqual)
|
||||||
);
|
);
|
||||||
|
|
||||||
named!(gt_eqeq_expression<TokenIter, Expression, error::Error>,
|
named!(gt_eqeq_expression<TokenIter, Expression, error::Error>,
|
||||||
do_binary_expr!(punct!(">="), BinaryExprType::GTEqual)
|
do_compare_expr!(punct!(">="), CompareType::GTEqual)
|
||||||
);
|
);
|
||||||
|
|
||||||
named!(gt_expression<TokenIter, Expression, error::Error>,
|
named!(gt_expression<TokenIter, Expression, error::Error>,
|
||||||
do_binary_expr!(punct!(">"), BinaryExprType::GT)
|
do_compare_expr!(punct!(">"), CompareType::GT)
|
||||||
);
|
);
|
||||||
|
|
||||||
named!(lt_expression<TokenIter, Expression, error::Error>,
|
named!(lt_expression<TokenIter, Expression, error::Error>,
|
||||||
do_binary_expr!(punct!("<"), BinaryExprType::LT)
|
do_compare_expr!(punct!("<"), CompareType::LT)
|
||||||
);
|
);
|
||||||
|
|
||||||
fn expression_to_grouped_expression(e: Expression) -> ParseResult<Expression> {
|
fn expression_to_grouped_expression(e: Expression) -> ParseResult<Expression> {
|
||||||
@ -826,41 +848,39 @@ mod test {
|
|||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
|
|
||||||
macro_rules! assert_parse {
|
macro_rules! assert_parse {
|
||||||
($parsemac:ident( $i:expr ), $out:expr) => {
|
($parsemac: ident($i: expr), $out: expr) => {
|
||||||
assert_parse!($i, $parsemac, $out)
|
assert_parse!($i, $parsemac, $out)
|
||||||
};
|
};
|
||||||
($i:expr, $f:expr, $out:expr) => {
|
($i: expr, $f: expr, $out: expr) => {{
|
||||||
{
|
let input = LocatedSpan::new($i);
|
||||||
let input = LocatedSpan::new($i);
|
match tokenize(input) {
|
||||||
match tokenize(input) {
|
Err(e) => assert!(false, format!("Tokenizer Error: {:?}", e)),
|
||||||
Err(e) => assert!(false, format!("Tokenizer Error: {:?}", e)),
|
Ok(val) => match $f(TokenIter {
|
||||||
Ok(val) => {
|
source: val.as_slice(),
|
||||||
match $f(TokenIter{source: val.as_slice()}) {
|
}) {
|
||||||
IResult::Done(_, result) => assert_eq!(result, $out),
|
IResult::Done(_, result) => assert_eq!(result, $out),
|
||||||
other => assert!(false, format!("Expected Done got {:?}", other)),
|
other => assert!(false, format!("Expected Done got {:?}", other)),
|
||||||
}
|
},
|
||||||
},
|
}
|
||||||
}
|
};};
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! assert_error {
|
macro_rules! assert_error {
|
||||||
($parsemac:ident( $i:expr )) => {
|
($parsemac: ident($i: expr)) => {
|
||||||
assert_error!($i, $parsemac)
|
assert_error!($i, $parsemac)
|
||||||
};
|
};
|
||||||
($i:expr, $f:expr) => {
|
($i: expr, $f: expr) => {{
|
||||||
{
|
let input = LocatedSpan::new($i);
|
||||||
let input = LocatedSpan::new($i);
|
match tokenize(input) {
|
||||||
match tokenize(input) {
|
Err(_) => assert!(true),
|
||||||
Err(_) => assert!(true),
|
Ok(val) => {
|
||||||
Ok(val) => {
|
let result = $f(TokenIter {
|
||||||
let result = $f(TokenIter{source: val.as_slice()});
|
source: val.as_slice(),
|
||||||
assert!(result.is_err(), format!("Not an error: {:?}", result))
|
});
|
||||||
},
|
assert!(result.is_err(), format!("Not an error: {:?}", result))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1133,7 +1153,7 @@ mod test {
|
|||||||
expression("1 + 1"),
|
expression("1 + 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Add,
|
kind: BinaryExprType::Add,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
@ -1142,7 +1162,7 @@ mod test {
|
|||||||
expression("1 - 1"),
|
expression("1 - 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Sub,
|
kind: BinaryExprType::Sub,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
@ -1151,7 +1171,7 @@ mod test {
|
|||||||
expression("1 * 1"),
|
expression("1 * 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Mul,
|
kind: BinaryExprType::Mul,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
@ -1160,43 +1180,43 @@ mod test {
|
|||||||
expression("1 / 1"),
|
expression("1 / 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Div,
|
kind: BinaryExprType::Div,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_parse!(
|
assert_parse!(
|
||||||
expression("1 > 1"),
|
expression("1 > 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Compare(ComparisonDef {
|
||||||
kind: BinaryExprType::GT,
|
kind: CompareType::GT,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_parse!(
|
assert_parse!(
|
||||||
expression("1 < 1"),
|
expression("1 < 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Compare(ComparisonDef {
|
||||||
kind: BinaryExprType::LT,
|
kind: CompareType::LT,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_parse!(
|
assert_parse!(
|
||||||
expression("1 <= 1"),
|
expression("1 <= 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Compare(ComparisonDef {
|
||||||
kind: BinaryExprType::LTEqual,
|
kind: CompareType::LTEqual,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_parse!(
|
assert_parse!(
|
||||||
expression("1 >= 1"),
|
expression("1 >= 1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Compare(ComparisonDef {
|
||||||
kind: BinaryExprType::GTEqual,
|
kind: CompareType::GTEqual,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
@ -1205,7 +1225,7 @@ mod test {
|
|||||||
expression("1+1"),
|
expression("1+1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Add,
|
kind: BinaryExprType::Add,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
@ -1214,7 +1234,7 @@ mod test {
|
|||||||
expression("1-1"),
|
expression("1-1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Sub,
|
kind: BinaryExprType::Sub,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
@ -1223,7 +1243,7 @@ mod test {
|
|||||||
expression("1*1"),
|
expression("1*1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Mul,
|
kind: BinaryExprType::Mul,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
@ -1232,7 +1252,7 @@ mod test {
|
|||||||
expression("1/1"),
|
expression("1/1"),
|
||||||
Expression::Binary(BinaryOpDef {
|
Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Div,
|
kind: BinaryExprType::Div,
|
||||||
left: Value::Int(value_node!(1, 1, 1)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))),
|
||||||
pos: Position::new(1, 1),
|
pos: Position::new(1, 1),
|
||||||
})
|
})
|
||||||
@ -1292,7 +1312,7 @@ mod test {
|
|||||||
expression("(1 + 1)"),
|
expression("(1 + 1)"),
|
||||||
Expression::Grouped(Box::new(Expression::Binary(BinaryOpDef {
|
Expression::Grouped(Box::new(Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Add,
|
kind: BinaryExprType::Add,
|
||||||
left: Value::Int(value_node!(1, 1, 2)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 2)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))),
|
||||||
pos: Position::new(1, 2), // FIXME(jwall): grouped expressions appear to be getting positioned wrong
|
pos: Position::new(1, 2), // FIXME(jwall): grouped expressions appear to be getting positioned wrong
|
||||||
})))
|
})))
|
||||||
@ -1481,7 +1501,7 @@ mod test {
|
|||||||
grouped_expression("(1 + 1)"),
|
grouped_expression("(1 + 1)"),
|
||||||
Expression::Grouped(Box::new(Expression::Binary(BinaryOpDef {
|
Expression::Grouped(Box::new(Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Add,
|
kind: BinaryExprType::Add,
|
||||||
left: Value::Int(value_node!(1, 1, 2)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 2)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))),
|
||||||
pos: Position::new(1, 2),
|
pos: Position::new(1, 2),
|
||||||
})))
|
})))
|
||||||
@ -1821,7 +1841,7 @@ mod test {
|
|||||||
}),
|
}),
|
||||||
Statement::Expression(Expression::Binary(BinaryOpDef {
|
Statement::Expression(Expression::Binary(BinaryOpDef {
|
||||||
kind: BinaryExprType::Add,
|
kind: BinaryExprType::Add,
|
||||||
left: Value::Int(value_node!(1, 1, 35)),
|
left: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 35)))),
|
||||||
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 37)))),
|
right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 37)))),
|
||||||
pos: Position::new(1, 35),
|
pos: Position::new(1, 35),
|
||||||
})),
|
})),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user