r/interpreter/builtins/
args.rs1use crate::interpreter::environment::Environment;
4use crate::interpreter::value::{RError, RErrorKind, RValue};
5
6pub(crate) struct CallArgs<'a> {
7 positional: &'a [RValue],
8 named: &'a [(String, RValue)],
9}
10
11impl<'a> CallArgs<'a> {
12 pub(crate) fn new(positional: &'a [RValue], named: &'a [(String, RValue)]) -> Self {
13 Self { positional, named }
14 }
15
16 pub(crate) fn positional(&self, index: usize) -> Option<&'a RValue> {
17 self.positional.get(index)
18 }
19
20 pub(crate) fn named(&self, name: &str) -> Option<&'a RValue> {
21 self.named
22 .iter()
23 .find(|(candidate, _)| candidate == name)
24 .map(|(_, value)| value)
25 }
26
27 pub(crate) fn value(&self, name: &str, position: usize) -> Option<&'a RValue> {
28 self.named(name).or_else(|| self.positional(position))
29 }
30
31 pub(crate) fn string(&self, name: &str, position: usize) -> Result<String, RError> {
32 self.value(name, position)
33 .and_then(|value| value.as_vector()?.as_character_scalar())
34 .ok_or_else(|| RError::new(RErrorKind::Argument, format!("invalid '{name}' argument")))
35 }
36
37 pub(crate) fn optional_string(&self, name: &str, position: usize) -> Option<String> {
38 self.value(name, position)
39 .and_then(|value| value.as_vector()?.as_character_scalar())
40 }
41
42 pub(crate) fn named_string(&self, name: &str) -> Option<String> {
43 self.named(name)
44 .and_then(|value| value.as_vector()?.as_character_scalar())
45 }
46
47 pub(crate) fn logical_flag(&self, name: &str, position: usize, default: bool) -> bool {
48 self.value(name, position)
49 .and_then(|value| value.as_vector()?.as_logical_scalar())
50 .unwrap_or(default)
51 }
52
53 pub(crate) fn integer_or(&self, name: &str, position: usize, default: i64) -> i64 {
54 self.value(name, position)
55 .and_then(|value| value.as_vector()?.as_integer_scalar())
56 .unwrap_or(default)
57 }
58
59 pub(crate) fn environment_or(
60 &self,
61 name: &str,
62 position: usize,
63 default: &Environment,
64 ) -> Result<Environment, RError> {
65 match self.value(name, position) {
66 Some(RValue::Environment(env)) => Ok(env.clone()),
67 Some(_) => Err(RError::new(
68 RErrorKind::Argument,
69 format!("invalid '{name}' argument"),
70 )),
71 None => Ok(default.clone()),
72 }
73 }
74}