summaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval')
-rw-r--r--src/eval/args.rs9
-rw-r--r--src/eval/methods.rs26
-rw-r--r--src/eval/ops.rs10
-rw-r--r--src/eval/value.rs14
4 files changed, 43 insertions, 16 deletions
diff --git a/src/eval/args.rs b/src/eval/args.rs
index 69e6aaee..4d280ff7 100644
--- a/src/eval/args.rs
+++ b/src/eval/args.rs
@@ -39,6 +39,15 @@ impl Args {
Self { span, items }
}
+ /// Push a positional argument.
+ pub fn push(&mut self, span: Span, value: Value) {
+ self.items.push(Arg {
+ span: self.span,
+ name: None,
+ value: Spanned::new(value, span),
+ })
+ }
+
/// Consume and cast the first positional argument if there is one.
pub fn eat<T>(&mut self) -> TypResult<Option<T>>
where
diff --git a/src/eval/methods.rs b/src/eval/methods.rs
index f6de614f..6ccd98e6 100644
--- a/src/eval/methods.rs
+++ b/src/eval/methods.rs
@@ -2,6 +2,7 @@
use super::{Args, Machine, Regex, StrExt, Value};
use crate::diag::{At, TypResult};
+use crate::model::{Content, Group};
use crate::syntax::Span;
use crate::util::EcoString;
@@ -66,18 +67,23 @@ pub fn call(
_ => missing()?,
},
- Value::Dyn(dynamic) => {
- if let Some(regex) = dynamic.downcast::<Regex>() {
- match method {
- "matches" => {
- Value::Bool(regex.matches(&args.expect::<EcoString>("text")?))
- }
- _ => missing()?,
+ Value::Dyn(dynamic) => match method {
+ "matches" => {
+ if let Some(regex) = dynamic.downcast::<Regex>() {
+ Value::Bool(regex.matches(&args.expect::<EcoString>("text")?))
+ } else {
+ missing()?
}
- } else {
- missing()?
}
- }
+ "entry" => {
+ if let Some(group) = dynamic.downcast::<Group>() {
+ Value::Content(Content::Locate(group.entry(args.expect("recipe")?)))
+ } else {
+ missing()?
+ }
+ }
+ _ => missing()?,
+ },
_ => missing()?,
};
diff --git a/src/eval/ops.rs b/src/eval/ops.rs
index b3f2f3b4..f88f3cee 100644
--- a/src/eval/ops.rs
+++ b/src/eval/ops.rs
@@ -2,7 +2,7 @@
use std::cmp::Ordering;
-use super::{Dynamic, RawAlign, RawLength, RawStroke, Smart, StrExt, Value};
+use super::{RawAlign, RawLength, RawStroke, Smart, StrExt, Value};
use crate::diag::StrResult;
use crate::geom::{Numeric, Relative, Spec, SpecAxis};
use crate::model;
@@ -94,10 +94,10 @@ pub fn add(lhs: Value, rhs: Value) -> StrResult<Value> {
(Dict(a), Dict(b)) => Dict(a + b),
(Color(color), Length(thickness)) | (Length(thickness), Color(color)) => {
- Dyn(Dynamic::new(RawStroke {
+ Value::dynamic(RawStroke {
paint: Smart::Custom(color.into()),
thickness: Smart::Custom(thickness),
- }))
+ })
}
(Dyn(a), Dyn(b)) => {
@@ -106,10 +106,10 @@ pub fn add(lhs: Value, rhs: Value) -> StrResult<Value> {
(a.downcast::<RawAlign>(), b.downcast::<RawAlign>())
{
if a.axis() != b.axis() {
- Dyn(Dynamic::new(match a.axis() {
+ Value::dynamic(match a.axis() {
SpecAxis::Horizontal => Spec { x: a, y: b },
SpecAxis::Vertical => Spec { x: b, y: a },
- }))
+ })
} else {
return Err(format!("cannot add two {:?} alignments", a.axis()));
}
diff --git a/src/eval/value.rs b/src/eval/value.rs
index b47d1e91..9b36812a 100644
--- a/src/eval/value.rs
+++ b/src/eval/value.rs
@@ -11,7 +11,7 @@ use crate::geom::{
Angle, Color, Dir, Em, Fraction, Length, Paint, Ratio, Relative, RgbaColor, Sides,
};
use crate::library::text::RawNode;
-use crate::model::{Content, Layout, LayoutNode, Pattern};
+use crate::model::{Content, Group, Layout, LayoutNode, Pattern};
use crate::syntax::Spanned;
use crate::util::EcoString;
@@ -73,6 +73,14 @@ impl Value {
Self::Content(Content::block(node))
}
+ /// Create a new dynamic value.
+ pub fn dynamic<T>(any: T) -> Self
+ where
+ T: Type + Debug + PartialEq + Hash + Sync + Send + 'static,
+ {
+ Self::Dyn(Dynamic::new(any))
+ }
+
/// The name of the stored value's type.
pub fn type_name(&self) -> &'static str {
match self {
@@ -653,6 +661,10 @@ dynamic! {
Regex: "regular expression",
}
+dynamic! {
+ Group: "group",
+}
+
castable! {
usize,
Expected: "non-negative integer",