summaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval')
-rw-r--r--src/eval/function.rs42
-rw-r--r--src/eval/mod.rs1
-rw-r--r--src/eval/ops.rs8
3 files changed, 26 insertions, 25 deletions
diff --git a/src/eval/function.rs b/src/eval/function.rs
index d9f79adf..cbbc0b36 100644
--- a/src/eval/function.rs
+++ b/src/eval/function.rs
@@ -77,25 +77,22 @@ pub struct Arg {
}
impl Args {
- /// Find and consume the first castable positional argument.
- pub fn eat<T>(&mut self) -> Option<T>
+ /// Consume and cast the first positional argument.
+ ///
+ /// Returns a `missing argument: {what}` error if no positional argument is
+ /// left.
+ pub fn expect<T>(&mut self, what: &str) -> TypResult<T>
where
T: Cast<Spanned<Value>>,
{
- for (i, slot) in self.items.iter().enumerate() {
- if slot.name.is_none() {
- if T::is(&slot.value) {
- let value = self.items.remove(i).value;
- return T::cast(value).ok();
- }
- }
+ match self.eat()? {
+ Some(v) => Ok(v),
+ None => bail!(self.span, "missing argument: {}", what),
}
- None
}
- /// Try to cast the first positional argument ir returning a `missing
- /// argument: {what}` error if no positional argument is left.
- pub fn expect<T>(&mut self, what: &str) -> TypResult<T>
+ /// Consume and cast the first positional argument if there is one.
+ pub fn eat<T>(&mut self) -> TypResult<Option<T>>
where
T: Cast<Spanned<Value>>,
{
@@ -103,11 +100,24 @@ impl Args {
if slot.name.is_none() {
let value = self.items.remove(i).value;
let span = value.span;
- return T::cast(value).at(span);
+ return T::cast(value).at(span).map(Some);
}
}
+ Ok(None)
+ }
- bail!(self.span, "missing argument: {}", what);
+ /// Find and consume the first castable positional argument.
+ pub fn find<T>(&mut self) -> Option<T>
+ where
+ T: Cast<Spanned<Value>>,
+ {
+ for (i, slot) in self.items.iter().enumerate() {
+ if slot.name.is_none() && T::is(&slot.value) {
+ let value = self.items.remove(i).value;
+ return T::cast(value).ok();
+ }
+ }
+ None
}
/// Find and consume all castable positional arguments.
@@ -115,7 +125,7 @@ impl Args {
where
T: Cast<Spanned<Value>>,
{
- std::iter::from_fn(move || self.eat())
+ std::iter::from_fn(move || self.find())
}
/// Cast and remove the value for the given named argument, returning an
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index 2adf785e..691e3c49 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -317,7 +317,6 @@ impl Eval for BinaryExpr {
BinOp::SubAssign => self.assign(ctx, ops::sub),
BinOp::MulAssign => self.assign(ctx, ops::mul),
BinOp::DivAssign => self.assign(ctx, ops::div),
- BinOp::Range => self.apply(ctx, ops::range),
}
}
}
diff --git a/src/eval/ops.rs b/src/eval/ops.rs
index 8756e8c6..732bfb14 100644
--- a/src/eval/ops.rs
+++ b/src/eval/ops.rs
@@ -244,14 +244,6 @@ comparison!(leq, "<=", Ordering::Less | Ordering::Equal);
comparison!(gt, ">", Ordering::Greater);
comparison!(geq, ">=", Ordering::Greater | Ordering::Equal);
-/// Compute the range from `lhs` to `rhs`.
-pub fn range(lhs: Value, rhs: Value) -> StrResult<Value> {
- match (lhs, rhs) {
- (Int(a), Int(b)) => Ok(Array((a .. b).map(Int).collect())),
- (a, b) => mismatch!("cannot apply '..' to {} and {}", a, b),
- }
-}
-
/// Determine whether two values are equal.
pub fn equal(lhs: &Value, rhs: &Value) -> bool {
match (lhs, rhs) {