summaryrefslogtreecommitdiff
path: root/src/eval/function.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-08-12 13:39:33 +0200
committerLaurenz <laurmaedje@gmail.com>2021-08-12 13:56:23 +0200
commiteaa3cbaa9c2b1564a4b0db013672245a1893314a (patch)
tree616a3d0f3686793caffcef72f230f8ba79b8f3ca /src/eval/function.rs
parent8207c31aec6336b773fbf4661fdb87625c8b584e (diff)
Array and dictionary indexing
Diffstat (limited to 'src/eval/function.rs')
-rw-r--r--src/eval/function.rs39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/eval/function.rs b/src/eval/function.rs
index 8b1e883f..be7894f4 100644
--- a/src/eval/function.rs
+++ b/src/eval/function.rs
@@ -134,7 +134,7 @@ impl FuncArgs {
let value = self.items.remove(index).value;
let span = value.span;
- T::cast(value).map(Some).map_err(Error::partial(self.source, span))
+ T::cast(value).map(Some).map_err(Error::at(self.source, span))
}
/// Return an "unexpected argument" error if there is any remaining
@@ -146,3 +146,40 @@ impl FuncArgs {
Ok(())
}
}
+
+impl FuncArgs {
+ /// Reinterpret these arguments as actually being an array index.
+ pub fn into_index(self) -> TypResult<i64> {
+ self.into_castable("index")
+ }
+
+ /// Reinterpret these arguments as actually being a dictionary key.
+ pub fn into_key(self) -> TypResult<EcoString> {
+ self.into_castable("key")
+ }
+
+ /// Reinterpret these arguments as actually being a single castable thing.
+ fn into_castable<T>(self, what: &str) -> TypResult<T>
+ where
+ T: Cast<Value>,
+ {
+ let mut iter = self.items.into_iter();
+ let value = match iter.next() {
+ None => {
+ bail!(self.source, self.span, "missing {}", what);
+ }
+ Some(FuncArg { name: Some(_), span, .. }) => {
+ bail!(self.source, span, "named pair is not allowed here");
+ }
+ Some(FuncArg { name: None, value, .. }) => {
+ value.v.cast().map_err(Error::at(self.source, value.span))?
+ }
+ };
+
+ if let Some(arg) = iter.next() {
+ bail!(self.source, arg.span, "only one {} is allowed", what);
+ }
+
+ Ok(value)
+ }
+}