Enable for loop over captured args
This commit is contained in:
parent
3cad6bf607
commit
24d513d891
@ -642,16 +642,8 @@ impl Eval for CallArgs {
|
||||
value: Spanned::new(value, span),
|
||||
}));
|
||||
}
|
||||
v => {
|
||||
if let Value::Dyn(dynamic) = &v {
|
||||
if let Some(args) = dynamic.downcast::<Args>() {
|
||||
items.extend(args.items.iter().cloned());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bail!(expr.span(), "cannot spread {}", v.type_name())
|
||||
}
|
||||
Value::Args(args) => items.extend(args.items),
|
||||
v => bail!(expr.span(), "cannot spread {}", v.type_name()),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -716,10 +708,6 @@ impl Eval for ClosureExpr {
|
||||
|
||||
// Put the remaining arguments into the sink.
|
||||
if let Some(sink) = &sink {
|
||||
dynamic! {
|
||||
Args: "arguments",
|
||||
}
|
||||
|
||||
ctx.scopes.def_mut(sink, args.take());
|
||||
}
|
||||
|
||||
@ -868,6 +856,15 @@ impl Eval for ForExpr {
|
||||
(Some(k), v, Value::Dict(dict)) => {
|
||||
iter!(for (k => key, v => value) in dict.into_iter());
|
||||
}
|
||||
(None, v, Value::Args(args)) => {
|
||||
iter!(for (v => value) in args.items.into_iter()
|
||||
.filter(|arg| arg.name.is_none())
|
||||
.map(|arg| arg.value.v));
|
||||
}
|
||||
(Some(k), v, Value::Args(args)) => {
|
||||
iter!(for (k => key, v => value) in args.items.into_iter()
|
||||
.map(|arg| (arg.name.map_or(Value::None, Value::Str), arg.value.v)));
|
||||
}
|
||||
(_, _, Value::Str(_)) => {
|
||||
bail!(pattern.span(), "mismatched pattern");
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Formatter};
|
||||
use std::hash::Hash;
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::{ops, Array, Class, Dict, Function, Node};
|
||||
use super::{ops, Args, Array, Class, Dict, Function, Node};
|
||||
use crate::diag::StrResult;
|
||||
use crate::geom::{Angle, Color, Fractional, Length, Linear, Relative, RgbaColor};
|
||||
use crate::layout::Layout;
|
||||
@ -46,6 +46,8 @@ pub enum Value {
|
||||
Node(Node),
|
||||
/// An executable function.
|
||||
Func(Function),
|
||||
/// Captured arguments to a function.
|
||||
Args(Args),
|
||||
/// A class of nodes.
|
||||
Class(Class),
|
||||
/// A dynamic value.
|
||||
@ -88,6 +90,7 @@ impl Value {
|
||||
Self::Dict(_) => Dict::TYPE_NAME,
|
||||
Self::Node(_) => Node::TYPE_NAME,
|
||||
Self::Func(_) => Function::TYPE_NAME,
|
||||
Self::Args(_) => Args::TYPE_NAME,
|
||||
Self::Class(_) => Class::TYPE_NAME,
|
||||
Self::Dyn(v) => v.type_name(),
|
||||
}
|
||||
@ -151,6 +154,7 @@ impl Debug for Value {
|
||||
Self::Dict(v) => Debug::fmt(v, f),
|
||||
Self::Node(_) => f.pad("<template>"),
|
||||
Self::Func(v) => Debug::fmt(v, f),
|
||||
Self::Args(v) => Debug::fmt(v, f),
|
||||
Self::Class(v) => Debug::fmt(v, f),
|
||||
Self::Dyn(v) => Debug::fmt(v, f),
|
||||
}
|
||||
@ -219,12 +223,12 @@ impl Dynamic {
|
||||
}
|
||||
|
||||
/// Whether the wrapped type is `T`.
|
||||
pub fn is<T: 'static>(&self) -> bool {
|
||||
pub fn is<T: Type + 'static>(&self) -> bool {
|
||||
self.0.as_any().is::<T>()
|
||||
}
|
||||
|
||||
/// Try to downcast to a reference to a specific type.
|
||||
pub fn downcast<T: 'static>(&self) -> Option<&T> {
|
||||
pub fn downcast<T: Type + 'static>(&self) -> Option<&T> {
|
||||
self.0.as_any().downcast_ref()
|
||||
}
|
||||
|
||||
@ -404,6 +408,7 @@ primitive! { Function: "function",
|
||||
move |ctx, args| v.construct(ctx, args).map(Value::Node)
|
||||
)
|
||||
}
|
||||
primitive! { Args: "arguments", Args }
|
||||
primitive! { Class: "class", Class }
|
||||
|
||||
impl Cast<Value> for Value {
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.9 KiB |
@ -32,6 +32,12 @@
|
||||
// Should output `2345`.
|
||||
#for v in (1, 2, 3, 4, 5, 6, 7) [#if v >= 2 and v <= 5 { repr(v) }]
|
||||
|
||||
// Loop over captured arguments.
|
||||
#let f1(..args) = for v in args { (repr(v),) }
|
||||
#let f2(..args) = for k, v in args { (repr(k) + ": " + repr(v),) }
|
||||
#let f(..args) = join(sep: ", ", ..f1(..args), ..f2(..args))
|
||||
#f(1, a: 2)
|
||||
|
||||
---
|
||||
#let out = ()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user