Propagate error before checking for control flow event

This commit is contained in:
Laurenz 2023-08-21 16:22:17 +02:00
parent 877df549aa
commit f6a4b8f97b
2 changed files with 28 additions and 35 deletions

View File

@ -414,7 +414,7 @@ impl Closure {
args.finish()?;
// Handle control flow.
let result = closure.body().eval(&mut vm);
let output = closure.body().eval(&mut vm)?;
match vm.flow {
Some(FlowEvent::Return(_, Some(explicit))) => return Ok(explicit),
Some(FlowEvent::Return(_, None)) => {}
@ -422,7 +422,7 @@ impl Closure {
None => {}
}
result
Ok(output)
}
}

View File

@ -133,7 +133,7 @@ pub fn eval(
// Evaluate the module.
let markup = root.cast::<ast::Markup>().unwrap();
let result = markup.eval(&mut vm);
let output = markup.eval(&mut vm)?;
// Handle control flow.
if let Some(flow) = vm.flow {
@ -142,7 +142,7 @@ pub fn eval(
// Assemble the module.
let name = id.path().file_stem().unwrap_or_default().to_string_lossy();
Ok(Module::new(name).with_scope(vm.scopes.top).with_content(result?))
Ok(Module::new(name).with_scope(vm.scopes.top).with_content(output))
}
/// Evaluate a string as code and return the resulting value.
@ -190,13 +190,13 @@ pub fn eval_string(
vm.scopes.scopes.push(scope);
// Evaluate the code.
let result = match mode {
EvalMode::Code => root.cast::<ast::Code>().unwrap().eval(&mut vm),
let output = match mode {
EvalMode::Code => root.cast::<ast::Code>().unwrap().eval(&mut vm)?,
EvalMode::Markup => {
root.cast::<ast::Markup>().unwrap().eval(&mut vm).map(Value::Content)
Value::Content(root.cast::<ast::Markup>().unwrap().eval(&mut vm)?)
}
EvalMode::Math => {
root.cast::<ast::Math>().unwrap().eval(&mut vm).map(Value::Content)
Value::Content(root.cast::<ast::Math>().unwrap().eval(&mut vm)?)
}
};
@ -205,7 +205,7 @@ pub fn eval_string(
bail!(flow.forbidden());
}
result
Ok(output)
}
/// In which mode to evaluate a string.
@ -1306,30 +1306,22 @@ impl Eval for ast::Closure<'_> {
}
/// Destruct the value into the pattern by binding.
fn define_pattern(
vm: &mut Vm,
pattern: ast::Pattern,
value: Value,
) -> SourceResult<Value> {
fn define_pattern(vm: &mut Vm, pattern: ast::Pattern, value: Value) -> SourceResult<()> {
destructure(vm, pattern, value, |vm, expr, value| match expr {
ast::Expr::Ident(ident) => {
vm.define(ident, value);
Ok(Value::None)
Ok(())
}
_ => bail!(expr.span(), "nested patterns are currently not supported"),
})
}
/// Destruct the value into the pattern by assignment.
fn assign_pattern(
vm: &mut Vm,
pattern: ast::Pattern,
value: Value,
) -> SourceResult<Value> {
fn assign_pattern(vm: &mut Vm, pattern: ast::Pattern, value: Value) -> SourceResult<()> {
destructure(vm, pattern, value, |vm, expr, value| {
let location = expr.access(vm)?;
*location = value;
Ok(Value::None)
Ok(())
})
}
@ -1340,22 +1332,22 @@ fn destructure<T>(
pattern: ast::Pattern,
value: Value,
f: T,
) -> SourceResult<Value>
) -> SourceResult<()>
where
T: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<Value>,
T: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<()>,
{
match pattern {
ast::Pattern::Normal(expr) => {
f(vm, expr, value)?;
Ok(Value::None)
}
ast::Pattern::Placeholder(_) => Ok(Value::None),
ast::Pattern::Placeholder(_) => {}
ast::Pattern::Destructuring(destruct) => match value {
Value::Array(value) => destructure_array(vm, pattern, value, f, destruct),
Value::Dict(value) => destructure_dict(vm, value, f, destruct),
Value::Array(value) => destructure_array(vm, pattern, value, f, destruct)?,
Value::Dict(value) => destructure_dict(vm, value, f, destruct)?,
_ => bail!(pattern.span(), "cannot destructure {}", value.type_name()),
},
}
Ok(())
}
fn destructure_array<F>(
@ -1364,9 +1356,9 @@ fn destructure_array<F>(
value: Array,
f: F,
destruct: ast::Destructuring,
) -> SourceResult<Value>
) -> SourceResult<()>
where
F: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<Value>,
F: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<()>,
{
let mut i = 0;
let len = value.as_slice().len();
@ -1407,7 +1399,7 @@ where
bail!(pattern.span(), "too many elements to destructure");
}
Ok(Value::None)
Ok(())
}
fn destructure_dict<F>(
@ -1415,9 +1407,9 @@ fn destructure_dict<F>(
dict: Dict,
f: F,
destruct: ast::Destructuring,
) -> SourceResult<Value>
) -> SourceResult<()>
where
F: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<Value>,
F: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<()>,
{
let mut sink = None;
let mut used = HashSet::new();
@ -1458,7 +1450,7 @@ where
f(vm, expr, Value::Dict(sink))?;
}
Ok(Value::None)
Ok(())
}
impl Eval for ast::LetBinding<'_> {
@ -1475,12 +1467,13 @@ impl Eval for ast::LetBinding<'_> {
}
match self.kind() {
ast::LetBindingKind::Normal(pattern) => define_pattern(vm, pattern, value),
ast::LetBindingKind::Normal(pattern) => define_pattern(vm, pattern, value)?,
ast::LetBindingKind::Closure(ident) => {
vm.define(ident, value);
Ok(Value::None)
}
}
Ok(Value::None)
}
}