Add null coalescing operator.

This commit is contained in:
Stephen Chung
2022-06-10 11:22:33 +08:00
parent 0f1e51b1c9
commit 8999872d62
7 changed files with 87 additions and 15 deletions

View File

@@ -417,6 +417,8 @@ pub enum Expr {
And(Box<BinaryExpr>, Position),
/// lhs `||` rhs
Or(Box<BinaryExpr>, Position),
/// lhs `??` rhs
Coalesce(Box<BinaryExpr>, Position),
/// Custom syntax
Custom(Box<CustomExpr>, Position),
}
@@ -510,11 +512,12 @@ impl fmt::Debug for Expr {
}
f.finish()
}
Self::And(x, pos) | Self::Or(x, pos) => {
Self::And(x, pos) | Self::Or(x, pos) | Self::Coalesce(x, pos) => {
let op_name = match self {
Self::And(..) => "And",
Self::Or(..) => "Or",
expr => unreachable!("Self::And or Self::Or expected but gets {:?}", expr),
Self::Coalesce(..) => "Coalesce",
expr => unreachable!("`And`, `Or` or `Coalesce` expected but gets {:?}", expr),
};
if !pos.is_none() {
@@ -696,6 +699,7 @@ impl Expr {
| Self::Variable(.., pos)
| Self::And(.., pos)
| Self::Or(.., pos)
| Self::Coalesce(.., pos)
| Self::Index(.., pos)
| Self::Dot(.., pos)
| Self::Custom(.., pos)
@@ -721,10 +725,15 @@ impl Expr {
self.position()
}
}
Self::And(x, ..) | Self::Or(x, ..) | Self::Index(x, ..) | Self::Dot(x, ..) => {
x.lhs.start_position()
}
Self::And(x, ..)
| Self::Or(x, ..)
| Self::Coalesce(x, ..)
| Self::Index(x, ..)
| Self::Dot(x, ..) => x.lhs.start_position(),
Self::FnCall(.., pos) => *pos,
_ => self.position(),
}
}
@@ -745,6 +754,7 @@ impl Expr {
| Self::Map(.., pos)
| Self::And(.., pos)
| Self::Or(.., pos)
| Self::Coalesce(.., pos)
| Self::Dot(.., pos)
| Self::Index(.., pos)
| Self::Variable(.., pos)
@@ -770,7 +780,9 @@ impl Expr {
Self::Map(x, ..) => x.0.iter().map(|(.., v)| v).all(Self::is_pure),
Self::And(x, ..) | Self::Or(x, ..) => x.lhs.is_pure() && x.rhs.is_pure(),
Self::And(x, ..) | Self::Or(x, ..) | Self::Coalesce(x, ..) => {
x.lhs.is_pure() && x.rhs.is_pure()
}
Self::Stmt(x) => x.iter().all(Stmt::is_pure),
@@ -828,6 +840,7 @@ impl Expr {
| Self::CharConstant(..)
| Self::And(..)
| Self::Or(..)
| Self::Coalesce(..)
| Self::Unit(..) => false,
Self::IntegerConstant(..)
@@ -892,7 +905,11 @@ impl Expr {
}
}
}
Self::Index(x, ..) | Self::Dot(x, ..) | Expr::And(x, ..) | Expr::Or(x, ..) => {
Self::Index(x, ..)
| Self::Dot(x, ..)
| Expr::And(x, ..)
| Expr::Or(x, ..)
| Expr::Coalesce(x, ..) => {
if !x.lhs.walk(path, on_node) {
return false;
}