Merge Expr::True/False into BoolConstant.
This commit is contained in:
parent
b87fa87a75
commit
15afd83da5
21
src/ast.rs
21
src/ast.rs
@ -862,6 +862,8 @@ pub enum Expr {
|
||||
/// Used to hold either an Array or Map literal for quick cloning.
|
||||
/// All other primitive data types should use the appropriate variants for better speed.
|
||||
DynamicConstant(Box<Dynamic>, Position),
|
||||
/// Boolean constant.
|
||||
BoolConstant(bool, Position),
|
||||
/// Integer constant.
|
||||
IntegerConstant(INT, Position),
|
||||
/// Floating-point constant.
|
||||
@ -877,10 +879,6 @@ pub enum Expr {
|
||||
Array(Box<StaticVec<Expr>>, Position),
|
||||
/// #{ name:expr, ... }
|
||||
Map(Box<StaticVec<(IdentX, Expr)>>, Position),
|
||||
/// true
|
||||
True(Position),
|
||||
/// false
|
||||
False(Position),
|
||||
/// ()
|
||||
Unit(Position),
|
||||
/// Variable access - (optional index, optional modules, hash, variable name)
|
||||
@ -932,8 +930,7 @@ impl Expr {
|
||||
x.clone(),
|
||||
Default::default(),
|
||||
)))),
|
||||
Self::True(_) => true.into(),
|
||||
Self::False(_) => false.into(),
|
||||
Self::BoolConstant(x, _) => (*x).into(),
|
||||
Self::Unit(_) => ().into(),
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
@ -978,6 +975,7 @@ impl Expr {
|
||||
Self::FloatConstant(_, pos) => *pos,
|
||||
|
||||
Self::DynamicConstant(_, pos) => *pos,
|
||||
Self::BoolConstant(_, pos) => *pos,
|
||||
Self::IntegerConstant(_, pos) => *pos,
|
||||
Self::CharConstant(_, pos) => *pos,
|
||||
Self::StringConstant(_, pos) => *pos,
|
||||
@ -991,7 +989,7 @@ impl Expr {
|
||||
|
||||
Self::And(x, _) | Self::Or(x, _) | Self::In(x, _) => x.lhs.position(),
|
||||
|
||||
Self::True(pos) | Self::False(pos) | Self::Unit(pos) => *pos,
|
||||
Self::Unit(pos) => *pos,
|
||||
|
||||
Self::Dot(x, _) | Self::Index(x, _) => x.lhs.position(),
|
||||
|
||||
@ -1009,6 +1007,7 @@ impl Expr {
|
||||
Self::FloatConstant(_, pos) => *pos = new_pos,
|
||||
|
||||
Self::DynamicConstant(_, pos) => *pos = new_pos,
|
||||
Self::BoolConstant(_, pos) => *pos = new_pos,
|
||||
Self::IntegerConstant(_, pos) => *pos = new_pos,
|
||||
Self::CharConstant(_, pos) => *pos = new_pos,
|
||||
Self::StringConstant(_, pos) => *pos = new_pos,
|
||||
@ -1020,7 +1019,7 @@ impl Expr {
|
||||
Self::Stmt(_, pos) => *pos = new_pos,
|
||||
Self::FnCall(_, pos) => *pos = new_pos,
|
||||
Self::And(_, pos) | Self::Or(_, pos) | Self::In(_, pos) => *pos = new_pos,
|
||||
Self::True(pos) | Self::False(pos) | Self::Unit(pos) => *pos = new_pos,
|
||||
Self::Unit(pos) => *pos = new_pos,
|
||||
Self::Dot(_, pos) | Self::Index(_, pos) => *pos = new_pos,
|
||||
Self::Custom(_, pos) => *pos = new_pos,
|
||||
}
|
||||
@ -1066,12 +1065,11 @@ impl Expr {
|
||||
Self::FloatConstant(_, _) => true,
|
||||
|
||||
Self::DynamicConstant(_, _)
|
||||
| Self::BoolConstant(_, _)
|
||||
| Self::IntegerConstant(_, _)
|
||||
| Self::CharConstant(_, _)
|
||||
| Self::StringConstant(_, _)
|
||||
| Self::FnPointer(_, _)
|
||||
| Self::True(_)
|
||||
| Self::False(_)
|
||||
| Self::Unit(_) => true,
|
||||
|
||||
// An array literal is constant if all items are constant
|
||||
@ -1099,14 +1097,13 @@ impl Expr {
|
||||
Self::FloatConstant(_, _) => false,
|
||||
|
||||
Self::DynamicConstant(_, _)
|
||||
| Self::BoolConstant(_, _)
|
||||
| Self::IntegerConstant(_, _)
|
||||
| Self::CharConstant(_, _)
|
||||
| Self::FnPointer(_, _)
|
||||
| Self::In(_, _)
|
||||
| Self::And(_, _)
|
||||
| Self::Or(_, _)
|
||||
| Self::True(_)
|
||||
| Self::False(_)
|
||||
| Self::Unit(_) => false,
|
||||
|
||||
Self::StringConstant(_, _)
|
||||
|
@ -1815,8 +1815,7 @@ impl Engine {
|
||||
.into())
|
||||
}
|
||||
|
||||
Expr::True(_) => Ok(true.into()),
|
||||
Expr::False(_) => Ok(false.into()),
|
||||
Expr::BoolConstant(x, _) => Ok((*x).into()),
|
||||
Expr::Unit(_) => Ok(Dynamic::UNIT),
|
||||
|
||||
Expr::Custom(custom, _) => {
|
||||
|
@ -282,12 +282,12 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
|
||||
},
|
||||
|
||||
// if false { if_block } -> Noop
|
||||
Stmt::If(Expr::False(pos), x, _) if x.1.is_none() => {
|
||||
Stmt::If(Expr::BoolConstant(false, pos), x, _) if x.1.is_none() => {
|
||||
state.set_dirty();
|
||||
*stmt = Stmt::Noop(*pos);
|
||||
}
|
||||
// if true { if_block } -> if_block
|
||||
Stmt::If(Expr::True(_), x, _) if x.1.is_none() => {
|
||||
Stmt::If(Expr::BoolConstant(true, _), x, _) if x.1.is_none() => {
|
||||
*stmt = mem::take(&mut x.0);
|
||||
optimize_stmt(stmt, state, true);
|
||||
}
|
||||
@ -316,12 +316,12 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
|
||||
optimize_stmt(&mut x.0, state, true);
|
||||
}
|
||||
// if false { if_block } else { else_block } -> else_block
|
||||
Stmt::If(Expr::False(_), x, _) if x.1.is_some() => {
|
||||
Stmt::If(Expr::BoolConstant(false, _), x, _) if x.1.is_some() => {
|
||||
*stmt = mem::take(x.1.as_mut().unwrap());
|
||||
optimize_stmt(stmt, state, true);
|
||||
}
|
||||
// if true { if_block } else { else_block } -> if_block
|
||||
Stmt::If(Expr::True(_), x, _) => {
|
||||
Stmt::If(Expr::BoolConstant(true, _), x, _) => {
|
||||
*stmt = mem::take(&mut x.0);
|
||||
optimize_stmt(stmt, state, true);
|
||||
}
|
||||
@ -375,12 +375,12 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
|
||||
}
|
||||
|
||||
// while false { block } -> Noop
|
||||
Stmt::While(Expr::False(pos), _, _) => {
|
||||
Stmt::While(Expr::BoolConstant(false, pos), _, _) => {
|
||||
state.set_dirty();
|
||||
*stmt = Stmt::Noop(*pos)
|
||||
}
|
||||
// while true { block } -> loop { block }
|
||||
Stmt::While(Expr::True(_), block, pos) => {
|
||||
Stmt::While(Expr::BoolConstant(true, _), block, pos) => {
|
||||
optimize_stmt(block, state, false);
|
||||
*stmt = Stmt::Loop(Box::new(mem::take(block)), *pos)
|
||||
}
|
||||
@ -576,32 +576,23 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
|
||||
// "xxx" in "xxxxx"
|
||||
(Expr::StringConstant(a, pos), Expr::StringConstant(b, _)) => {
|
||||
state.set_dirty();
|
||||
*expr = if b.contains(a.as_str()) { Expr::True(*pos) } else { Expr::False(*pos) };
|
||||
*expr = Expr::BoolConstant( b.contains(a.as_str()), *pos);
|
||||
}
|
||||
// 'x' in "xxxxx"
|
||||
(Expr::CharConstant(a, pos), Expr::StringConstant(b, _)) => {
|
||||
state.set_dirty();
|
||||
*expr = if b.contains(*a) { Expr::True(*pos) } else { Expr::False(*pos) };
|
||||
*expr = Expr::BoolConstant(b.contains(*a), *pos);
|
||||
}
|
||||
// "xxx" in #{...}
|
||||
(Expr::StringConstant(a, pos), Expr::Map(b, _)) => {
|
||||
state.set_dirty();
|
||||
*expr = if b.iter().find(|(x, _)| x.name == *a).is_some() {
|
||||
Expr::True(*pos)
|
||||
} else {
|
||||
Expr::False(*pos)
|
||||
};
|
||||
*expr = Expr::BoolConstant(b.iter().find(|(x, _)| x.name == *a).is_some(), *pos);
|
||||
}
|
||||
// 'x' in #{...}
|
||||
(Expr::CharConstant(a, pos), Expr::Map(b, _)) => {
|
||||
state.set_dirty();
|
||||
let ch = a.to_string();
|
||||
|
||||
*expr = if b.iter().find(|(x, _)| x.name == &ch).is_some() {
|
||||
Expr::True(*pos)
|
||||
} else {
|
||||
Expr::False(*pos)
|
||||
};
|
||||
*expr = Expr::BoolConstant(b.iter().find(|(x, _)| x.name == &ch).is_some(), *pos);
|
||||
}
|
||||
// lhs in rhs
|
||||
(lhs, rhs) => { optimize_expr(lhs, state); optimize_expr(rhs, state); }
|
||||
@ -609,18 +600,18 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
|
||||
// lhs && rhs
|
||||
Expr::And(x, _) => match (&mut x.lhs, &mut x.rhs) {
|
||||
// true && rhs -> rhs
|
||||
(Expr::True(_), rhs) => {
|
||||
(Expr::BoolConstant(true, _), rhs) => {
|
||||
state.set_dirty();
|
||||
optimize_expr(rhs, state);
|
||||
*expr = mem::take(rhs);
|
||||
}
|
||||
// false && rhs -> false
|
||||
(Expr::False(pos), _) => {
|
||||
(Expr::BoolConstant(false, pos), _) => {
|
||||
state.set_dirty();
|
||||
*expr = Expr::False(*pos);
|
||||
*expr = Expr::BoolConstant(false, *pos);
|
||||
}
|
||||
// lhs && true -> lhs
|
||||
(lhs, Expr::True(_)) => {
|
||||
(lhs, Expr::BoolConstant(true, _)) => {
|
||||
state.set_dirty();
|
||||
optimize_expr(lhs, state);
|
||||
*expr = mem::take(lhs);
|
||||
@ -631,18 +622,18 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
|
||||
// lhs || rhs
|
||||
Expr::Or(ref mut x, _) => match (&mut x.lhs, &mut x.rhs) {
|
||||
// false || rhs -> rhs
|
||||
(Expr::False(_), rhs) => {
|
||||
(Expr::BoolConstant(false, _), rhs) => {
|
||||
state.set_dirty();
|
||||
optimize_expr(rhs, state);
|
||||
*expr = mem::take(rhs);
|
||||
}
|
||||
// true || rhs -> true
|
||||
(Expr::True(pos), _) => {
|
||||
(Expr::BoolConstant(true, pos), _) => {
|
||||
state.set_dirty();
|
||||
*expr = Expr::True(*pos);
|
||||
*expr = Expr::BoolConstant(true, *pos);
|
||||
}
|
||||
// lhs || false
|
||||
(lhs, Expr::False(_)) => {
|
||||
(lhs, Expr::BoolConstant(false, _)) => {
|
||||
state.set_dirty();
|
||||
optimize_expr(lhs, state);
|
||||
*expr = mem::take(lhs);
|
||||
|
@ -464,8 +464,7 @@ fn parse_index_chain(
|
||||
| Expr::And(_, _)
|
||||
| Expr::Or(_, _)
|
||||
| Expr::In(_, _)
|
||||
| Expr::True(_)
|
||||
| Expr::False(_)
|
||||
| Expr::BoolConstant(_, _)
|
||||
| Expr::Unit(_) => {
|
||||
return Err(PERR::MalformedIndexExpr(
|
||||
"Only arrays, object maps and strings can be indexed".into(),
|
||||
@ -499,8 +498,7 @@ fn parse_index_chain(
|
||||
| Expr::And(_, _)
|
||||
| Expr::Or(_, _)
|
||||
| Expr::In(_, _)
|
||||
| Expr::True(_)
|
||||
| Expr::False(_)
|
||||
| Expr::BoolConstant(_, _)
|
||||
| Expr::Unit(_) => {
|
||||
return Err(PERR::MalformedIndexExpr(
|
||||
"Only arrays, object maps and strings can be indexed".into(),
|
||||
@ -541,7 +539,7 @@ fn parse_index_chain(
|
||||
.into_err(x.position()))
|
||||
}
|
||||
// lhs[true], lhs[false]
|
||||
x @ Expr::True(_) | x @ Expr::False(_) => {
|
||||
x @ Expr::BoolConstant(_, _) => {
|
||||
return Err(PERR::MalformedIndexExpr(
|
||||
"Array access expects integer index, not a boolean".into(),
|
||||
)
|
||||
@ -999,8 +997,8 @@ fn parse_primary(
|
||||
Token::LeftBracket => parse_array_literal(input, state, lib, settings.level_up())?,
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Token::MapStart => parse_map_literal(input, state, lib, settings.level_up())?,
|
||||
Token::True => Expr::True(settings.pos),
|
||||
Token::False => Expr::False(settings.pos),
|
||||
Token::True => Expr::BoolConstant(true, settings.pos),
|
||||
Token::False => Expr::BoolConstant(false, settings.pos),
|
||||
Token::LexError(err) => return Err(err.into_err(settings.pos)),
|
||||
|
||||
_ => {
|
||||
@ -1451,8 +1449,7 @@ fn make_in_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result<Expr, ParseErr
|
||||
| (_, x @ Expr::And(_, _))
|
||||
| (_, x @ Expr::Or(_, _))
|
||||
| (_, x @ Expr::In(_, _))
|
||||
| (_, x @ Expr::True(_))
|
||||
| (_, x @ Expr::False(_))
|
||||
| (_, x @ Expr::BoolConstant(_, _))
|
||||
| (_, x @ Expr::Unit(_)) => {
|
||||
return Err(PERR::MalformedInExpr(
|
||||
"'in' expression expects a string, array or object map".into(),
|
||||
@ -1492,8 +1489,7 @@ fn make_in_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result<Expr, ParseErr
|
||||
(x @ Expr::And(_, _), Expr::StringConstant(_, _))
|
||||
| (x @ Expr::Or(_, _), Expr::StringConstant(_, _))
|
||||
| (x @ Expr::In(_, _), Expr::StringConstant(_, _))
|
||||
| (x @ Expr::True(_), Expr::StringConstant(_, _))
|
||||
| (x @ Expr::False(_), Expr::StringConstant(_, _)) => {
|
||||
| (x @ Expr::BoolConstant(_, _), Expr::StringConstant(_, _)) => {
|
||||
return Err(PERR::MalformedInExpr(
|
||||
"'in' expression for a string expects a string, not a boolean".into(),
|
||||
)
|
||||
@ -1545,8 +1541,7 @@ fn make_in_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result<Expr, ParseErr
|
||||
(x @ Expr::And(_, _), Expr::Map(_, _))
|
||||
| (x @ Expr::Or(_, _), Expr::Map(_, _))
|
||||
| (x @ Expr::In(_, _), Expr::Map(_, _))
|
||||
| (x @ Expr::True(_), Expr::Map(_, _))
|
||||
| (x @ Expr::False(_), Expr::Map(_, _)) => {
|
||||
| (x @ Expr::BoolConstant(_, _), Expr::Map(_, _)) => {
|
||||
return Err(PERR::MalformedInExpr(
|
||||
"'in' expression for an object map expects a string, not a boolean".into(),
|
||||
)
|
||||
@ -2961,8 +2956,7 @@ pub fn map_dynamic_to_expr(value: Dynamic, pos: Position) -> Option<Expr> {
|
||||
Union::Int(value) => Some(Expr::IntegerConstant(value, pos)),
|
||||
Union::Char(value) => Some(Expr::CharConstant(value, pos)),
|
||||
Union::Str(value) => Some(Expr::StringConstant(value, pos)),
|
||||
Union::Bool(true) => Some(Expr::True(pos)),
|
||||
Union::Bool(false) => Some(Expr::False(pos)),
|
||||
Union::Bool(value) => Some(Expr::BoolConstant(value, pos)),
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Array(array) => {
|
||||
let items: Vec<_> = array
|
||||
|
Loading…
Reference in New Issue
Block a user