From ebfdb1dafa430786db10dad2ef7d5467c1bdbed1 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 2 Jul 2023 19:59:52 +0200 Subject: Move everything into `crates/` directory --- src/eval/args.rs | 216 ------------------------------------------------------- 1 file changed, 216 deletions(-) delete mode 100644 src/eval/args.rs (limited to 'src/eval/args.rs') diff --git a/src/eval/args.rs b/src/eval/args.rs deleted file mode 100644 index da29eeaf..00000000 --- a/src/eval/args.rs +++ /dev/null @@ -1,216 +0,0 @@ -use std::fmt::{self, Debug, Formatter}; - -use ecow::{eco_format, EcoVec}; - -use super::{Array, Dict, FromValue, IntoValue, Str, Value}; -use crate::diag::{bail, At, SourceResult}; -use crate::syntax::{Span, Spanned}; -use crate::util::pretty_array_like; - -/// Evaluated arguments to a function. -#[derive(Clone, PartialEq, Hash)] -pub struct Args { - /// The span of the whole argument list. - pub span: Span, - /// The positional and named arguments. - pub items: EcoVec, -} - -/// An argument to a function call: `12` or `draw: false`. -#[derive(Clone, PartialEq, Hash)] -pub struct Arg { - /// The span of the whole argument. - pub span: Span, - /// The name of the argument (`None` for positional arguments). - pub name: Option, - /// The value of the argument. - pub value: Spanned, -} - -impl Args { - /// Create positional arguments from a span and values. - pub fn new(span: Span, values: impl IntoIterator) -> Self { - let items = values - .into_iter() - .map(|value| Arg { - span, - name: None, - value: Spanned::new(value.into_value(), span), - }) - .collect(); - 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(&mut self) -> SourceResult> - where - T: FromValue>, - { - for (i, slot) in self.items.iter().enumerate() { - if slot.name.is_none() { - let value = self.items.remove(i).value; - let span = value.span; - return T::from_value(value).at(span).map(Some); - } - } - Ok(None) - } - - /// Consume n positional arguments if possible. - pub fn consume(&mut self, n: usize) -> SourceResult> { - let mut list = vec![]; - - let mut i = 0; - while i < self.items.len() && list.len() < n { - if self.items[i].name.is_none() { - list.push(self.items.remove(i)); - } else { - i += 1; - } - } - - if list.len() < n { - bail!(self.span, "not enough arguments"); - } - - Ok(list) - } - - /// Consume and cast the first positional argument. - /// - /// Returns a `missing argument: {what}` error if no positional argument is - /// left. - pub fn expect(&mut self, what: &str) -> SourceResult - where - T: FromValue>, - { - match self.eat()? { - Some(v) => Ok(v), - None => bail!(self.span, "missing argument: {what}"), - } - } - - /// Find and consume the first castable positional argument. - pub fn find(&mut self) -> SourceResult> - where - T: FromValue>, - { - for (i, slot) in self.items.iter().enumerate() { - if slot.name.is_none() && T::castable(&slot.value.v) { - let value = self.items.remove(i).value; - let span = value.span; - return T::from_value(value).at(span).map(Some); - } - } - Ok(None) - } - - /// Find and consume all castable positional arguments. - pub fn all(&mut self) -> SourceResult> - where - T: FromValue>, - { - let mut list = vec![]; - while let Some(value) = self.find()? { - list.push(value); - } - Ok(list) - } - - /// Cast and remove the value for the given named argument, returning an - /// error if the conversion fails. - pub fn named(&mut self, name: &str) -> SourceResult> - where - T: FromValue>, - { - // We don't quit once we have a match because when multiple matches - // exist, we want to remove all of them and use the last one. - let mut i = 0; - let mut found = None; - while i < self.items.len() { - if self.items[i].name.as_deref() == Some(name) { - let value = self.items.remove(i).value; - let span = value.span; - found = Some(T::from_value(value).at(span)?); - } else { - i += 1; - } - } - Ok(found) - } - - /// Same as named, but with fallback to find. - pub fn named_or_find(&mut self, name: &str) -> SourceResult> - where - T: FromValue>, - { - match self.named(name)? { - Some(value) => Ok(Some(value)), - None => self.find(), - } - } - - /// Take out all arguments into a new instance. - pub fn take(&mut self) -> Self { - Self { - span: self.span, - items: std::mem::take(&mut self.items), - } - } - - /// Return an "unexpected argument" error if there is any remaining - /// argument. - pub fn finish(self) -> SourceResult<()> { - if let Some(arg) = self.items.first() { - match &arg.name { - Some(name) => bail!(arg.span, "unexpected argument: {name}"), - _ => bail!(arg.span, "unexpected argument"), - } - } - Ok(()) - } - - /// Extract the positional arguments as an array. - pub fn to_pos(&self) -> Array { - self.items - .iter() - .filter(|item| item.name.is_none()) - .map(|item| item.value.v.clone()) - .collect() - } - - /// Extract the named arguments as a dictionary. - pub fn to_named(&self) -> Dict { - self.items - .iter() - .filter_map(|item| item.name.clone().map(|name| (name, item.value.v.clone()))) - .collect() - } -} - -impl Debug for Args { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - let pieces: Vec<_> = - self.items.iter().map(|arg| eco_format!("{arg:?}")).collect(); - f.write_str(&pretty_array_like(&pieces, false)) - } -} - -impl Debug for Arg { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - if let Some(name) = &self.name { - f.write_str(name)?; - f.write_str(": ")?; - } - Debug::fmt(&self.value.v, f) - } -} -- cgit v1.2.3