Support scope argument for eval

This commit is contained in:
Laurenz 2023-07-18 21:53:42 +02:00
parent f52c39c388
commit 803ae9309f
5 changed files with 45 additions and 5 deletions

View File

@ -218,9 +218,30 @@ pub fn eval(
#[named]
#[default(EvalMode::Code)]
mode: EvalMode,
/// A scope of definitions that are made available.
///
/// ```example
/// #eval("x + 1", scope: (x: 2)) \
/// #eval(
/// "abc/xyz",
/// mode: "math",
/// scope: (
/// abc: $a + b + c$,
/// xyz: $x + y + z$,
/// ),
/// )
/// ```
#[named]
#[default]
scope: Dict,
/// The virtual machine.
vm: &mut Vm,
) -> SourceResult<Value> {
let Spanned { v: text, span } = source;
typst::eval::eval_string(vm.world(), &text, mode, span)
let dict = scope;
let mut scope = Scope::new();
for (key, value) in dict {
scope.define(key, value);
}
typst::eval::eval_string(vm.world(), &text, span, mode, scope)
}

View File

@ -145,8 +145,9 @@ pub fn eval(
pub fn eval_string(
world: Tracked<dyn World + '_>,
string: &str,
mode: EvalMode,
span: Span,
mode: EvalMode,
scope: Scope,
) -> SourceResult<Value> {
let mut root = match mode {
EvalMode::Code => parse_code(string),
@ -179,6 +180,7 @@ pub fn eval_string(
let id = FileId::detached();
let scopes = Scopes::new(Some(world.library()));
let mut vm = Vm::new(vt, route.track(), id, scopes);
vm.scopes.scopes.push(scope);
// Evaluate the code.
let result = match mode {

View File

@ -72,7 +72,11 @@ impl<'a> Scopes<'a> {
#[cold]
fn unknown_variable(var: &str) -> EcoString {
if var.contains('-') {
eco_format!("unknown variable: {} - if you meant to use subtraction, try adding spaces around the minus sign.", var)
eco_format!(
"unknown variable: {} - if you meant to use subtraction, \
try adding spaces around the minus sign.",
var
)
} else {
eco_format!("unknown variable: {}", var)
}
@ -171,7 +175,10 @@ impl Slot {
match self.kind {
Kind::Normal => Ok(&mut self.value),
Kind::Captured => {
bail!("variables from outside the function are read-only and cannot be modified")
bail!(
"variables from outside the function are \
read-only and cannot be modified"
)
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -73,7 +73,17 @@
#test(type(10 / 3), "float")
---
#eval("[_Hello" + " World!_]")
// Test the eval function.
#test(eval("1 + 2"), 3)
#test(eval("1 + x", scope: (x: 3)), 4)
#test(eval("let x = x + 1; x + 1", scope: (x: 1)), 3)
---
// Test evaluation in other modes.
// Ref: true
#eval("[_Hello" + " World!_]") \
#eval("_Hello" + " World!_", mode: "markup") \
#eval("RR_1^NN", mode: "math", scope: (RR: math.NN, NN: math.RR))
---
// Error: 7-12 expected identifier