1use crate::interpreter::environment::Environment;
4use crate::interpreter::value::*;
5use crate::interpreter::Interpreter;
6use crate::parser::ast::Expr;
7
8impl Interpreter {
9 pub(super) fn eval_pipe(
10 &self,
11 lhs: &Expr,
12 rhs: &Expr,
13 env: &Environment,
14 ) -> Result<RValue, RFlow> {
15 let left_val = self.eval_in(lhs, env)?;
16 match rhs {
17 Expr::Call { func, args, .. } => {
18 let f = self.eval_in(func, env)?;
19
20 let is_placeholder = |s: &str| s == "_" || s == ".";
23 let has_placeholder = args.iter().any(|arg| {
24 matches!(
25 &arg.value,
26 Some(Expr::Symbol(s)) if is_placeholder(s)
27 )
28 });
29
30 let mut eval_args = Vec::new();
31 let mut named_args = Vec::new();
32
33 if has_placeholder {
34 for arg in args {
36 if let Some(name) = &arg.name {
37 if let Some(val_expr) = &arg.value {
38 let val = if matches!(val_expr, Expr::Symbol(s) if is_placeholder(s))
39 {
40 left_val.clone()
41 } else {
42 self.eval_in(val_expr, env)?
43 };
44 named_args.push((name.clone(), val));
45 }
46 } else if let Some(val_expr) = &arg.value {
47 let val = if matches!(val_expr, Expr::Symbol(s) if is_placeholder(s)) {
48 left_val.clone()
49 } else {
50 self.eval_in(val_expr, env)?
51 };
52 eval_args.push(val);
53 }
54 }
55 } else {
56 eval_args.push(left_val);
58 for arg in args {
59 if let Some(name) = &arg.name {
60 if let Some(val_expr) = &arg.value {
61 named_args.push((name.clone(), self.eval_in(val_expr, env)?));
62 }
63 } else if let Some(val_expr) = &arg.value {
64 eval_args.push(self.eval_in(val_expr, env)?);
65 }
66 }
67 }
68
69 self.call_function(&f, &eval_args, &named_args, env)
70 }
71 Expr::Symbol(name) => {
72 let f = env
73 .get(name)
74 .ok_or_else(|| RError::new(RErrorKind::Name, name.clone()))?;
75 self.call_function(&f, &[left_val], &[], env)
76 }
77 _ => Err(RError::other("invalid use of pipe".to_string()).into()),
78 }
79 }
80
81 pub(super) fn eval_if(
82 &self,
83 condition: &Expr,
84 then_body: &Expr,
85 else_body: Option<&Expr>,
86 env: &Environment,
87 ) -> Result<RValue, RFlow> {
88 let cond = self.eval_in(condition, env)?;
89 let test = match &cond {
90 RValue::Vector(v) => v.as_logical_scalar(),
91 _ => None,
92 };
93 match test {
94 Some(true) => self.eval_in(then_body, env),
95 Some(false) | None => {
96 if let Some(else_expr) = else_body {
97 self.eval_in(else_expr, env)
98 } else {
99 Ok(RValue::Null)
100 }
101 }
102 }
103 }
104
105 pub(super) fn eval_while(
106 &self,
107 condition: &Expr,
108 body: &Expr,
109 env: &Environment,
110 ) -> Result<RValue, RFlow> {
111 loop {
112 self.check_interrupt()?;
113 let cond = self.eval_in(condition, env)?;
114 let test = match &cond {
115 RValue::Vector(v) => v.as_logical_scalar().unwrap_or(false),
116 _ => false,
117 };
118 if !test {
119 break;
120 }
121 match self.eval_in(body, env) {
122 Err(RFlow::Signal(RSignal::Break)) => break,
123 Err(RFlow::Signal(RSignal::Next)) => continue,
124 Err(err) => return Err(err),
125 _ => {}
126 }
127 }
128 Ok(RValue::Null)
129 }
130
131 pub(super) fn eval_repeat(&self, body: &Expr, env: &Environment) -> Result<RValue, RFlow> {
132 loop {
133 self.check_interrupt()?;
134 match self.eval_in(body, env) {
135 Err(RFlow::Signal(RSignal::Break)) => break,
136 Err(RFlow::Signal(RSignal::Next)) => continue,
137 Err(err) => return Err(err),
138 _ => {}
139 }
140 }
141 Ok(RValue::Null)
142 }
143
144 pub(super) fn eval_ns_get(
145 &self,
146 namespace: &Expr,
147 name: &str,
148 env: &Environment,
149 ) -> Result<RValue, RFlow> {
150 let ns_name = match namespace {
152 crate::parser::ast::Expr::Symbol(s) => s.as_str(),
153 _ => "",
154 };
155
156 if !ns_name.is_empty() {
157 {
159 let loaded = self.loaded_namespaces.borrow();
160 if let Some(ns) = loaded.get(ns_name) {
161 if let Some(val) = ns.exports_env.get(name) {
165 return Ok(val);
166 }
167 if let Some(val) = ns.namespace_env.get(name) {
168 return Ok(val);
169 }
170 }
171 }
172
173 if self.find_package_dir(ns_name).is_some() {
175 if let Ok(_ns_env) = self.load_namespace(ns_name) {
176 let loaded = self.loaded_namespaces.borrow();
177 if let Some(ns) = loaded.get(ns_name) {
178 if let Some(val) = ns.exports_env.get(name) {
179 return Ok(val);
180 }
181 if let Some(val) = ns.namespace_env.get(name) {
182 return Ok(val);
183 }
184 }
185 }
186 }
187
188 if let Some(descriptor) = crate::interpreter::builtins::find_builtin_ns(ns_name, name) {
190 return Ok(RValue::Function(RFunction::Builtin {
191 name: descriptor.name.to_string(),
192 implementation: descriptor.implementation,
193 min_args: descriptor.min_args,
194 max_args: descriptor.max_args,
195 formals: descriptor.formals,
196 }));
197 }
198 }
199
200 env.get(name)
202 .or_else(|| self.global_env.get(name))
203 .ok_or_else(|| RError::new(RErrorKind::Name, format!("{}::{}", ns_name, name)).into())
204 }
205
206 pub(super) fn eval_for(
207 &self,
208 var: &str,
209 iter_val: &RValue,
210 body: &Expr,
211 env: &Environment,
212 ) -> Result<RValue, RFlow> {
213 match iter_val {
214 RValue::Vector(v) => {
215 let len = v.len();
216 for i in 0..len {
217 self.check_interrupt()?;
218 let elem = match &v.inner {
219 Vector::Raw(vals) => RValue::vec(Vector::Raw(vec![vals[i]])),
220 Vector::Double(vals) => {
221 RValue::vec(Vector::Double(vec![vals.get_opt(i)].into()))
222 }
223 Vector::Integer(vals) => {
224 RValue::vec(Vector::Integer(vec![vals.get_opt(i)].into()))
225 }
226 Vector::Logical(vals) => RValue::vec(Vector::Logical(vec![vals[i]].into())),
227 Vector::Complex(vals) => RValue::vec(Vector::Complex(vec![vals[i]].into())),
228 Vector::Character(vals) => {
229 RValue::vec(Vector::Character(vec![vals[i].clone()].into()))
230 }
231 };
232 env.set(var.to_string(), elem);
233 match self.eval_in(body, env) {
234 Ok(_) => {}
235 Err(RFlow::Signal(RSignal::Next)) => continue,
236 Err(RFlow::Signal(RSignal::Break)) => break,
237 Err(err) => return Err(err),
238 }
239 }
240 }
241 RValue::List(list) => {
242 for (_, val) in &list.values {
243 self.check_interrupt()?;
244 env.set(var.to_string(), val.clone());
245 match self.eval_in(body, env) {
246 Ok(_) => {}
247 Err(RFlow::Signal(RSignal::Next)) => continue,
248 Err(RFlow::Signal(RSignal::Break)) => break,
249 Err(err) => return Err(err),
250 }
251 }
252 }
253 RValue::Null => {}
254 _ => {
255 return Err(RError::new(
256 RErrorKind::Type,
257 "invalid for() loop sequence".to_string(),
258 )
259 .into());
260 }
261 }
262 Ok(RValue::Null)
263 }
264}