diff options
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/args.rs | 9 | ||||
| -rw-r--r-- | src/eval/methods.rs | 26 | ||||
| -rw-r--r-- | src/eval/ops.rs | 10 | ||||
| -rw-r--r-- | src/eval/value.rs | 14 |
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", |
