-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathexpressions_as_statement.rs
75 lines (69 loc) · 2.29 KB
/
expressions_as_statement.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::nodes::{
BinaryExpression, BinaryOperator, Block, DoStatement, Expression, LocalAssignStatement,
Statement,
};
fn get_inner_expression(mut expression: Expression) -> Expression {
loop {
expression = match expression {
Expression::Parenthese(parenthese) => parenthese.into_inner_expression(),
Expression::TypeCast(type_cast) => type_cast.into_inner_expression(),
value => break value,
};
}
}
pub(crate) fn expressions_as_statement(expressions: Vec<Expression>) -> Statement {
let mut statements: Vec<Statement> = Vec::new();
for value in expressions {
match get_inner_expression(value) {
Expression::Call(call) => {
statements.push((*call).into());
}
value => {
if let Some(assign) = statements.last_mut().and_then(|statement| match statement {
Statement::LocalAssign(assign) => Some(assign),
_ => None,
}) {
assign.push_value(value);
} else {
statements.push(
LocalAssignStatement::from_variable("_")
.with_value(value)
.into(),
);
}
}
}
}
if statements.len() == 1 {
match statements.pop().unwrap() {
Statement::Call(call) => call.into(),
statement => statement,
}
} else {
DoStatement::new(Block::new(statements, None)).into()
}
}
pub(crate) fn expressions_as_expression(expressions: Vec<Expression>) -> Expression {
if expressions.is_empty() {
return Expression::nil();
}
if expressions.len() == 1 {
BinaryExpression::new(
BinaryOperator::And,
expressions.into_iter().next().unwrap(),
Expression::nil(),
)
.into()
} else {
expressions
.into_iter()
.rfold(Expression::nil(), |current, value| {
BinaryExpression::new(
BinaryOperator::And,
BinaryExpression::new(BinaryOperator::Or, value, true),
current,
)
.into()
})
}
}