Fix key, value in membership and some-in

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2023-02-20 07:57:30 -08:00
committed by Anand Krishnamoorthi
parent 3549931342
commit eded43bdc6
10 changed files with 60 additions and 74 deletions

View File

@@ -136,8 +136,8 @@ pub enum Expr<'source> {
Membership {
span: Span<'source>,
key: Box<Expr<'source>>,
value: Box<Option<Expr<'source>>>,
key: Box<Option<Expr<'source>>>,
value: Box<Expr<'source>>,
collection: Box<Expr<'source>>,
},
}
@@ -174,8 +174,8 @@ pub enum Literal<'source> {
},
SomeIn {
span: Span<'source>,
key: Expr<'source>,
value: Option<Expr<'source>>,
key: Option<Expr<'source>>,
value: Expr<'source>,
collection: Expr<'source>,
},
Expr {

View File

@@ -233,10 +233,10 @@ impl<'source> Interpreter<'source> {
collection,
..
} => {
self.hoist_loops_impl(key, loops);
if let Some(value) = value.as_ref() {
self.hoist_loops_impl(value, loops);
if let Some(key) = key.as_ref() {
self.hoist_loops_impl(key, loops);
}
self.hoist_loops_impl(value, loops);
self.hoist_loops_impl(collection, loops);
}
@@ -258,10 +258,10 @@ impl<'source> Interpreter<'source> {
collection,
..
} => {
self.hoist_loops_impl(key, &mut loops);
if let Some(value) = value {
self.hoist_loops_impl(value, &mut loops);
if let Some(key) = key {
self.hoist_loops_impl(key, &mut loops);
}
self.hoist_loops_impl(value, &mut loops);
self.hoist_loops_impl(collection, &mut loops);
}
Every {
@@ -548,18 +548,8 @@ impl<'source> Interpreter<'source> {
}
true
}
Literal::SomeIn {
key,
value,
collection,
..
} => {
let value = self.eval_membership(key, value, collection)?;
if let Value::Bool(bool) = value {
bool
} else {
panic!();
}
Literal::SomeIn { .. } => {
unimplemented!()
}
Literal::NotExpr { expr, .. } => matches!(self.eval_expr(expr)?, Value::Bool(false)),
Literal::Every {
@@ -861,37 +851,35 @@ impl<'source> Interpreter<'source> {
fn eval_membership(
&mut self,
key: &'source Expr<'source>,
value: &'source Option<Expr<'source>>,
key: &'source Option<Expr<'source>>,
value: &'source Expr<'source>,
collection: &'source Expr<'source>,
) -> Result<Value> {
let key = self.eval_expr(key)?;
let value = self.eval_expr(value)?;
let collection = self.eval_expr(collection)?;
let result = match &collection {
Value::Array(array) => {
if let Some(value) = value {
let value = self.eval_expr(value)?;
if let Some(key) = key {
let key = self.eval_expr(key)?;
collection[&key] == value
} else {
array.iter().any(|item| *item == key)
array.iter().any(|item| *item == value)
}
}
Value::Object(object) => {
if let Some(value) = value {
let value = self.eval_expr(value)?;
if let Some(key) = key {
let key = self.eval_expr(key)?;
collection[&key] == value
} else {
object.values().into_iter().any(|item| *item == key)
object.values().into_iter().any(|item| *item == value)
}
}
Value::Set(set) => {
if value.is_some() {
if key.is_some() {
false
//return Err(anyhow!("key-value pair is not supported for set"));
} else {
set.contains(&key)
set.contains(&value)
}
}
_ => {

View File

@@ -690,10 +690,14 @@ impl<'source> Parser<'source> {
self.parse_future_keyword("in", false, "while parsing membership expression")?;
let expr3 = self.parse_bool_expr()?;
span.end = self.end;
let (key, value) = match expr2 {
Some(e) => (Box::new(Some(expr1)), Box::new(e)),
None => (Box::new(None), Box::new(expr1)),
};
expr1 = Expr::Membership {
span,
key: Box::new(expr1),
value: Box::new(expr2),
key,
value,
collection: Box::new(expr3),
};
expr2 = None;
@@ -856,8 +860,8 @@ impl<'source> Parser<'source> {
}
let (key, value) = match refs.len() {
2 => (refs[0].clone(), Some(refs[1].clone())),
1 => (refs[0].clone(), None),
2 => (Some(refs[0].clone()), refs[1].clone()),
1 => (None, refs[0].clone()),
_ => {
let span = &vars[2];
return Err(anyhow!(