mirror of
https://github.com/typst/typst
synced 2025-05-15 01:25:28 +08:00
Propagate error before checking for control flow event
This commit is contained in:
parent
877df549aa
commit
f6a4b8f97b
@ -414,7 +414,7 @@ impl Closure {
|
|||||||
args.finish()?;
|
args.finish()?;
|
||||||
|
|
||||||
// Handle control flow.
|
// Handle control flow.
|
||||||
let result = closure.body().eval(&mut vm);
|
let output = closure.body().eval(&mut vm)?;
|
||||||
match vm.flow {
|
match vm.flow {
|
||||||
Some(FlowEvent::Return(_, Some(explicit))) => return Ok(explicit),
|
Some(FlowEvent::Return(_, Some(explicit))) => return Ok(explicit),
|
||||||
Some(FlowEvent::Return(_, None)) => {}
|
Some(FlowEvent::Return(_, None)) => {}
|
||||||
@ -422,7 +422,7 @@ impl Closure {
|
|||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
Ok(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ pub fn eval(
|
|||||||
|
|
||||||
// Evaluate the module.
|
// Evaluate the module.
|
||||||
let markup = root.cast::<ast::Markup>().unwrap();
|
let markup = root.cast::<ast::Markup>().unwrap();
|
||||||
let result = markup.eval(&mut vm);
|
let output = markup.eval(&mut vm)?;
|
||||||
|
|
||||||
// Handle control flow.
|
// Handle control flow.
|
||||||
if let Some(flow) = vm.flow {
|
if let Some(flow) = vm.flow {
|
||||||
@ -142,7 +142,7 @@ pub fn eval(
|
|||||||
|
|
||||||
// Assemble the module.
|
// Assemble the module.
|
||||||
let name = id.path().file_stem().unwrap_or_default().to_string_lossy();
|
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.
|
/// Evaluate a string as code and return the resulting value.
|
||||||
@ -190,13 +190,13 @@ pub fn eval_string(
|
|||||||
vm.scopes.scopes.push(scope);
|
vm.scopes.scopes.push(scope);
|
||||||
|
|
||||||
// Evaluate the code.
|
// Evaluate the code.
|
||||||
let result = match mode {
|
let output = match mode {
|
||||||
EvalMode::Code => root.cast::<ast::Code>().unwrap().eval(&mut vm),
|
EvalMode::Code => root.cast::<ast::Code>().unwrap().eval(&mut vm)?,
|
||||||
EvalMode::Markup => {
|
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 => {
|
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());
|
bail!(flow.forbidden());
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In which mode to evaluate a string.
|
/// In which mode to evaluate a string.
|
||||||
@ -1306,30 +1306,22 @@ impl Eval for ast::Closure<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Destruct the value into the pattern by binding.
|
/// Destruct the value into the pattern by binding.
|
||||||
fn define_pattern(
|
fn define_pattern(vm: &mut Vm, pattern: ast::Pattern, value: Value) -> SourceResult<()> {
|
||||||
vm: &mut Vm,
|
|
||||||
pattern: ast::Pattern,
|
|
||||||
value: Value,
|
|
||||||
) -> SourceResult<Value> {
|
|
||||||
destructure(vm, pattern, value, |vm, expr, value| match expr {
|
destructure(vm, pattern, value, |vm, expr, value| match expr {
|
||||||
ast::Expr::Ident(ident) => {
|
ast::Expr::Ident(ident) => {
|
||||||
vm.define(ident, value);
|
vm.define(ident, value);
|
||||||
Ok(Value::None)
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => bail!(expr.span(), "nested patterns are currently not supported"),
|
_ => bail!(expr.span(), "nested patterns are currently not supported"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destruct the value into the pattern by assignment.
|
/// Destruct the value into the pattern by assignment.
|
||||||
fn assign_pattern(
|
fn assign_pattern(vm: &mut Vm, pattern: ast::Pattern, value: Value) -> SourceResult<()> {
|
||||||
vm: &mut Vm,
|
|
||||||
pattern: ast::Pattern,
|
|
||||||
value: Value,
|
|
||||||
) -> SourceResult<Value> {
|
|
||||||
destructure(vm, pattern, value, |vm, expr, value| {
|
destructure(vm, pattern, value, |vm, expr, value| {
|
||||||
let location = expr.access(vm)?;
|
let location = expr.access(vm)?;
|
||||||
*location = value;
|
*location = value;
|
||||||
Ok(Value::None)
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1340,22 +1332,22 @@ fn destructure<T>(
|
|||||||
pattern: ast::Pattern,
|
pattern: ast::Pattern,
|
||||||
value: Value,
|
value: Value,
|
||||||
f: T,
|
f: T,
|
||||||
) -> SourceResult<Value>
|
) -> SourceResult<()>
|
||||||
where
|
where
|
||||||
T: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<Value>,
|
T: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<()>,
|
||||||
{
|
{
|
||||||
match pattern {
|
match pattern {
|
||||||
ast::Pattern::Normal(expr) => {
|
ast::Pattern::Normal(expr) => {
|
||||||
f(vm, expr, value)?;
|
f(vm, expr, value)?;
|
||||||
Ok(Value::None)
|
|
||||||
}
|
}
|
||||||
ast::Pattern::Placeholder(_) => Ok(Value::None),
|
ast::Pattern::Placeholder(_) => {}
|
||||||
ast::Pattern::Destructuring(destruct) => match value {
|
ast::Pattern::Destructuring(destruct) => match value {
|
||||||
Value::Array(value) => destructure_array(vm, pattern, value, f, destruct),
|
Value::Array(value) => destructure_array(vm, pattern, value, f, destruct)?,
|
||||||
Value::Dict(value) => destructure_dict(vm, value, f, destruct),
|
Value::Dict(value) => destructure_dict(vm, value, f, destruct)?,
|
||||||
_ => bail!(pattern.span(), "cannot destructure {}", value.type_name()),
|
_ => bail!(pattern.span(), "cannot destructure {}", value.type_name()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destructure_array<F>(
|
fn destructure_array<F>(
|
||||||
@ -1364,9 +1356,9 @@ fn destructure_array<F>(
|
|||||||
value: Array,
|
value: Array,
|
||||||
f: F,
|
f: F,
|
||||||
destruct: ast::Destructuring,
|
destruct: ast::Destructuring,
|
||||||
) -> SourceResult<Value>
|
) -> SourceResult<()>
|
||||||
where
|
where
|
||||||
F: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<Value>,
|
F: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<()>,
|
||||||
{
|
{
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let len = value.as_slice().len();
|
let len = value.as_slice().len();
|
||||||
@ -1407,7 +1399,7 @@ where
|
|||||||
bail!(pattern.span(), "too many elements to destructure");
|
bail!(pattern.span(), "too many elements to destructure");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::None)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destructure_dict<F>(
|
fn destructure_dict<F>(
|
||||||
@ -1415,9 +1407,9 @@ fn destructure_dict<F>(
|
|||||||
dict: Dict,
|
dict: Dict,
|
||||||
f: F,
|
f: F,
|
||||||
destruct: ast::Destructuring,
|
destruct: ast::Destructuring,
|
||||||
) -> SourceResult<Value>
|
) -> SourceResult<()>
|
||||||
where
|
where
|
||||||
F: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<Value>,
|
F: Fn(&mut Vm, ast::Expr, Value) -> SourceResult<()>,
|
||||||
{
|
{
|
||||||
let mut sink = None;
|
let mut sink = None;
|
||||||
let mut used = HashSet::new();
|
let mut used = HashSet::new();
|
||||||
@ -1458,7 +1450,7 @@ where
|
|||||||
f(vm, expr, Value::Dict(sink))?;
|
f(vm, expr, Value::Dict(sink))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::None)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eval for ast::LetBinding<'_> {
|
impl Eval for ast::LetBinding<'_> {
|
||||||
@ -1475,12 +1467,13 @@ impl Eval for ast::LetBinding<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self.kind() {
|
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) => {
|
ast::LetBindingKind::Closure(ident) => {
|
||||||
vm.define(ident, value);
|
vm.define(ident, value);
|
||||||
Ok(Value::None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(Value::None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user