basic implementation of short circuiting with or
op
This commit is contained in:
parent
39d439b2c2
commit
07d6faf64b
@ -887,9 +887,9 @@ impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> {
|
|||||||
space_separated.push(right.map_node(|n| Value::UnaryOp(op.node, Box::new(n))));
|
space_separated.push(right.map_node(|n| Value::UnaryOp(op.node, Box::new(n))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Op::And | Op::Or => {
|
Op::And => {
|
||||||
self.whitespace();
|
self.whitespace();
|
||||||
// special case when the value is literally "and" or "or"
|
// special case when the value is literally "and"
|
||||||
if self.peek().is_none() {
|
if self.peek().is_none() {
|
||||||
space_separated
|
space_separated
|
||||||
.push(Value::String(op.to_string(), QuoteKind::None).span(op.span));
|
.push(Value::String(op.to_string(), QuoteKind::None).span(op.span));
|
||||||
@ -904,6 +904,38 @@ impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> {
|
|||||||
return Err(("Expected expression.", op.span).into());
|
return Err(("Expected expression.", op.span).into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Op::Or => {
|
||||||
|
self.whitespace();
|
||||||
|
// special case when the value is literally "or"
|
||||||
|
if self.peek().is_none() {
|
||||||
|
space_separated
|
||||||
|
.push(Value::String(op.to_string(), QuoteKind::None).span(op.span));
|
||||||
|
} else if let Some(left) = space_separated.pop() {
|
||||||
|
self.whitespace();
|
||||||
|
if left.node.is_true(left.span)? {
|
||||||
|
// we explicitly ignore errors here as a workaround for short circuiting
|
||||||
|
while let Some(foo) = self.peek() {
|
||||||
|
if let Ok(Spanned {
|
||||||
|
node: IntermediateValue::Comma,
|
||||||
|
..
|
||||||
|
}) = foo
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
self.next();
|
||||||
|
}
|
||||||
|
space_separated.push(left);
|
||||||
|
} else {
|
||||||
|
let right = self.single_value()?;
|
||||||
|
space_separated.push(
|
||||||
|
Value::BinaryOp(Box::new(left.node), op.node, Box::new(right.node))
|
||||||
|
.span(left.span.merge(right.span)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(("Expected expression.", op.span).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(left) = space_separated.pop() {
|
if let Some(left) = space_separated.pop() {
|
||||||
self.whitespace();
|
self.whitespace();
|
||||||
|
14
tests/or.rs
14
tests/or.rs
@ -59,3 +59,17 @@ test!(
|
|||||||
"a {\n color: 1 - OR;\n}\n",
|
"a {\n color: 1 - OR;\n}\n",
|
||||||
"a {\n color: 1-OR;\n}\n"
|
"a {\n color: 1-OR;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
short_circuits_when_lhs_is_true,
|
||||||
|
"a {\n color: true or red % foo;\n}\n",
|
||||||
|
"a {\n color: true;\n}\n"
|
||||||
|
);
|
||||||
|
error!(
|
||||||
|
does_not_short_circuit_when_lhs_is_false,
|
||||||
|
"a {\n color: false or red % foo;\n}\n", "Error: Undefined operation \"red % foo\"."
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
short_circuiting_in_comma_separated_list,
|
||||||
|
"a {\n color: true or red % foo, red;\n}\n",
|
||||||
|
"a {\n color: true, red;\n}\n"
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user