mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Early quit loop when body returns error 🛑
This commit is contained in:
parent
790dc9e667
commit
58f799c41c
@ -429,57 +429,59 @@ impl Eval for ExprFor {
|
|||||||
|
|
||||||
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
||||||
macro_rules! iter {
|
macro_rules! iter {
|
||||||
(for ($($binding:ident => $value:ident),*) in $iter:expr) => {{
|
(for ($($binding:ident => $value:ident),*) in $iter:expr) => {
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
ctx.scopes.push();
|
||||||
|
|
||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
for ($($value),*) in $iter {
|
for ($($value),*) in $iter {
|
||||||
$(ctx.scopes.def_mut($binding.as_str(), $value);)*
|
$(ctx.scopes.def_mut($binding.as_str(), $value);)*
|
||||||
|
|
||||||
if let Value::Template(new) = self.body.eval(ctx) {
|
match self.body.eval(ctx) {
|
||||||
output.extend(new);
|
Value::Template(new) => output.extend(new),
|
||||||
|
Value::Error => {
|
||||||
|
ctx.scopes.pop();
|
||||||
|
return Value::Error;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::Template(output)
|
ctx.scopes.pop();
|
||||||
}};
|
return Value::Template(output);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.scopes.push();
|
|
||||||
|
|
||||||
let iter = self.iter.eval(ctx);
|
let iter = self.iter.eval(ctx);
|
||||||
let value = match (self.pattern.clone(), iter) {
|
match (self.pattern.clone(), iter) {
|
||||||
(ForPattern::Value(v), Value::Str(string)) => {
|
(ForPattern::Value(v), Value::Str(string)) => {
|
||||||
iter!(for (v => value) in string.chars().map(|c| Value::Str(c.into())))
|
iter!(for (v => value) in string.chars().map(|c| Value::Str(c.into())));
|
||||||
}
|
}
|
||||||
(ForPattern::Value(v), Value::Array(array)) => {
|
(ForPattern::Value(v), Value::Array(array)) => {
|
||||||
iter!(for (v => value) in array.into_iter())
|
iter!(for (v => value) in array.into_iter());
|
||||||
}
|
}
|
||||||
(ForPattern::Value(v), Value::Dict(dict)) => {
|
(ForPattern::Value(v), Value::Dict(dict)) => {
|
||||||
iter!(for (v => value) in dict.into_iter().map(|p| p.1))
|
iter!(for (v => value) in dict.into_iter().map(|p| p.1));
|
||||||
}
|
}
|
||||||
(ForPattern::KeyValue(k, v), Value::Dict(dict)) => {
|
(ForPattern::KeyValue(k, v), Value::Dict(dict)) => {
|
||||||
iter!(for (k => key, v => value) in dict.into_iter())
|
iter!(for (k => key, v => value) in dict.into_iter());
|
||||||
}
|
}
|
||||||
|
|
||||||
(ForPattern::KeyValue(_, _), Value::Str(_))
|
(ForPattern::KeyValue(_, _), Value::Str(_))
|
||||||
| (ForPattern::KeyValue(_, _), Value::Array(_)) => {
|
| (ForPattern::KeyValue(_, _), Value::Array(_)) => {
|
||||||
ctx.diag(error!(self.pattern.span(), "mismatched pattern"));
|
ctx.diag(error!(self.pattern.span(), "mismatched pattern"));
|
||||||
Value::Error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(_, Value::Error) => Value::Error,
|
(_, Value::Error) => {}
|
||||||
(_, iter) => {
|
(_, iter) => {
|
||||||
ctx.diag(error!(
|
ctx.diag(error!(
|
||||||
self.iter.span(),
|
self.iter.span(),
|
||||||
"cannot loop over {}",
|
"cannot loop over {}",
|
||||||
iter.type_name(),
|
iter.type_name(),
|
||||||
));
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Value::Error
|
Value::Error
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
ctx.scopes.pop();
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -42,3 +42,10 @@
|
|||||||
// Make sure that we don't complain twice.
|
// Make sure that we don't complain twice.
|
||||||
// Error: 12-19 cannot add integer and string
|
// Error: 12-19 cannot add integer and string
|
||||||
#for v #in 1 + "2" {}
|
#for v #in 1 + "2" {}
|
||||||
|
|
||||||
|
// Error: 14-17 cannot apply '-' to string
|
||||||
|
#let error = -""
|
||||||
|
#let result = #for v #in (1, 2, 3) {
|
||||||
|
#if v < 2 [Ok] #else {error}
|
||||||
|
}
|
||||||
|
#[test result, error]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user