mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Streamline template evaluation
This commit is contained in:
parent
80a9b300d1
commit
62ecd31af2
@ -34,11 +34,8 @@ pub fn eval(
|
|||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
) -> Pass<Module> {
|
) -> Pass<Module> {
|
||||||
let mut ctx = EvalContext::new(loader, cache, path, scope);
|
let mut ctx = EvalContext::new(loader, cache, path, scope);
|
||||||
let map = tree.eval(&mut ctx);
|
let template = tree.eval(&mut ctx);
|
||||||
let module = Module {
|
let module = Module { scope: ctx.scopes.top, template };
|
||||||
scope: ctx.scopes.top,
|
|
||||||
template: vec![TemplateNode::Tree { tree, map }],
|
|
||||||
};
|
|
||||||
Pass::new(module, ctx.diags)
|
Pass::new(module, ctx.diags)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +149,7 @@ impl<'a> EvalContext<'a> {
|
|||||||
|
|
||||||
// Evaluate the module.
|
// Evaluate the module.
|
||||||
let tree = Rc::new(parsed.output);
|
let tree = Rc::new(parsed.output);
|
||||||
let map = tree.eval(self);
|
let template = tree.eval(self);
|
||||||
|
|
||||||
// Restore the old context.
|
// Restore the old context.
|
||||||
let new_scopes = mem::replace(&mut self.scopes, old_scopes);
|
let new_scopes = mem::replace(&mut self.scopes, old_scopes);
|
||||||
@ -167,10 +164,8 @@ impl<'a> EvalContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the evaluated module.
|
// Save the evaluated module.
|
||||||
self.modules.insert(hash, Module {
|
let module = Module { scope: new_scopes.top, template };
|
||||||
scope: new_scopes.top,
|
self.modules.insert(hash, module);
|
||||||
template: vec![TemplateNode::Tree { tree, map }],
|
|
||||||
});
|
|
||||||
|
|
||||||
Some(hash)
|
Some(hash)
|
||||||
}
|
}
|
||||||
@ -217,8 +212,8 @@ pub trait Eval {
|
|||||||
fn eval(&self, ctx: &mut EvalContext) -> Self::Output;
|
fn eval(&self, ctx: &mut EvalContext) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eval for Tree {
|
impl Eval for Rc<Tree> {
|
||||||
type Output = ExprMap;
|
type Output = TemplateValue;
|
||||||
|
|
||||||
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
||||||
struct ExprVisitor<'a, 'b> {
|
struct ExprVisitor<'a, 'b> {
|
||||||
@ -234,7 +229,8 @@ impl Eval for Tree {
|
|||||||
|
|
||||||
let mut visitor = ExprVisitor { ctx, map: ExprMap::new() };
|
let mut visitor = ExprVisitor { ctx, map: ExprMap::new() };
|
||||||
visitor.visit_tree(self);
|
visitor.visit_tree(self);
|
||||||
visitor.map
|
|
||||||
|
vec![TemplateNode::Tree { tree: Rc::clone(self), map: visitor.map }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,11 +259,11 @@ impl Eval for Expr {
|
|||||||
},
|
},
|
||||||
Self::Array(ref v) => Value::Array(v.eval(ctx)),
|
Self::Array(ref v) => Value::Array(v.eval(ctx)),
|
||||||
Self::Dict(ref v) => Value::Dict(v.eval(ctx)),
|
Self::Dict(ref v) => Value::Dict(v.eval(ctx)),
|
||||||
Self::Template(ref v) => Value::Template(vec![v.eval(ctx)]),
|
Self::Template(ref v) => Value::Template(v.eval(ctx)),
|
||||||
Self::Group(ref v) => v.eval(ctx),
|
Self::Group(ref v) => v.eval(ctx),
|
||||||
Self::Block(ref v) => v.eval(ctx),
|
Self::Block(ref v) => v.eval(ctx),
|
||||||
Self::Call(ref v) => v.eval(ctx),
|
Self::Call(ref v) => v.eval(ctx),
|
||||||
Self::Closure(ref v) => v.eval(ctx),
|
Self::Closure(ref v) => Value::Func(v.eval(ctx)),
|
||||||
Self::Unary(ref v) => v.eval(ctx),
|
Self::Unary(ref v) => v.eval(ctx),
|
||||||
Self::Binary(ref v) => v.eval(ctx),
|
Self::Binary(ref v) => v.eval(ctx),
|
||||||
Self::Let(ref v) => v.eval(ctx),
|
Self::Let(ref v) => v.eval(ctx),
|
||||||
@ -300,12 +296,10 @@ impl Eval for DictExpr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Eval for TemplateExpr {
|
impl Eval for TemplateExpr {
|
||||||
type Output = TemplateNode;
|
type Output = TemplateValue;
|
||||||
|
|
||||||
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
||||||
let tree = Rc::clone(&self.tree);
|
self.tree.eval(ctx)
|
||||||
let map = self.tree.eval(ctx);
|
|
||||||
TemplateNode::Tree { tree, map }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +510,7 @@ impl Eval for CallArg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Eval for ClosureExpr {
|
impl Eval for ClosureExpr {
|
||||||
type Output = Value;
|
type Output = FuncValue;
|
||||||
|
|
||||||
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
||||||
let params = Rc::clone(&self.params);
|
let params = Rc::clone(&self.params);
|
||||||
@ -530,7 +524,7 @@ impl Eval for ClosureExpr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let name = self.name.as_ref().map(|id| id.to_string());
|
let name = self.name.as_ref().map(|id| id.to_string());
|
||||||
Value::Func(FuncValue::new(name, move |ctx, args| {
|
FuncValue::new(name, move |ctx, args| {
|
||||||
// Don't leak the scopes from the call site. Instead, we use the
|
// Don't leak the scopes from the call site. Instead, we use the
|
||||||
// scope of captured variables we collected earlier.
|
// scope of captured variables we collected earlier.
|
||||||
let prev = mem::take(&mut ctx.scopes);
|
let prev = mem::take(&mut ctx.scopes);
|
||||||
@ -545,7 +539,7 @@ impl Eval for ClosureExpr {
|
|||||||
let value = body.eval(ctx);
|
let value = body.eval(ctx);
|
||||||
ctx.scopes = prev;
|
ctx.scopes = prev;
|
||||||
value
|
value
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user