1use std::cmp;
10use std::f32;
11use std::ffi::OsString;
12use std::fs;
13use std::fs::File;
14use std::fs::create_dir;
15use std::fs::read_dir;
16use std::fs::remove_dir;
17use std::fs::remove_file;
18use std::io::BufWriter;
19use std::io::ErrorKind;
20use std::io::Read;
21use std::io::Write;
22use std::io::stdin;
23use std::io::stdout;
24use std::io::stderr;
25use std::mem::size_of;
26use std::path;
27use std::path::PathBuf;
28use std::process::Command;
29use std::sync::Arc;
30use std::sync::RwLock;
31use std::sync::Weak;
32use opener::open_browser;
33use rand::random;
34use rand::random_range;
35use crate::matrix::Matrix;
36use crate::serde_json;
37use crate::toml;
38use crate::env::*;
39use crate::error::*;
40use crate::getopts::*;
41use crate::interp::*;
42use crate::io::*;
43use crate::mod_node::*;
44use crate::parser::*;
45#[cfg(feature = "plot")]
46use crate::plot::*;
47use crate::utils::*;
48use crate::value::*;
49use crate::version::*;
50
51fn fun1<F>(arg_values: &[Value], f: F) -> Result<Value>
52 where F: FnOnce(&Value) -> Result<Value>
53{
54 if arg_values.len() != 1 {
55 return Err(Error::Interp(String::from("invalid number of arguments")));
56 }
57 match arg_values.get(0) {
58 Some(value) => f(value),
59 None => Err(Error::Interp(String::from("no argument"))),
60 }
61}
62
63fn fun2<F>(arg_values: &[Value], f: F) -> Result<Value>
64 where F: FnOnce(&Value, &Value) -> Result<Value>
65{
66 if arg_values.len() != 2 {
67 return Err(Error::Interp(String::from("invalid number of arguments")));
68 }
69 match (arg_values.get(0), arg_values.get(1)) {
70 (Some(value), Some(value2)) => f(value, value2),
71 (_, _) => Err(Error::Interp(String::from("no argument"))),
72 }
73}
74
75fn fun1_for_f32_and_matrix_with_fun_refs<F, G>(arg_values: &[Value], err_msg: &str, f: &mut F, g: &mut G) -> Result<Value>
76 where F: FnMut(f32) -> f32,
77 G: FnMut(&Matrix) -> Result<Matrix>
78{
79 if arg_values.len() != 1 {
80 return Err(Error::Interp(String::from("invalid number of arguments")));
81 }
82 match arg_values.get(0) {
83 Some(value @ (Value::Int(_) | Value::Float(_))) => Ok(Value::Float(f(value.to_f32()))),
84 Some(Value::Object(object)) => {
85 match &**object {
86 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(g(a)?)))),
87 _ => Err(Error::Interp(String::from(err_msg))),
88 }
89 },
90 Some(value) => value.dot1(err_msg, |a| fun1_for_f32_and_matrix_with_fun_refs(&[a.clone()], err_msg, f, g)),
91 None => Err(Error::Interp(String::from("no argument"))),
92 }
93}
94
95fn fun1_for_f32_and_matrix<F, G>(arg_values: &[Value], err_msg: &str, mut f: F, mut g: G) -> Result<Value>
96 where F: FnMut(f32) -> f32,
97 G: FnMut(&Matrix) -> Result<Matrix>
98{ fun1_for_f32_and_matrix_with_fun_refs(arg_values, err_msg, &mut f, &mut g) }
99
100fn fun2_for_f32_and_matrix_with_fun_refs<F, G, RG, H>(arg_values: &[Value], err_msg: &str, f: &mut F, g: &mut G, rg: &mut RG, h: &mut H) -> Result<Value>
101 where F: FnMut(f32, f32) -> f32,
102 G: FnMut(&Matrix, f32) -> Result<Matrix>,
103 RG: FnMut(&Matrix, f32) -> Result<Matrix>,
104 H: FnMut(&Matrix, &Matrix) -> Result<Matrix>
105{
106 if arg_values.len() != 2 {
107 return Err(Error::Interp(String::from("invalid number of arguments")));
108 }
109 match (arg_values.get(0), arg_values.get(1)) {
110 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => Ok(Value::Float(f(value.to_f32(), value2.to_f32()))),
111 (Some(Value::Object(object)), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => {
112 match &**object {
113 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(g(a, value2.to_f32())?)))),
114 _ => Err(Error::Interp(String::from(err_msg))),
115 }
116 },
117 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(Value::Object(object2))) => {
118 match &**object2 {
119 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(rg(b, value.to_f32())?)))),
120 _ => Err(Error::Interp(String::from(err_msg))),
121 }
122 },
123 (Some(Value::Object(object)), Some(Value::Object(object2))) => {
124 match (&**object, &**object2) {
125 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(h(a, b)?)))),
126 _ => Err(Error::Interp(String::from(err_msg))),
127 }
128 },
129 (Some(value @ Value::Ref(_)), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => value.dot1(err_msg, |a| fun2_for_f32_and_matrix_with_fun_refs(&[a.clone(), value2.clone()], err_msg, f, g, rg, h)),
130 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(value2 @ Value::Ref(_))) => value2.dot1(err_msg, |b| fun2_for_f32_and_matrix_with_fun_refs(&[value.clone(), b.clone()], err_msg, f, g, rg, h)),
131 (Some(value), Some(value2)) => value.dot2(value2, err_msg, |a, b| fun2_for_f32_and_matrix_with_fun_refs(&[a.clone(), b.clone()], err_msg, f, g, rg, h)),
132 (_, _) => Err(Error::Interp(String::from("no argument"))),
133 }
134}
135
136fn fun2_for_f32_and_matrix<F, G, RG, H>(arg_values: &[Value], err_msg: &str, mut f: F, mut g: G, mut rg: RG, mut h: H) -> Result<Value>
137 where F: FnMut(f32, f32) -> f32,
138 G: FnMut(&Matrix, f32) -> Result<Matrix>,
139 RG: FnMut(&Matrix, f32) -> Result<Matrix>,
140 H: FnMut(&Matrix, &Matrix) -> Result<Matrix>
141{ fun2_for_f32_and_matrix_with_fun_refs(arg_values, err_msg, &mut f, &mut g, &mut rg, &mut h) }
142
143fn get_first_arg_string(arg_values: &[Value], err_msg: &str) -> Result<String>
144{
145 match arg_values.get(0) {
146 Some(arg_value) => {
147 match arg_value.to_opt_string() {
148 Some(s) => Ok(s),
149 None => Err(Error::Interp(String::from(err_msg))),
150 }
151 },
152 None => Err(Error::Interp(String::from("no argument"))),
153 }
154}
155
156pub fn typ(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
158{
159 if arg_values.len() != 1 {
160 return Err(Error::Interp(String::from("invalid number of arguments")));
161 }
162 match arg_values.get(0) {
163 Some(Value::None) => Ok(Value::Object(Arc::new(Object::String(String::from("none"))))),
164 Some(Value::Bool(_)) => Ok(Value::Object(Arc::new(Object::String(String::from("bool"))))),
165 Some(Value::Int(_)) => Ok(Value::Object(Arc::new(Object::String(String::from("int"))))),
166 Some(Value::Float(_)) => Ok(Value::Object(Arc::new(Object::String(String::from("float"))))),
167 Some(Value::Object(object)) => {
168 match &**object {
169 Object::String(_) => Ok(Value::Object(Arc::new(Object::String(String::from("string"))))),
170 Object::IntRange(_, _, _) => Ok(Value::Object(Arc::new(Object::String(String::from("intrange"))))),
171 Object::FloatRange(_, _, _) => Ok(Value::Object(Arc::new(Object::String(String::from("floatrange"))))),
172 Object::Matrix(_) => Ok(Value::Object(Arc::new(Object::String(String::from("matrix"))))),
173 Object::Fun(_, _, _) | Object::BuiltinFun(_, _) => Ok(Value::Object(Arc::new(Object::String(String::from("function"))))),
174 Object::MatrixArray(_, _, _, _) => Ok(Value::Object(Arc::new(Object::String(String::from("matrixarray"))))),
175 Object::MatrixRowSlice(_, _) => Ok(Value::Object(Arc::new(Object::String(String::from("matrixrowslice"))))),
176 Object::Error(_, _) => Ok(Value::Object(Arc::new(Object::String(String::from("error"))))),
177 Object::WindowId(_) => Ok(Value::Object(Arc::new(Object::String(String::from("windowid"))))),
178 }
179 },
180 Some(Value::Ref(object)) => {
181 let object_g = rw_lock_read(object)?;
182 match &*object_g {
183 MutObject::Array(_) => Ok(Value::Object(Arc::new(Object::String(String::from("array"))))),
184 MutObject::Struct(_) => Ok(Value::Object(Arc::new(Object::String(String::from("struct"))))),
185 }
186 },
187 Some(Value::Weak(_)) => Ok(Value::Object(Arc::new(Object::String(String::from("weak"))))),
188 None => Err(Error::Interp(String::from("no argument"))),
189 }
190}
191
192pub fn clone(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
194{
195 if arg_values.len() != 1 {
196 return Err(Error::Interp(String::from("invalid number of arguments")));
197 }
198 match arg_values.get(0) {
199 Some(Value::Ref(object)) => {
200 let object_g = rw_lock_read(object)?;
201 Ok(Value::Ref(Arc::new(RwLock::new(object_g.clone()))))
202 },
203 Some(value) => Ok(value.clone()),
204 None => Err(Error::Interp(String::from("no argument"))),
205 }
206}
207
208pub fn boolean(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
210{ fun1(arg_values, |a| Ok(Value::Bool(a.to_bool()))) }
211
212pub fn int(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
214{ fun1(arg_values, |a| Ok(Value::Int(a.to_i64()))) }
215
216pub fn float(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
218{ fun1(arg_values, |a| Ok(Value::Float(a.to_f32()))) }
219
220pub fn string(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
222{ fun1(arg_values, |a| Ok(Value::Object(Arc::new(Object::String(format!("{}", a)))))) }
223
224fn checked_mul_row_count_and_col_count(row_count: i64, col_count: i64) -> Result<usize>
225{
226 if row_count < 0 {
227 return Err(Error::Interp(String::from("number of rows is negative")));
228 }
229 if col_count < 0 {
230 return Err(Error::Interp(String::from("number of columns is negative")));
231 }
232 if row_count > (isize::MAX as i64) {
233 return Err(Error::Interp(String::from("too large number of rows")));
234 }
235 if col_count > (isize::MAX as i64) {
236 return Err(Error::Interp(String::from("too large number of columns")));
237 }
238 match row_count.checked_mul(col_count) {
239 Some(len) => {
240 if len > (isize::MAX as i64) {
241 return Err(Error::Interp(String::from("too large number of matrix elements")));
242 }
243 match (len as isize).checked_mul(size_of::<f32>() as isize) {
244 Some(_) => Ok(len as usize),
245 None => Err(Error::Interp(String::from("too large number of matrix elements"))),
246 }
247 },
248 None => Err(Error::Interp(String::from("too large number of matrix elements"))),
249 }
250}
251
252pub fn zeros(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
254{
255 if arg_values.len() != 2 {
256 return Err(Error::Interp(String::from("invalid number of arguments")));
257 }
258 match (arg_values.get(0), arg_values.get(1)) {
259 (Some(n_value @ (Value::Int(_) | Value::Float(_))), Some(m_value @ (Value::Int(_) | Value::Float(_)))) => {
260 let n = n_value.to_i64();
261 let m = m_value.to_i64();
262 checked_mul_row_count_and_col_count(n, m)?;
263 Ok(Value::Object(Arc::new(Object::Matrix(matrix_create_and_set_zeros(n as usize, m as usize)?))))
264 },
265 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function zeros"))),
266 (_, _) => Err(Error::Interp(String::from("no argument"))),
267 }
268}
269
270pub fn ones(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
272{
273 if arg_values.len() != 2 {
274 return Err(Error::Interp(String::from("invalid number of arguments")));
275 }
276 match (arg_values.get(0), arg_values.get(1)) {
277 (Some(n_value @ (Value::Int(_) | Value::Float(_))), Some(m_value @ (Value::Int(_) | Value::Float(_)))) => {
278 let n = n_value.to_i64();
279 let m = m_value.to_i64();
280 let len = checked_mul_row_count_and_col_count(n, m)?;
281 let xs = vec![1.0f32; len];
282 Ok(Value::Object(Arc::new(Object::Matrix(matrix_create_and_set_elems(n as usize, m as usize, xs.as_slice())?))))
283 },
284 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function ones"))),
285 (_, _) => Err(Error::Interp(String::from("no argument"))),
286 }
287}
288
289pub fn eye(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
291{
292 if arg_values.len() != 1 {
293 return Err(Error::Interp(String::from("invalid number of arguments")));
294 }
295 match arg_values.get(0) {
296 Some(n_value @ (Value::Int(_) | Value::Float(_))) => {
297 let n = n_value.to_i64();
298 let len = checked_mul_row_count_and_col_count(n, n)?;
299 let mut xs = vec![0.0f32; len];
300 for i in 0..(n as usize) {
301 xs[i * (n as usize) + i] = 1.0;
302 }
303 Ok(Value::Object(Arc::new(Object::Matrix(matrix_create_and_set_elems(n as usize, n as usize, xs.as_slice())?))))
304 },
305 Some(_) => Err(Error::Interp(String::from("unsupported type for function eye"))),
306 None => Err(Error::Interp(String::from("no argument"))),
307 }
308}
309
310pub fn init(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
312{
313 if arg_values.len() != 4 {
314 return Err(Error::Interp(String::from("invalid number of arguments")));
315 }
316 match (arg_values.get(0), arg_values.get(1), arg_values.get(2), arg_values.get(3)) {
317 (Some(n_value @ (Value::Int(_) | Value::Float(_))), Some(m_value @ (Value::Int(_) | Value::Float(_))), Some(data_value), Some(fun_value)) => {
318 let n = n_value.to_i64();
319 let m = m_value.to_i64();
320 let len = checked_mul_row_count_and_col_count(n, m)?;
321 let mut xs = vec![0.0f32; len];
322 for i in 0..(n as usize) {
323 for j in 0..(m as usize) {
324 match fun_value.apply(interp, env, &[data_value.clone(), Value::Int((i + 1) as i64), Value::Int((j + 1) as i64)])?.to_opt_f32() {
325 Some(x) => xs[i * (m as usize) + j] = x,
326 None => return Err(Error::Interp(String::from("can't convert value to floating-point number"))),
327 }
328 }
329 }
330 Ok(Value::Object(Arc::new(Object::Matrix(matrix_create_and_set_elems(n as usize, m as usize, xs.as_slice())?))))
331 },
332 (Some(_), Some(_), Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function init"))),
333 (_, _, _, _) => Err(Error::Interp(String::from("no argument"))),
334 }
335}
336
337pub fn initdiag(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
339{
340 if arg_values.len() != 3 {
341 return Err(Error::Interp(String::from("invalid number of arguments")));
342 }
343 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
344 (Some(n_value @ (Value::Int(_) | Value::Float(_))), Some(data_value), Some(fun_value)) => {
345 let n = n_value.to_i64();
346 let len = checked_mul_row_count_and_col_count(n, n)?;
347 let mut xs = vec![0.0f32; len];
348 for i in 0..(n as usize) {
349 match fun_value.apply(interp, env, &[data_value.clone(), Value::Int((i + 1) as i64)])?.to_opt_f32() {
350 Some(x) => xs[i * (n as usize) + i] = x,
351 None => return Err(Error::Interp(String::from("can't convert value to floating-point number"))),
352 }
353 }
354 Ok(Value::Object(Arc::new(Object::Matrix(matrix_create_and_set_elems(n as usize, n as usize, xs.as_slice())?))))
355 },
356 (Some(_), Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function init"))),
357 (_, _, _) => Err(Error::Interp(String::from("no argument"))),
358 }
359}
360
361fn to_row_or_column(value: &Value) -> Result<Vec<f32>>
362{
363 match value.iter()? {
364 Some(mut iter) => {
365 let mut xs: Vec<f32> = Vec::new();
366 loop {
367 match iter.next() {
368 Some(Ok(elem)) => {
369 match elem.to_opt_f32() {
370 Some(x) => xs.push(x),
371 None => return Err(Error::Interp(String::from("can't convert value to floating-point number"))),
372 }
373 },
374 Some(Err(err)) => return Err(err),
375 None => break,
376 }
377 }
378 Ok(xs)
379 },
380 None => Err(Error::Interp(String::from("value isn't iterable"))),
381 }
382}
383
384pub fn matrix(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
386{
387 if arg_values.len() != 1 {
388 return Err(Error::Interp(String::from("invalid number of arguments")));
389 }
390 let value = match arg_values.get(0) {
391 Some(tmp_value @ Value::Object(object)) => {
392 match &**object {
393 Object::Matrix(_) => return Ok(tmp_value.clone()),
394 _ => tmp_value,
395 }
396 },
397 Some(tmp_value) => tmp_value,
398 None => return Err(Error::Interp(String::from("no argument"))),
399 };
400 match value.iter()? {
401 Some(mut iter) => {
402 let mut xs: Vec<f32> = Vec::new();
403 let mut row_count = 0usize;
404 let mut col_count: Option<usize> = None;
405 loop {
406 match iter.next() {
407 Some(Ok(row_value)) => {
408 let ys = to_row_or_column(&row_value)?;
409 if col_count.map(|n| n == ys.len()).unwrap_or(true) {
410 xs.extend_from_slice(ys.as_slice());
411 col_count = Some(ys.len());
412 } else {
413 return Err(Error::Interp(String::from("numbers of columns of matrix rows aren't equal")));
414 }
415 match row_count.checked_add(1) {
416 Some(new_row_count) => row_count = new_row_count,
417 None => return Err(Error::Interp(String::from("too many matrix rows"))),
418 }
419 },
420 Some(Err(err)) => return Err(err),
421 None => break,
422 }
423 }
424 Ok(Value::Object(Arc::new(Object::Matrix(matrix_create_and_set_elems(row_count, col_count.unwrap_or(0), xs.as_slice())?))))
425 },
426 None => Err(Error::Interp(String::from("value isn't iterable"))),
427 }
428}
429
430pub fn rowvector(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
432{
433 if arg_values.len() != 1 {
434 return Err(Error::Interp(String::from("invalid number of arguments")));
435 }
436 let value = match arg_values.get(0) {
437 Some(tmp_value @ Value::Object(object)) => {
438 match &**object {
439 Object::Matrix(a) => {
440 if a.row_count() == 1 {
441 return Ok(tmp_value.clone());
442 } else {
443 return Err(Error::Interp(String::from("number of rows isn't one")));
444 }
445 },
446 _ => tmp_value,
447 }
448 },
449 Some(tmp_value) => tmp_value,
450 None => return Err(Error::Interp(String::from("no argument"))),
451 };
452 let xs = to_row_or_column(&value)?;
453 Ok(Value::Object(Arc::new(Object::Matrix(matrix_create_and_set_elems(1, xs.len(), xs.as_slice())?))))
454}
455
456pub fn colvector(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
458{
459 if arg_values.len() != 1 {
460 return Err(Error::Interp(String::from("invalid number of arguments")));
461 }
462 let value = match arg_values.get(0) {
463 Some(tmp_value @ Value::Object(object)) => {
464 match &**object {
465 Object::Matrix(a) => {
466 if a.col_count() == 1 {
467 return Ok(tmp_value.clone());
468 } else {
469 return Err(Error::Interp(String::from("number of columns isn't one")));
470 }
471 },
472 _ => tmp_value,
473 }
474 },
475 Some(tmp_value) => tmp_value,
476 None => return Err(Error::Interp(String::from("no argument"))),
477 };
478 let xs = to_row_or_column(&value)?;
479 Ok(Value::Object(Arc::new(Object::Matrix(matrix_create_and_set_elems(xs.len(), 1, xs.as_slice())?))))
480}
481
482pub fn matrixarray(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
484{ fun1(arg_values, Value::to_matrix_array) }
485
486pub fn error(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
488{
489 if arg_values.len() != 2 {
490 return Err(Error::Interp(String::from("invalid number of arguments")));
491 }
492 match (arg_values.get(0), arg_values.get(1)) {
493 (Some(Value::Object(kind_object)), Some(Value::Object(msg_object))) => {
494 match (&**kind_object, &**msg_object) {
495 (Object::String(kind), Object::String(msg)) => Ok(Value::Object(Arc::new(Object::Error(kind.clone(), msg.clone())))),
496 (_, _) => Err(Error::Interp(String::from("unsupported types for function error"))),
497 }
498 },
499 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function error"))),
500 (_, _) => Err(Error::Interp(String::from("no argument"))),
501 }
502}
503
504pub fn array(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
506{
507 if arg_values.len() != 1 {
508 return Err(Error::Interp(String::from("invalid number of arguments")));
509 }
510 let value = match arg_values.get(0) {
511 Some(tmp_value @ Value::Ref(object)) => {
512 let object_g = rw_lock_read(object)?;
513 match &*object_g {
514 MutObject::Array(_) => return Ok(tmp_value.clone()),
515 _ => tmp_value,
516 }
517 },
518 Some(tmp_value) => tmp_value,
519 None => return Err(Error::Interp(String::from("no argument"))),
520 };
521 match value.iter()? {
522 Some(mut iter) => {
523 let mut elems: Vec<Value> = Vec::new();
524 loop {
525 match iter.next() {
526 Some(Ok(elem)) => elems.push(elem),
527 Some(Err(err)) => return Err(err),
528 None => break,
529 }
530 }
531 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(elems)))))
532 },
533 None => Err(Error::Interp(String::from("value isn't iterable"))),
534 }
535}
536
537pub fn strong(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
539{
540 if arg_values.len() != 1 {
541 return Err(Error::Interp(String::from("invalid number of arguments")));
542 }
543 match arg_values.get(0) {
544 Some(value @ Value::Ref(_)) => Ok(value.clone()),
545 Some(Value::Weak(object)) => {
546 match object.upgrade() {
547 Some(object) => Ok(Value::Ref(object)),
548 None => Ok(Value::None),
549 }
550 },
551 Some(_) => Err(Error::Interp(String::from("unsupported types for function strong"))),
552 None => Err(Error::Interp(String::from("no argument"))),
553 }
554}
555
556pub fn weak(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
558{
559 if arg_values.len() > 1 {
560 return Err(Error::Interp(String::from("invalid number of arguments")));
561 }
562 match arg_values.get(0) {
563 Some(Value::Ref(object)) => Ok(Value::Weak(Arc::downgrade(object))),
564 Some(value @ Value::Weak(_)) => Ok(value.clone()),
565 Some(_) => Err(Error::Interp(String::from("unsupported types for function weak"))),
566 None => Ok(Value::Weak(Weak::new())),
567 }
568}
569
570pub fn isempty(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
572{
573 if arg_values.len() != 1 {
574 return Err(Error::Interp(String::from("invalid number of arguments")));
575 }
576 match arg_values.get(0) {
577 Some(Value::Object(object)) => {
578 match &**object {
579 Object::String(s) => Ok(Value::Bool(s.is_empty())),
580 Object::MatrixArray(row_count, _, _, _) => Ok(Value::Bool(*row_count == 0)),
581 Object::MatrixRowSlice(matrix_array, _) => {
582 match &**matrix_array {
583 Object::MatrixArray(_, col_count, _, _) => Ok(Value::Bool(*col_count == 0)),
584 _ => Err(Error::Interp(String::from("invalid matrix array type"))),
585 }
586 },
587 _ => Err(Error::Interp(String::from("unsupported type for function isempty"))),
588 }
589 },
590 Some(Value::Ref(object)) => {
591 let object_g = rw_lock_read(object)?;
592 match &*object_g {
593 MutObject::Array(elems) => Ok(Value::Bool(elems.is_empty())),
594 _ => Err(Error::Interp(String::from("unsupported type for function isempty"))),
595 }
596 },
597 Some(_) => Err(Error::Interp(String::from("unsupported type for function isempty"))),
598 None => Err(Error::Interp(String::from("no argument"))),
599 }
600}
601
602pub fn length(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
604{
605 if arg_values.len() != 1 {
606 return Err(Error::Interp(String::from("invalid number of arguments")));
607 }
608 match arg_values.get(0) {
609 Some(Value::Object(object)) => {
610 match &**object {
611 Object::String(s) => Ok(Value::Int(s.chars().count() as i64)),
612 Object::MatrixArray(row_count, _, _, _) => Ok(Value::Int(*row_count as i64)),
613 Object::MatrixRowSlice(matrix_array, _) => {
614 match &**matrix_array {
615 Object::MatrixArray(_, col_count, _, _) => Ok(Value::Int(*col_count as i64)),
616 _ => Err(Error::Interp(String::from("invalid matrix array type"))),
617 }
618 },
619 _ => Err(Error::Interp(String::from("unsupported type for function length"))),
620 }
621 },
622 Some(Value::Ref(object)) => {
623 let object_g = rw_lock_read(object)?;
624 match &*object_g {
625 MutObject::Array(elems) => Ok(Value::Int(elems.len() as i64)),
626 _ => Err(Error::Interp(String::from("unsupported type for function length"))),
627 }
628 },
629 Some(_) => Err(Error::Interp(String::from("unsupported type for function length"))),
630 None => Err(Error::Interp(String::from("no argument"))),
631 }
632}
633
634pub fn rows(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
636{
637 if arg_values.len() != 1 {
638 return Err(Error::Interp(String::from("invalid number of arguments")));
639 }
640 match arg_values.get(0) {
641 Some(Value::Object(object)) => {
642 match &**object {
643 Object::Matrix(a) => Ok(Value::Int(a.row_count() as i64)),
644 Object::MatrixArray(row_count, _, _, _) => Ok(Value::Int(*row_count as i64)),
645 _ => Err(Error::Interp(String::from("unsupported type for function rows"))),
646 }
647 },
648 Some(_) => Err(Error::Interp(String::from("unsupported type for function rows"))),
649 None => Err(Error::Interp(String::from("no argument"))),
650 }
651}
652
653pub fn columns(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
655{
656 if arg_values.len() != 1 {
657 return Err(Error::Interp(String::from("invalid number of arguments")));
658 }
659 match arg_values.get(0) {
660 Some(Value::Object(object)) => {
661 match &**object {
662 Object::Matrix(a) => Ok(Value::Int(a.col_count() as i64)),
663 Object::MatrixArray(_, col_count, _, _) => Ok(Value::Int(*col_count as i64)),
664 Object::MatrixRowSlice(matrix_array, _) => {
665 match &**matrix_array {
666 Object::MatrixArray(_, col_count, _, _) => Ok(Value::Int(*col_count as i64)),
667 _ => Err(Error::Interp(String::from("invalid matrix array type"))),
668 }
669 },
670 _ => Err(Error::Interp(String::from("unsupported type for function columns"))),
671 }
672 },
673 Some(_) => Err(Error::Interp(String::from("unsupported type for function columns"))),
674 None => Err(Error::Interp(String::from("no argument"))),
675 }
676}
677
678pub fn get(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
680{
681 if arg_values.len() < 2 || arg_values.len() > 3 {
682 return Err(Error::Interp(String::from("invalid number of arguments")));
683 }
684 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
685 (Some(Value::Object(object)), Some(i_value @ (Value::Int(_) | Value::Float(_))), None) => {
686 match &**object {
687 Object::String(s) => {
688 let i = i_value.to_i64();
689 if i < 1 || i > (s.chars().count() as i64) {
690 return Ok(Value::None);
691 }
692 match s.chars().nth((i - 1) as usize) {
693 Some(c) => {
694 let mut t = String::new();
695 t.push(c);
696 Ok(Value::Object(Arc::new(Object::String(t))))
697 }
698 None => Ok(Value::None),
699 }
700 },
701 Object::MatrixArray(row_count, _, _, _) => {
702 let i = i_value.to_i64();
703 if i < 1 || i > (*row_count as i64) {
704 return Ok(Value::None);
705 }
706 Ok(Value::Object(Arc::new(Object::MatrixRowSlice(object.clone(), (i - 1) as usize))))
707 },
708 Object::MatrixRowSlice(matrix_array, i) => {
709 let j = i_value.to_i64();
710 match &**matrix_array {
711 Object::MatrixArray(row_count, col_count, transpose_flag, xs) => {
712 if j < 1 || j > (*col_count as i64) {
713 return Ok(Value::None);
714 }
715 let k = match transpose_flag {
716 TransposeFlag::NoTranspose => i * (*col_count) + ((j - 1) as usize),
717 TransposeFlag::Transpose => ((j - 1) as usize) * (*row_count) + i,
718 };
719 Ok(xs.get(k).map(|x| Value::Float(*x)).unwrap_or(Value::None))
720 },
721 _ => Err(Error::Interp(String::from("invalid matrix array type"))),
722 }
723 },
724 _ => Err(Error::Interp(String::from("unsupported types for function get"))),
725 }
726 },
727 (Some(Value::Ref(object)), Some(i_value @ (Value::Int(_) | Value::Float(_) | Value::Object(_))), None) => {
728 let object_g = rw_lock_read(&**object)?;
729 match &*object_g {
730 MutObject::Array(elems) => {
731 match i_value {
732 Value::Int(_) | Value::Float(_) => {
733 let i = i_value.to_i64();
734 if i < 1 || i > (elems.len() as i64) {
735 return Ok(Value::None);
736 }
737 Ok(elems.get((i - 1) as usize).map(|x| x.clone()).unwrap_or(Value::None))
738 },
739 _ => Err(Error::Interp(String::from("unsupported types for function get"))),
740 }
741 },
742 MutObject::Struct(fields) => {
743 match i_value {
744 Value::Object(i_object) => {
745 match &**i_object {
746 Object::String(ident) => Ok(fields.get(ident).map(|x| x.clone()).unwrap_or(Value::None)),
747 _ => Err(Error::Interp(String::from("unsupported types for function get"))),
748 }
749 },
750 _ => Err(Error::Interp(String::from("unsupported types for function get"))),
751 }
752 },
753 }
754 },
755 (Some(Value::Object(object)), Some(i_value @ (Value::Int(_) | Value::Float(_))), Some(j_value @ (Value::Int(_) | Value::Float(_)))) => {
756 match &**object {
757 Object::MatrixArray(row_count, col_count, transpose_flag, xs) => {
758 let i = i_value.to_i64();
759 let j = j_value.to_i64();
760 if i < 1 || i > (*row_count as i64) {
761 return Ok(Value::None);
762 }
763 if j < 1 || j > (*col_count as i64) {
764 return Ok(Value::None);
765 }
766 let k = match transpose_flag {
767 TransposeFlag::NoTranspose => ((i - 1) as usize) * (*col_count) + ((j - 1) as usize),
768 TransposeFlag::Transpose => ((j - 1) as usize) * (*row_count) + ((i - 1) as usize),
769 };
770 Ok(xs.get(k).map(|x| Value::Float(*x)).unwrap_or(Value::None))
771 },
772 _ => Err(Error::Interp(String::from("unsupported types for function get"))),
773 }
774 },
775 (Some(_), Some(_), _) => Err(Error::Interp(String::from("unsupported types for function get"))),
776 (_, _, _) => Err(Error::Interp(String::from("no argument")))
777 }
778}
779
780pub fn getdiag(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
782{
783 if arg_values.len() != 2 {
784 return Err(Error::Interp(String::from("invalid number of arguments")));
785 }
786 match (arg_values.get(0), arg_values.get(1)) {
787 (Some(Value::Object(object)), Some(i_value @ (Value::Int(_) | Value::Float(_)))) => {
788 match &**object {
789 Object::MatrixArray(row_count, col_count, _, xs) => {
790 if *row_count != *col_count {
791 return Err(Error::Interp(String::from("number of rows isn't equal to number of columns")));
792 }
793 let i = i_value.to_i64();
794 if i < 1 || i > (*row_count as i64) {
795 return Ok(Value::None);
796 }
797 let k = ((i - 1) as usize) * (*col_count) + ((i - 1) as usize);
798 Ok(xs.get(k).map(|x| Value::Float(*x)).unwrap_or(Value::None))
799 },
800 _ => Err(Error::Interp(String::from("unsupported type for function getdiag"))),
801 }
802 },
803 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function getdiag"))),
804 (_, _) => Err(Error::Interp(String::from("no argument")))
805 }
806}
807
808pub fn split(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
810{
811 if arg_values.len() < 1 || arg_values.len() > 2 {
812 return Err(Error::Interp(String::from("invalid number of arguments")));
813 }
814 match (arg_values.get(0), arg_values.get(1)) {
815 (Some(Value::Object(object)), None) => {
816 match &**object {
817 Object::String(s) => {
818 let ss = s.split_whitespace();
819 let elems: Vec<Value> = ss.map(|t| Value::Object(Arc::new(Object::String(String::from(t))))).collect();
820 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(elems)))))
821 },
822 _ => Err(Error::Interp(String::from("unsupported type for function split"))),
823 }
824 },
825 (Some(Value::Object(object)), Some(Value::Object(object2))) => {
826 match (&**object, &**object2) {
827 (Object::String(s), Object::String(t)) => {
828 let ss = s.split(t.as_str());
829 let elems: Vec<Value> = ss.map(|u| Value::Object(Arc::new(Object::String(String::from(u))))).collect();
830 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(elems)))))
831 },
832 (_, _) => Err(Error::Interp(String::from("unsupported types for function split"))),
833 }
834 },
835 (Some(_), None) => Err(Error::Interp(String::from("unsupported type for function split"))),
836 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function split"))),
837 (_, _) => Err(Error::Interp(String::from("no argument"))),
838 }
839}
840
841pub fn trim(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
843{
844 if arg_values.len() != 1 {
845 return Err(Error::Interp(String::from("invalid number of arguments")));
846 }
847 match arg_values.get(0) {
848 Some(Value::Object(object)) => {
849 match &**object {
850 Object::String(s) => Ok(Value::Object(Arc::new(Object::String(String::from(s.trim()))))),
851 _ => Err(Error::Interp(String::from("unsupported type for function trim"))),
852 }
853 },
854 Some(_) => Err(Error::Interp(String::from("unsupported type for function trim"))),
855 None => Err(Error::Interp(String::from("no argument"))),
856 }
857}
858
859pub fn contains(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
861{
862 if arg_values.len() != 2 {
863 return Err(Error::Interp(String::from("invalid number of arguments")));
864 }
865 match (arg_values.get(0), arg_values.get(1)) {
866 (Some(Value::Object(object)), Some(Value::Object(object2))) => {
867 match (&**object, &**object2) {
868 (Object::String(s), Object::String(t)) => Ok(Value::Bool(s.contains(t.as_str()))),
869 (_, _) => Err(Error::Interp(String::from("unsupported types for function contains"))),
870 }
871 },
872 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function contains"))),
873 (_, _) => Err(Error::Interp(String::from("no argument"))),
874 }
875}
876
877pub fn startswith(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
879{
880 if arg_values.len() != 2 {
881 return Err(Error::Interp(String::from("invalid number of arguments")));
882 }
883 match (arg_values.get(0), arg_values.get(1)) {
884 (Some(Value::Object(object)), Some(Value::Object(object2))) => {
885 match (&**object, &**object2) {
886 (Object::String(s), Object::String(t)) => Ok(Value::Bool(s.starts_with(t.as_str()))),
887 (_, _) => Err(Error::Interp(String::from("unsupported types for function startswith"))),
888 }
889 },
890 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function startswith"))),
891 (_, _) => Err(Error::Interp(String::from("no argument"))),
892 }
893}
894
895pub fn endswith(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
897{
898 if arg_values.len() != 2 {
899 return Err(Error::Interp(String::from("invalid number of arguments")));
900 }
901 match (arg_values.get(0), arg_values.get(1)) {
902 (Some(Value::Object(object)), Some(Value::Object(object2))) => {
903 match (&**object, &**object2) {
904 (Object::String(s), Object::String(t)) => Ok(Value::Bool(s.ends_with(t.as_str()))),
905 (_, _) => Err(Error::Interp(String::from("unsupported types for function endswith"))),
906 }
907 },
908 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function endswith"))),
909 (_, _) => Err(Error::Interp(String::from("no argument"))),
910 }
911}
912
913pub fn replace(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
915{
916 if arg_values.len() != 3 {
917 return Err(Error::Interp(String::from("invalid number of arguments")));
918 }
919 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
920 (Some(Value::Object(object)), Some(Value::Object(object2)), Some(Value::Object(object3))) => {
921 match (&**object, &**object2, &**object3) {
922 (Object::String(s), Object::String(t), Object::String(u)) => Ok(Value::Object(Arc::new(Object::String(s.replace(t.as_str(), u.as_str()))))),
923 (_, _, _) => Err(Error::Interp(String::from("unsupported types for function replace"))),
924 }
925 },
926 (Some(_), Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function replace"))),
927 (_, _, _) => Err(Error::Interp(String::from("no argument"))),
928 }
929}
930
931pub fn upper(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
933{
934 if arg_values.len() != 1 {
935 return Err(Error::Interp(String::from("invalid number of arguments")));
936 }
937 match arg_values.get(0) {
938 Some(Value::Object(object)) => {
939 match &**object {
940 Object::String(s) => Ok(Value::Object(Arc::new(Object::String(s.to_uppercase())))),
941 _ => Err(Error::Interp(String::from("unsupported type for function upper"))),
942 }
943 },
944 Some(_) => Err(Error::Interp(String::from("unsupported type for function upper"))),
945 None => Err(Error::Interp(String::from("no argument"))),
946 }
947}
948
949pub fn lower(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
951{
952 if arg_values.len() != 1 {
953 return Err(Error::Interp(String::from("invalid number of arguments")));
954 }
955 match arg_values.get(0) {
956 Some(Value::Object(object)) => {
957 match &**object {
958 Object::String(s) => Ok(Value::Object(Arc::new(Object::String(s.to_lowercase())))),
959 _ => Err(Error::Interp(String::from("unsupported type for function lower"))),
960 }
961 },
962 Some(_) => Err(Error::Interp(String::from("unsupported type for function lower"))),
963 None => Err(Error::Interp(String::from("no argument"))),
964 }
965}
966
967#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
968enum SortType
969{
970 Bool,
971 Number,
972 String,
973 Incomparable,
974}
975
976pub fn sort(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
978{
979 if arg_values.len() != 1 {
980 return Err(Error::Interp(String::from("invalid number of arguments")));
981 }
982 match arg_values.get(0) {
983 Some(Value::Ref(object)) => {
984 let mut object_g = rw_lock_write(object)?;
985 match &mut *object_g {
986 MutObject::Array(elems) => {
987 let mut sort_type: Option<SortType> = None;
988 for elem in &*elems {
989 let new_sort_type = match elem {
990 Value::Bool(_) => SortType::Bool,
991 Value::Int(_) => SortType::Number,
992 Value::Float(n) => if !n.is_nan() { SortType::Number } else { SortType::Incomparable },
993 Value::Object(elem_object) => {
994 match &**elem_object {
995 Object::String(_) => SortType::String,
996 _ => SortType::Incomparable,
997 }
998 },
999 _ => SortType::Incomparable,
1000 };
1001 if sort_type.map(|t| t == new_sort_type).unwrap_or(true) {
1002 sort_type = Some(new_sort_type);
1003 } else {
1004 return Err(Error::Interp(String::from("array has elements which can't be compared")));
1005 }
1006 }
1007 match sort_type {
1008 Some(SortType::Incomparable) => return Err(Error::Interp(String::from("array has incomparable elements"))),
1009 _ => (),
1010 }
1011 elems.sort_by(|x, y| x.partial_cmp(y).unwrap());
1012 Ok(Value::None)
1013 },
1014 _ => Err(Error::Interp(String::from("unsupported type for function sort"))),
1015 }
1016 },
1017 Some(_) => Err(Error::Interp(String::from("unsupported type for function sort"))),
1018 None => Err(Error::Interp(String::from("no argument"))),
1019 }
1020}
1021
1022pub fn reverse(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1024{
1025 if arg_values.len() != 1 {
1026 return Err(Error::Interp(String::from("invalid number of arguments")));
1027 }
1028 match arg_values.get(0) {
1029 Some(Value::Ref(object)) => {
1030 let mut object_g = rw_lock_write(object)?;
1031 match &mut *object_g {
1032 MutObject::Array(elems) => {
1033 elems.reverse();
1034 Ok(Value::None)
1035 },
1036 _ => Err(Error::Interp(String::from("unsupported type for function reverse"))),
1037 }
1038 },
1039 Some(_) => Err(Error::Interp(String::from("unsupported type for function reverse"))),
1040 None => Err(Error::Interp(String::from("no argument"))),
1041 }
1042}
1043
1044pub fn any(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
1046{
1047 if arg_values.len() != 3 {
1048 return Err(Error::Interp(String::from("invalid number of arguments")));
1049 }
1050 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
1051 (Some(a_value), Some(data_value), Some(fun_value)) => {
1052 match a_value.iter()? {
1053 Some(mut iter) => {
1054 loop {
1055 match iter.next() {
1056 Some(Ok(elem)) => {
1057 if fun_value.apply(interp, env, &[data_value.clone(), elem])?.to_bool() {
1058 return Ok(Value::Bool(true));
1059 }
1060 },
1061 Some(Err(err)) => return Err(err),
1062 None => break,
1063 }
1064 }
1065 Ok(Value::Bool(false))
1066 },
1067 None => Err(Error::Interp(String::from("value isn't iterable"))),
1068 }
1069 },
1070 (_, _, _) => Err(Error::Interp(String::from("no argument"))),
1071 }
1072}
1073
1074pub fn all(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
1076{
1077 if arg_values.len() != 3 {
1078 return Err(Error::Interp(String::from("invalid number of arguments")));
1079 }
1080 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
1081 (Some(a_value), Some(data_value), Some(fun_value)) => {
1082 match a_value.iter()? {
1083 Some(mut iter) => {
1084 loop {
1085 match iter.next() {
1086 Some(Ok(elem)) => {
1087 if !fun_value.apply(interp, env, &[data_value.clone(), elem])?.to_bool() {
1088 return Ok(Value::Bool(false));
1089 }
1090 },
1091 Some(Err(err)) => return Err(err),
1092 None => break,
1093 }
1094 }
1095 Ok(Value::Bool(true))
1096 },
1097 None => Err(Error::Interp(String::from("value isn't iterable"))),
1098 }
1099 },
1100 (_, _, _) => Err(Error::Interp(String::from("no argument"))),
1101 }
1102}
1103
1104pub fn find(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
1106{
1107 if arg_values.len() != 3 {
1108 return Err(Error::Interp(String::from("invalid number of arguments")));
1109 }
1110 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
1111 (Some(a_value), Some(data_value), Some(fun_value)) => {
1112 match a_value.iter()? {
1113 Some(mut iter) => {
1114 let mut i = 1i64;
1115 loop {
1116 match iter.next() {
1117 Some(Ok(elem)) => {
1118 if fun_value.apply(interp, env, &[data_value.clone(), elem])?.to_bool() {
1119 return Ok(Value::Int(i));
1120 }
1121 match i.checked_add(1) {
1122 Some(j) => i = j,
1123 None => return Err(Error::Interp(String::from("too large index"))),
1124 }
1125 },
1126 Some(Err(err)) => return Err(err),
1127 None => break,
1128 }
1129 }
1130 Ok(Value::None)
1131 },
1132 None => Err(Error::Interp(String::from("value isn't iterable"))),
1133 }
1134 },
1135 (_, _, _) => Err(Error::Interp(String::from("no argument"))),
1136 }
1137}
1138
1139pub fn filter(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
1141{
1142 if arg_values.len() != 3 {
1143 return Err(Error::Interp(String::from("invalid number of arguments")));
1144 }
1145 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
1146 (Some(a_value), Some(data_value), Some(fun_value)) => {
1147 match a_value.iter()? {
1148 Some(mut iter) => {
1149 let mut i_values: Vec<Value> = Vec::new();
1150 let mut i = 1i64;
1151 loop {
1152 match iter.next() {
1153 Some(Ok(elem)) => {
1154 if fun_value.apply(interp, env, &[data_value.clone(), elem])?.to_bool() {
1155 i_values.push(Value::Int(i));
1156 }
1157 match i.checked_add(1) {
1158 Some(j) => i = j,
1159 None => return Err(Error::Interp(String::from("too large index"))),
1160 }
1161 },
1162 Some(Err(err)) => return Err(err),
1163 None => break,
1164 }
1165 }
1166 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(i_values)))))
1167 },
1168 None => Err(Error::Interp(String::from("value isn't iterable"))),
1169 }
1170 },
1171 (_, _, _) => Err(Error::Interp(String::from("no argument"))),
1172 }
1173}
1174
1175pub fn max(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
1177{
1178 if arg_values.len() < 1 || arg_values.len() > 2 {
1179 return Err(Error::Interp(String::from("invalid number of arguments")));
1180 }
1181 match (arg_values.get(0), arg_values.get(1)) {
1182 (Some(value), None) => {
1183 match value.iter()? {
1184 Some(mut iter) => {
1185 let mut max_elem = Value::None;
1186 loop {
1187 match iter.next() {
1188 Some(Ok(elem)) => {
1189 match max_elem {
1190 Value::None => max_elem = elem,
1191 _ => {
1192 if elem > max_elem {
1193 max_elem = elem;
1194 }
1195 },
1196 }
1197 },
1198 Some(Err(err)) => return Err(err),
1199 None => break,
1200 }
1201 }
1202 Ok(max_elem)
1203 },
1204 None => Err(Error::Interp(String::from("value isn't iterable"))),
1205 }
1206 },
1207 (Some(Value::Int(a)), Some(Value::Int(b))) => Ok(Value::Int((*a).max(*b))),
1208 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => Ok(Value::Float(value.to_f32().max(value2.to_f32()))),
1209 (Some(Value::Object(object)), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => {
1210 match &**object {
1211 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_max_for_scalar(a, value2.to_f32())?)))),
1212 _ => Err(Error::Interp(String::from("unsupported types for function max"))),
1213 }
1214 },
1215 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(Value::Object(object2))) => {
1216 match &**object2 {
1217 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_max_for_scalar(b, value.to_f32())?)))),
1218 _ => Err(Error::Interp(String::from("unsupported types for function max"))),
1219 }
1220 },
1221 (Some(Value::Object(object)), Some(Value::Object(object2))) => {
1222 match (&**object, &**object2) {
1223 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_max(a, b)?)))),
1224 _ => Err(Error::Interp(String::from("unsupported types for function max"))),
1225 }
1226 },
1227 (Some(value @ Value::Ref(_)), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => value.dot1("unsupported types for function max", |a| max(interp, env, &[a.clone(), value2.clone()])),
1228 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(value2 @ Value::Ref(_))) => value2.dot1("unsupported types for function max", |b| max(interp, env, &[value.clone(), b.clone()])),
1229 (Some(value), Some(value2)) => value.dot2(value2, "unsupported types for function max", |a, b| max(interp, env, &[a.clone(), b.clone()])),
1230 (_, _) => Err(Error::Interp(String::from("no argument"))),
1231 }
1232}
1233
1234pub fn min(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
1236{
1237 if arg_values.len() < 1 || arg_values.len() > 2 {
1238 return Err(Error::Interp(String::from("invalid number of arguments")));
1239 }
1240 match (arg_values.get(0), arg_values.get(1)) {
1241 (Some(value), None) => {
1242 match value.iter()? {
1243 Some(mut iter) => {
1244 let mut min_elem = Value::None;
1245 loop {
1246 match iter.next() {
1247 Some(Ok(elem)) => {
1248 match min_elem {
1249 Value::None => min_elem = elem,
1250 _ => {
1251 if elem < min_elem {
1252 min_elem = elem;
1253 }
1254 },
1255 }
1256 },
1257 Some(Err(err)) => return Err(err),
1258 None => break,
1259 }
1260 }
1261 Ok(min_elem)
1262 },
1263 None => Err(Error::Interp(String::from("value isn't iterable"))),
1264 }
1265 },
1266 (Some(Value::Int(a)), Some(Value::Int(b))) => Ok(Value::Int((*a).min(*b))),
1267 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => Ok(Value::Float(value.to_f32().min(value2.to_f32()))),
1268 (Some(Value::Object(object)), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => {
1269 match &**object {
1270 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_min_for_scalar(a, value2.to_f32())?)))),
1271 _ => Err(Error::Interp(String::from("unsupported types for function min"))),
1272 }
1273 },
1274 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(Value::Object(object2))) => {
1275 match &**object2 {
1276 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_min_for_scalar(b, value.to_f32())?)))),
1277 _ => Err(Error::Interp(String::from("unsupported types for function min"))),
1278 }
1279 },
1280 (Some(Value::Object(object)), Some(Value::Object(object2))) => {
1281 match (&**object, &**object2) {
1282 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_min(a, b)?)))),
1283 _ => Err(Error::Interp(String::from("unsupported types for function min"))),
1284 }
1285 },
1286 (Some(value @ Value::Ref(_)), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => value.dot1("unsupported types for function min", |a| min(interp, env, &[a.clone(), value2.clone()])),
1287 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(value2 @ Value::Ref(_))) => value2.dot1("unsupported types for function min", |b| min(interp, env, &[value.clone(), b.clone()])),
1288 (Some(value), Some(value2)) => value.dot2(value2, "unsupported types for function min", |a, b| min(interp, env, &[a.clone(), b.clone()])),
1289 (_, _) => Err(Error::Interp(String::from("no argument"))),
1290 }
1291}
1292
1293pub fn imax(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1295{
1296 if arg_values.len() != 1 {
1297 return Err(Error::Interp(String::from("invalid number of arguments")));
1298 }
1299 match arg_values.get(0) {
1300 Some(value) => {
1301 match value.iter()? {
1302 Some(mut iter) => {
1303 let mut max_elem = Value::None;
1304 let mut i: Option<i64> = None;
1305 let mut j = 1i64;
1306 loop {
1307 match iter.next() {
1308 Some(Ok(elem)) => {
1309 match max_elem {
1310 Value::None => {
1311 max_elem = elem;
1312 i = Some(j);
1313 },
1314 _ => {
1315 if elem > max_elem {
1316 max_elem = elem;
1317 i = Some(j);
1318 }
1319 },
1320 }
1321 match j.checked_add(1) {
1322 Some(k) => j = k,
1323 None => return Err(Error::Interp(String::from("too large index"))),
1324 }
1325 },
1326 Some(Err(err)) => return Err(err),
1327 None => break,
1328 }
1329 }
1330 Ok(i.map(|i| Value::Int(i)).unwrap_or(Value::None))
1331 },
1332 None => Err(Error::Interp(String::from("value isn't iterable"))),
1333 }
1334 },
1335 None => Err(Error::Interp(String::from("no argument"))),
1336 }
1337}
1338
1339pub fn imin(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1341{
1342 if arg_values.len() != 1 {
1343 return Err(Error::Interp(String::from("invalid number of arguments")));
1344 }
1345 match arg_values.get(0) {
1346 Some(value) => {
1347 match value.iter()? {
1348 Some(mut iter) => {
1349 let mut min_elem = Value::None;
1350 let mut i: Option<i64> = None;
1351 let mut j = 1i64;
1352 loop {
1353 match iter.next() {
1354 Some(Ok(elem)) => {
1355 match min_elem {
1356 Value::None => {
1357 min_elem = elem;
1358 i = Some(j);
1359 },
1360 _ => {
1361 if elem < min_elem {
1362 min_elem = elem;
1363 i = Some(j);
1364 }
1365 },
1366 }
1367 match j.checked_add(1) {
1368 Some(k) => j = k,
1369 None => return Err(Error::Interp(String::from("too large index"))),
1370 }
1371 },
1372 Some(Err(err)) => return Err(err),
1373 None => break,
1374 }
1375 }
1376 Ok(i.map(|i| Value::Int(i)).unwrap_or(Value::None))
1377 },
1378 None => Err(Error::Interp(String::from("value isn't iterable"))),
1379 }
1380 },
1381 None => Err(Error::Interp(String::from("no argument"))),
1382 }
1383}
1384
1385pub fn push(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1387{
1388 if arg_values.len() != 2 {
1389 return Err(Error::Interp(String::from("invalid number of arguments")));
1390 }
1391 match (arg_values.get(0), arg_values.get(1)) {
1392 (Some(Value::Ref(a_object)), Some(value)) => {
1393 let mut a_object_g = rw_lock_write(a_object)?;
1394 match &mut *a_object_g {
1395 MutObject::Array(elems) => {
1396 elems.push(value.clone());
1397 Ok(Value::None)
1398 },
1399 _ => Err(Error::Interp(String::from("unsupported types for function push"))),
1400 }
1401 },
1402 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function push"))),
1403 (_, _) => Err(Error::Interp(String::from("no argument"))),
1404 }
1405}
1406
1407pub fn pop(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1409{
1410 if arg_values.len() != 1 {
1411 return Err(Error::Interp(String::from("invalid number of arguments")));
1412 }
1413 match arg_values.get(0) {
1414 Some(Value::Ref(a_object)) => {
1415 let mut a_object_g = rw_lock_write(a_object)?;
1416 match &mut *a_object_g {
1417 MutObject::Array(elems) => {
1418 match elems.pop() {
1419 Some(value) => Ok(value),
1420 None => Ok(Value::None),
1421 }
1422 },
1423 _ => Err(Error::Interp(String::from("unsupported type for function pop"))),
1424 }
1425 },
1426 Some(_) => Err(Error::Interp(String::from("unsupported type for function pop"))),
1427 None => Err(Error::Interp(String::from("no argument"))),
1428 }
1429}
1430
1431pub fn append(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1433{
1434 if arg_values.len() != 2 {
1435 return Err(Error::Interp(String::from("invalid number of arguments")));
1436 }
1437 match (arg_values.get(0), arg_values.get(1)) {
1438 (Some(Value::Ref(a_object)), Some(Value::Ref(b_object))) => {
1439 if !Arc::ptr_eq(a_object, b_object) {
1440 let mut a_object_g = rw_lock_write(a_object)?;
1441 let b_object_g = rw_lock_read(b_object)?;
1442 match (&mut *a_object_g, &*b_object_g) {
1443 (MutObject::Array(elems), MutObject::Array(elems2)) => {
1444 elems.extend_from_slice(elems2.as_slice());
1445 Ok(Value::None)
1446 },
1447 (MutObject::Struct(fields), MutObject::Struct(fields2)) => {
1448 for (ident2, field2) in fields2 {
1449 fields.insert(ident2.clone(), field2.clone());
1450 }
1451 Ok(Value::None)
1452 },
1453 (_, _) => Err(Error::Interp(String::from("unsupported types for function append"))),
1454 }
1455 } else {
1456 let mut a_object_g = rw_lock_write(a_object)?;
1457 match &mut *a_object_g {
1458 MutObject::Array(elems) => {
1459 let elems2 = elems.clone();
1460 elems.extend_from_slice(elems2.as_slice());
1461 Ok(Value::None)
1462 },
1463 MutObject::Struct(_) => Ok(Value::None),
1464 }
1465 }
1466 },
1467 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function append"))),
1468 (_, _) => Err(Error::Interp(String::from("no argument"))),
1469 }
1470}
1471
1472pub fn insert(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1474{
1475 if arg_values.len() != 3 {
1476 return Err(Error::Interp(String::from("invalid number of arguments")));
1477 }
1478 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
1479 (Some(Value::Ref(a_object)), Some(i_value @ (Value::Int(_) | Value::Float(_) | Value::Object(_))), Some(value)) => {
1480 let mut a_object_g = rw_lock_write(a_object)?;
1481 match &mut *a_object_g {
1482 MutObject::Array(elems) => {
1483 match i_value {
1484 Value::Int(_) | Value::Float(_) => {
1485 let i = i_value.to_i64();
1486 if i < 1 || i > (elems.len() as i64).saturating_add(1) {
1487 return Err(Error::Interp(String::from("index out of bounds")));
1488 }
1489 elems.insert((i - 1) as usize, value.clone());
1490 Ok(Value::None)
1491 },
1492 _ => Err(Error::Interp(String::from("unsupported types for function insert"))),
1493 }
1494 },
1495 MutObject::Struct(fields) => {
1496 match i_value {
1497 Value::Object(i_object) => {
1498 match &**i_object {
1499 Object::String(ident) => Ok(fields.insert(ident.clone(), value.clone()).unwrap_or(Value::None)),
1500 _ => Err(Error::Interp(String::from("unsupported types for function insert"))),
1501 }
1502 },
1503 _ => Err(Error::Interp(String::from("unsupported types for function insert"))),
1504 }
1505 },
1506 }
1507 },
1508 (Some(_), Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function insert"))),
1509 (_, _, _) => Err(Error::Interp(String::from("no argument"))),
1510 }
1511}
1512
1513pub fn remove(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1515{
1516 if arg_values.len() != 2 {
1517 return Err(Error::Interp(String::from("invalid number of arguments")));
1518 }
1519 match (arg_values.get(0), arg_values.get(1)) {
1520 (Some(Value::Ref(a_object)), Some(i_value @ (Value::Int(_) | Value::Float(_) | Value::Object(_)))) => {
1521 let mut a_object_g = rw_lock_write(a_object)?;
1522 match &mut *a_object_g {
1523 MutObject::Array(elems) => {
1524 match i_value {
1525 Value::Int(_) | Value::Float(_) => {
1526 let i = i_value.to_i64();
1527 if i < 1 || i > (elems.len() as i64) {
1528 return Ok(Value::None);
1529 }
1530 Ok(elems.remove((i - 1) as usize))
1531 },
1532 _ => Err(Error::Interp(String::from("unsupported types for function remove"))),
1533 }
1534 },
1535 MutObject::Struct(fields) => {
1536 match i_value {
1537 Value::Object(i_object) => {
1538 match &**i_object {
1539 Object::String(ident) => Ok(fields.remove(ident).unwrap_or(Value::None)),
1540 _ => Err(Error::Interp(String::from("unsupported types for function remove"))),
1541 }
1542 },
1543 _ => Err(Error::Interp(String::from("unsupported types for function remove"))),
1544 }
1545 },
1546 }
1547 },
1548 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function remove"))),
1549 (_, _) => Err(Error::Interp(String::from("no argument"))),
1550 }
1551}
1552
1553pub fn errorkind(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1555{
1556 if arg_values.len() != 1 {
1557 return Err(Error::Interp(String::from("invalid number of arguments")));
1558 }
1559 match arg_values.get(0) {
1560 Some(Value::Object(object)) => {
1561 match &**object {
1562 Object::Error(kind, _) => Ok(Value::Object(Arc::new(Object::String(kind.clone())))),
1563 _ => Err(Error::Interp(String::from("unsupported type for function errorkind"))),
1564 }
1565 },
1566 Some(_) => Err(Error::Interp(String::from("unsupported type for function errorkind"))),
1567 None => Err(Error::Interp(String::from("no argument"))),
1568 }
1569}
1570
1571pub fn errormsg(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1573{
1574 if arg_values.len() != 1 {
1575 return Err(Error::Interp(String::from("invalid number of arguments")));
1576 }
1577 match arg_values.get(0) {
1578 Some(Value::Object(object)) => {
1579 match &**object {
1580 Object::Error(_, msg) => Ok(Value::Object(Arc::new(Object::String(msg.clone())))),
1581 _ => Err(Error::Interp(String::from("unsupported type for function errormsg"))),
1582 }
1583 },
1584 Some(_) => Err(Error::Interp(String::from("unsupported type for function errormsg"))),
1585 None => Err(Error::Interp(String::from("no argument"))),
1586 }
1587}
1588
1589pub fn isequal(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1591{ fun2(arg_values, |a, b| Ok(Value::Bool(a.eq_without_types(b)?))) }
1592
1593pub fn isnotequal(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1595{ fun2(arg_values, |a, b| Ok(Value::Bool(!a.eq_without_types(b)?))) }
1596
1597pub fn isless(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1599{ fun2(arg_values, |a, b| Ok(Value::Bool(a < b))) }
1600
1601pub fn isgreaterequal(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1603{ fun2(arg_values, |a, b| Ok(Value::Bool(a >= b))) }
1604
1605pub fn isgreater(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1607{ fun2(arg_values, |a, b| Ok(Value::Bool(a > b))) }
1608
1609pub fn islessequal(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1611{ fun2(arg_values, |a, b| Ok(Value::Bool(a <= b))) }
1612
1613pub fn sigmoid(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1615{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function sigmoid", |a| 1.0 / (1.0 + (-a).exp()), matrix_sigmoid) }
1616
1617pub fn tanh(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1619{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function tanh", f32::tanh, matrix_tanh) }
1620
1621pub fn swish(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1623{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function swish", |a| a / (1.0 + (-a).exp()), matrix_swish) }
1624
1625pub fn softmax(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1627{
1628 if arg_values.len() != 1 {
1629 return Err(Error::Interp(String::from("invalid number of arguments")));
1630 }
1631 match arg_values.get(0) {
1632 Some(value @ (Value::Int(_) | Value::Float(_))) => Ok(Value::Float(value.to_f32().exp() / value.to_f32().exp())),
1633 Some(Value::Object(object)) => {
1634 match &**object {
1635 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_softmax(a)?)))),
1636 _ => Err(Error::Interp(String::from("unsupported type for function softmax"))),
1637 }
1638 },
1639 Some(_) => Err(Error::Interp(String::from("unsupported type for function softmax"))),
1640 None => Err(Error::Interp(String::from("no argument"))),
1641 }
1642}
1643
1644pub fn sqrt(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1646{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function sqrt", f32::sqrt, matrix_sqrt) }
1647
1648pub fn reallytranspose(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1650{
1651 if arg_values.len() != 1 {
1652 return Err(Error::Interp(String::from("invalid number of arguments")));
1653 }
1654 match arg_values.get(0) {
1655 Some(value @ (Value::Int(_) | Value::Float(_))) => Ok(value.clone()),
1656 Some(Value::Object(object)) => {
1657 match &**object {
1658 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_really_transpose(a)?)))),
1659 _ => Err(Error::Interp(String::from("unsupported type for function reallytranspose"))),
1660 }
1661 },
1662 Some(_) => Err(Error::Interp(String::from("unsupported type for function reallytranspose"))),
1663 None => Err(Error::Interp(String::from("no argument"))),
1664 }
1665}
1666
1667pub fn repeat(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1669{
1670 if arg_values.len() != 2 {
1671 return Err(Error::Interp(String::from("invalid number of arguments")));
1672 }
1673 match (arg_values.get(0), arg_values.get(1)) {
1674 (Some(Value::Object(object)), Some(n_value @ (Value::Int(_) | Value::Float(_)))) => {
1675 match &**object {
1676 Object::Matrix(a) => {
1677 let n = n_value.to_i64();
1678 let (m, l) = if a.col_count() == 1 {
1679 (a.row_count() as i64, n)
1680 } else if a.row_count() == 1 {
1681 (n, a.col_count() as i64)
1682 } else {
1683 return Err(Error::Interp(String::from("number of columns or rows isn't one")));
1684 };
1685 checked_mul_row_count_and_col_count(m, l)?;
1686 match matrix_repeat(a, n as usize)? {
1687 Some(b) => Ok(Value::Object(Arc::new(Object::Matrix(b)))),
1688 None => return Err(Error::Interp(String::from("number of columns or rows isn't one"))),
1689 }
1690 },
1691 _ => Err(Error::Interp(String::from("unsupported types for function repeat"))),
1692 }
1693 },
1694 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function repeat"))),
1695 (_, _) => Err(Error::Interp(String::from("no argument"))),
1696 }
1697}
1698
1699pub fn modulo(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1701{
1702 if arg_values.len() != 2 {
1703 return Err(Error::Interp(String::from("invalid number of arguments")));
1704 }
1705 match (arg_values.get(0), arg_values.get(1)) {
1706 (Some(Value::Int(a)), Some(Value::Int(b))) => {
1707 match a.checked_rem(*b) {
1708 Some(c) => Ok(Value::Int(c)),
1709 None => {
1710 if *b == 0 {
1711 Err(Error::Interp(String::from("division by zero")))
1712 } else {
1713 Err(Error::Interp(String::from("overflow in function mod")))
1714 }
1715 },
1716 }
1717 },
1718 (Some(value @ (Value::Int(_) | Value::Float(_))), Some(value2 @ (Value::Int(_) | Value::Float(_)))) => Ok(Value::Float(value.to_f32() % value2.to_f32())),
1719 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function mod"))),
1720 (_, _) => Err(Error::Interp(String::from("no argument"))),
1721 }
1722}
1723
1724pub fn abs(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
1726{
1727 if arg_values.len() != 1 {
1728 return Err(Error::Interp(String::from("invalid number of arguments")));
1729 }
1730 match arg_values.get(0) {
1731 Some(Value::Int(a)) => Ok(Value::Int(a.abs())),
1732 Some(Value::Float(a)) => Ok(Value::Float(a.abs())),
1733 Some(Value::Object(object)) => {
1734 match &**object {
1735 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_abs(a)?)))),
1736 _ => Err(Error::Interp(String::from("unsupported type for function abs"))),
1737 }
1738 },
1739 Some(value) => value.dot1("unsupported type for function abs", |a| abs(interp, env, &[a.clone()])),
1740 None => Err(Error::Interp(String::from("no argument"))),
1741 }
1742}
1743
1744pub fn pow(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1746{ fun2_for_f32_and_matrix(arg_values, "unsupported types for function pow", f32::powf, matrix_pow_for_scalar, matrix_rpow_for_scalar, matrix_pow) }
1747
1748pub fn exp(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1750{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function exp", f32::exp, matrix_exp) }
1751
1752pub fn log(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1754{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function log", f32::ln, matrix_ln) }
1755
1756pub fn log2(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1758{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function log2", f32::log2, matrix_log2) }
1759
1760pub fn log10(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1762{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function log10", f32::log10, matrix_log10) }
1763
1764pub fn sin(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1766{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function sin", f32::sin, matrix_sin) }
1767
1768pub fn cos(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1770{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function cos", f32::cos, matrix_cos) }
1771
1772pub fn tan(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1774{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function tan", f32::tan, matrix_tan) }
1775
1776pub fn asin(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1778{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function asin", f32::asin, matrix_asin) }
1779
1780pub fn acos(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1782{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function acos", f32::acos, matrix_acos) }
1783
1784pub fn atan(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1786{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function atan", f32::atan, matrix_atan) }
1787
1788pub fn atan2(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1790{ fun2_for_f32_and_matrix(arg_values, "unsupported types for function atan2", f32::atan2, matrix_atan2_for_scalar, matrix_ratan2_for_scalar, matrix_atan2) }
1791
1792pub fn sinh(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1794{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function sinh", f32::sinh, matrix_sinh) }
1795
1796pub fn cosh(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1798{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function cosh", f32::cosh, matrix_cosh) }
1799
1800pub fn asinh(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1802{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function asinh", f32::asinh, matrix_asinh) }
1803
1804pub fn acosh(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1806{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function acosh", f32::acosh, matrix_acosh) }
1807
1808pub fn atanh(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1810{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function atanh", f32::atanh, matrix_atanh) }
1811
1812pub fn sign(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1814{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function sign", f32::signum, matrix_signum) }
1815
1816pub fn ceil(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1818{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function ceil", f32::ceil, matrix_ceil) }
1819
1820pub fn floor(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1822{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function floor", f32::floor, matrix_floor) }
1823
1824pub fn round(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1826{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function round", f32::round, matrix_round) }
1827
1828pub fn trunc(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1830{ fun1_for_f32_and_matrix(arg_values, "unsupported type for function trunc", f32::trunc, matrix_trunc) }
1831
1832pub fn rand(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1834{
1835 if arg_values.len() != 0 {
1836 return Err(Error::Interp(String::from("invalid number of arguments")));
1837 }
1838 Ok(Value::Float(random()))
1839}
1840
1841pub fn randi(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1843{
1844 if arg_values.len() < 1 || arg_values.len() > 2 {
1845 return Err(Error::Interp(String::from("invalid number of arguments")));
1846 }
1847 match (arg_values.get(0), arg_values.get(1)) {
1848 (Some(max_value @ (Value::Int(_) | Value::Float(_))), None) => {
1849 let max = max_value.to_i64();
1850 Ok(Value::Int(random_range(1..=max)))
1851 }
1852 (Some(min_value @ (Value::Int(_) | Value::Float(_))), Some(max_value @ (Value::Int(_) | Value::Float(_)))) => {
1853 let min = min_value.to_i64();
1854 let max = max_value.to_i64();
1855 Ok(Value::Int(random_range(min..=max)))
1856 },
1857 (Some(_), None) => Err(Error::Interp(String::from("unsupported type for function randi"))),
1858 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function randi"))),
1859 (_, _) => Err(Error::Interp(String::from("no argument"))),
1860 }
1861}
1862
1863pub fn str2int(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1865{
1866 if arg_values.len() != 1 {
1867 return Err(Error::Interp(String::from("invalid number of arguments")));
1868 }
1869 match arg_values.get(0) {
1870 Some(Value::Object(object)) => {
1871 match &**object {
1872 Object::String(s) => {
1873 match s.parse::<i64>() {
1874 Ok(n) => Ok(Value::Int(n)),
1875 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("parseint"), format!("{}", err))))),
1876 }
1877 },
1878 _ => Err(Error::Interp(String::from("unsupported type for function str2int"))),
1879 }
1880 },
1881 Some(_) => Err(Error::Interp(String::from("unsupported type for function str2int"))),
1882 None => Err(Error::Interp(String::from("no argument"))),
1883 }
1884}
1885
1886pub fn str2float(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1888{
1889 if arg_values.len() != 1 {
1890 return Err(Error::Interp(String::from("invalid number of arguments")));
1891 }
1892 match arg_values.get(0) {
1893 Some(Value::Object(object)) => {
1894 match &**object {
1895 Object::String(s) => {
1896 match s.parse::<f32>() {
1897 Ok(n) => Ok(Value::Float(n)),
1898 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("parsefloat"), format!("{}", err))))),
1899 }
1900 },
1901 _ => Err(Error::Interp(String::from("unsupported type for function str2float"))),
1902 }
1903 },
1904 Some(_) => Err(Error::Interp(String::from("unsupported type for function str2float"))),
1905 None => Err(Error::Interp(String::from("no argument"))),
1906 }
1907}
1908
1909pub fn hex2dec(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1911{
1912 if arg_values.len() != 1 {
1913 return Err(Error::Interp(String::from("invalid number of arguments")));
1914 }
1915 match arg_values.get(0) {
1916 Some(Value::Object(object)) => {
1917 match &**object {
1918 Object::String(s) => {
1919 let s2 = if s.starts_with("0X") || s.starts_with("0x") {
1920 &s[2..]
1921 } else {
1922 s
1923 };
1924 match i64::from_str_radix(s2, 16) {
1925 Ok(n) => Ok(Value::Int(n)),
1926 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("parseint"), format!("{}", err))))),
1927 }
1928 },
1929 _ => Err(Error::Interp(String::from("unsupported type for function hex2dec"))),
1930 }
1931 },
1932 Some(_) => Err(Error::Interp(String::from("unsupported type for function hex2dec"))),
1933 None => Err(Error::Interp(String::from("no argument"))),
1934 }
1935}
1936
1937pub fn char2code(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1939{
1940 if arg_values.len() != 1 {
1941 return Err(Error::Interp(String::from("invalid number of arguments")));
1942 }
1943 match arg_values.get(0) {
1944 Some(Value::Object(object)) => {
1945 match &**object {
1946 Object::String(s) => {
1947 match s.chars().next() {
1948 Some(c) => Ok(Value::Int((c as u32) as i64)),
1949 None => Ok(Value::None),
1950 }
1951 },
1952 _ => Err(Error::Interp(String::from("unsupported type for function char2code"))),
1953 }
1954 },
1955 Some(_) => Err(Error::Interp(String::from("unsupported type for function char2code"))),
1956 None => Err(Error::Interp(String::from("no argument"))),
1957 }
1958}
1959
1960pub fn code2char(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1962{
1963 if arg_values.len() != 1 {
1964 return Err(Error::Interp(String::from("invalid number of arguments")));
1965 }
1966 match arg_values.get(0) {
1967 Some(value @ (Value::Int(_) | Value::Float(_))) => {
1968 let n = value.to_i64();
1969 if n < 0 || n > (u32::MAX as i64) {
1970 return Ok(Value::None);
1971 }
1972 match char::from_u32(n as u32) {
1973 Some(c) => {
1974 let mut s = String::new();
1975 s.push(c);
1976 Ok(Value::Object(Arc::new(Object::String(s))))
1977 },
1978 None => Ok(Value::None),
1979 }
1980 },
1981 Some(_) => Err(Error::Interp(String::from("unsupported type for function code2char"))),
1982 None => Err(Error::Interp(String::from("no argument"))),
1983 }
1984}
1985
1986pub fn formatmillis(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
1988{
1989 if arg_values.len() != 2 {
1990 return Err(Error::Interp(String::from("invalid number of arguments")));
1991 }
1992 match (arg_values.get(0), arg_values.get(1)) {
1993 (Some(Value::Object(object)), Some(millis_value @ (Value::Int(_) | Value::Float(_)))) => {
1994 match &**object {
1995 Object::String(s) => {
1996 let millis = millis_value.to_i64();
1997 let secs = millis / 1000;
1998 if s == &String::from("s") {
1999 Ok(Value::Object(Arc::new(Object::String(format!("{}.{:03}s", secs, millis % 1000)))))
2000 } else if s == &String::from("ms") {
2001 Ok(Value::Object(Arc::new(Object::String(format!("{}m{}.{:03}s", secs / 60, secs % 60, millis % 1000)))))
2002 } else if s == &String::from("hms") {
2003 Ok(Value::Object(Arc::new(Object::String(format!("{}h{}m{}.{:03}s", (secs / 60) / 60, (secs / 60) % 60, secs % 60, millis % 1000)))))
2004 } else {
2005 Ok(Value::Object(Arc::new(Object::Error(String::from("format"), String::from("invalid format")))))
2006 }
2007 },
2008 _ => Err(Error::Interp(String::from("unsupported types for function formatmillis"))),
2009 }
2010 },
2011 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function formatmillis"))),
2012 (_, _) => Err(Error::Interp(String::from("no argument"))),
2013 }
2014}
2015
2016pub fn withwidth(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2018{
2019 if arg_values.len() < 2 || arg_values.len() > 3 {
2020 return Err(Error::Interp(String::from("invalid number of arguments")));
2021 }
2022 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
2023 (Some(value), Some(width_value @ (Value::Int(_) | Value::Float(_))), None) => {
2024 let width = width_value.to_i64();
2025 if width < 0 {
2026 return Ok(Value::Object(Arc::new(Object::Error(String::from("format"), String::from("width is negative")))));
2027 }
2028 if width > (isize::MAX as i64) {
2029 return Ok(Value::Object(Arc::new(Object::Error(String::from("format"), String::from("too large width")))));
2030 }
2031 Ok(Value::Object(Arc::new(Object::String(format!("{:width$}", format!("{}", value), width = width as usize)))))
2032 },
2033 (Some(value), Some(width_value @ (Value::Int(_) | Value::Float(_))), Some(Value::Object(align_object))) => {
2034 match &**align_object {
2035 Object::String(align) => {
2036 let width = width_value.to_i64();
2037 if width < 0 {
2038 return Ok(Value::Object(Arc::new(Object::Error(String::from("format"), String::from("width is negative")))));
2039 }
2040 if width > (isize::MAX as i64) {
2041 return Ok(Value::Object(Arc::new(Object::Error(String::from("format"), String::from("too large width")))));
2042 }
2043 if align == &String::from("left") || align == &String::from("l") {
2044 Ok(Value::Object(Arc::new(Object::String(format!("{:<width$}", format!("{}", value), width = width as usize)))))
2045 } else if align == &String::from("center") || align == &String::from("c") {
2046 Ok(Value::Object(Arc::new(Object::String(format!("{:^width$}", format!("{}", value), width = width as usize)))))
2047 } else if align == &String::from("right") || align == &String::from("r") {
2048 Ok(Value::Object(Arc::new(Object::String(format!("{:>width$}", format!("{}", value), width = width as usize)))))
2049 } else {
2050 Ok(Value::Object(Arc::new(Object::Error(String::from("format"), String::from("invalid alignment")))))
2051 }
2052 },
2053 _ => Err(Error::Interp(String::from("unsupported types for function withwidth"))),
2054 }
2055 },
2056 (Some(_), Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function withwidth"))),
2057 (_, _, _) => Err(Error::Interp(String::from("no argument"))),
2058 }
2059}
2060
2061pub fn withzeros(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2063{
2064 if arg_values.len() != 2 {
2065 return Err(Error::Interp(String::from("invalid number of arguments")));
2066 }
2067 match (arg_values.get(0), arg_values.get(1)) {
2068 (Some(value), Some(width_value @ (Value::Int(_) | Value::Float(_)))) => {
2069 let width = width_value.to_i64();
2070 if width < 0 {
2071 return Ok(Value::Object(Arc::new(Object::Error(String::from("format"), String::from("width is negative")))));
2072 }
2073 if width > (isize::MAX as i64) {
2074 return Ok(Value::Object(Arc::new(Object::Error(String::from("format"), String::from("too large width")))));
2075 }
2076 Ok(Value::Object(Arc::new(Object::String(format!("{:0>width$}", format!("{}", value), width = width as usize)))))
2077 },
2078 (Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for function withzeros"))),
2079 (_, _) => Err(Error::Interp(String::from("no argument"))),
2080 }
2081}
2082
2083pub fn readline(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2085{
2086 if arg_values.len() != 0 {
2087 return Err(Error::Interp(String::from("invalid number of arguments")));
2088 }
2089 match env.stdin() {
2090 Input::Std => {
2091 let mut line = String::new();
2092 match stdin().read_line(&mut line) {
2093 Ok(_) => Ok(Value::Object(Arc::new(Object::String(line)))),
2094 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2095 }
2096 },
2097 Input::Null => Ok(Value::Object(Arc::new(Object::String(String::new())))),
2098 }
2099}
2100
2101pub fn format(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2103{
2104 let mut s = String::new();
2105 for arg_value in arg_values {
2106 s.push_str(format!("{}", arg_value).as_str());
2107 }
2108 Ok(Value::Object(Arc::new(Object::String(s))))
2109}
2110
2111pub fn print(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2113{
2114 match env.stdout() {
2115 Output::Std => {
2116 for arg_value in arg_values {
2117 print!("{}", arg_value);
2118 }
2119 },
2120 Output::Null => (),
2121 Output::Cursor(cursor) => {
2122 let mut cursor_g = rw_lock_write(cursor)?;
2123 for arg_value in arg_values {
2124 write!(&mut *cursor_g, "{}", arg_value).unwrap();
2125 }
2126 },
2127 }
2128 Ok(Value::None)
2129}
2130
2131pub fn println(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2133{
2134 match env.stdout() {
2135 Output::Std => {
2136 for arg_value in arg_values {
2137 print!("{}", arg_value);
2138 }
2139 println!("");
2140 },
2141 Output::Null => (),
2142 Output::Cursor(cursor) => {
2143 let mut cursor_g = rw_lock_write(cursor)?;
2144 for arg_value in arg_values {
2145 write!(&mut *cursor_g, "{}", arg_value).unwrap();
2146 }
2147 writeln!(&mut *cursor_g, "").unwrap();
2148 },
2149 }
2150 Ok(Value::None)
2151}
2152
2153pub fn eprint(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2155{
2156 match env.stderr() {
2157 Output::Std => {
2158 for arg_value in arg_values {
2159 eprint!("{}", arg_value);
2160 }
2161 },
2162 Output::Null => (),
2163 Output::Cursor(cursor) => {
2164 let mut cursor_g = rw_lock_write(cursor)?;
2165 for arg_value in arg_values {
2166 write!(&mut *cursor_g, "{}", arg_value).unwrap();
2167 }
2168 },
2169 }
2170 Ok(Value::None)
2171}
2172
2173pub fn eprintln(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2175{
2176 match env.stderr() {
2177 Output::Std => {
2178 for arg_value in arg_values {
2179 eprint!("{}", arg_value);
2180 }
2181 eprintln!("");
2182 },
2183 Output::Null => (),
2184 Output::Cursor(cursor) => {
2185 let mut cursor_g = rw_lock_write(cursor)?;
2186 for arg_value in arg_values {
2187 write!(&mut *cursor_g, "{}", arg_value).unwrap();
2188 }
2189 writeln!(&mut *cursor_g, "").unwrap();
2190 },
2191 }
2192 Ok(Value::None)
2193}
2194
2195pub fn flush(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2197{
2198 if arg_values.len() != 0 {
2199 return Err(Error::Interp(String::from("invalid number of arguments")));
2200 }
2201 match env.stdout() {
2202 Output::Std => {
2203 match stdout().flush() {
2204 Ok(()) => Ok(Value::Bool(true)),
2205 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2206 }
2207 },
2208 _ => Ok(Value::Bool(true)),
2209 }
2210}
2211
2212pub fn eflush(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2214{
2215 if arg_values.len() != 0 {
2216 return Err(Error::Interp(String::from("invalid number of arguments")));
2217 }
2218 match env.stderr() {
2219 Output::Std => {
2220 match stderr().flush() {
2221 Ok(()) => Ok(Value::Bool(true)),
2222 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2223 }
2224 },
2225 _ => Ok(Value::Bool(true)),
2226 }
2227}
2228
2229pub fn cd(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2231{
2232 if arg_values.len() != 1 {
2233 return Err(Error::Interp(String::from("invalid number of arguments")));
2234 }
2235 let new_dir_name = get_first_arg_string(arg_values, "unsupported type for function cd")?;
2236 let old_dir_name = match std::env::current_dir() {
2237 Ok(path) => path.to_string_lossy().into_owned(),
2238 Err(err) => return Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2239 };
2240 match std::env::set_current_dir(new_dir_name) {
2241 Ok(()) => Ok(Value::Object(Arc::new(Object::String(old_dir_name)))),
2242 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2243 }
2244}
2245
2246pub fn pwd(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2248{
2249 if arg_values.len() != 0 {
2250 return Err(Error::Interp(String::from("invalid number of arguments")));
2251 }
2252 match std::env::current_dir() {
2253 Ok(path) => Ok(Value::Object(Arc::new(Object::String(path.to_string_lossy().into_owned())))),
2254 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2255 }
2256}
2257
2258pub fn exist(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2260{
2261 if arg_values.len() != 1 {
2262 return Err(Error::Interp(String::from("invalid number of arguments")));
2263 }
2264 let file_name = get_first_arg_string(arg_values, "unsupported type for function exist")?;
2265 match fs::metadata(file_name.as_str()) {
2266 Ok(_) => Ok(Value::Bool(true)),
2267 Err(err) if err.kind() == ErrorKind::NotFound => Ok(Value::Bool(false)),
2268 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2269 }
2270}
2271
2272pub fn filetype(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2274{
2275 if arg_values.len() != 1 {
2276 return Err(Error::Interp(String::from("invalid number of arguments")));
2277 }
2278 let file_name = get_first_arg_string(arg_values, "unsupported type for function filetype")?;
2279 match fs::metadata(file_name.as_str()) {
2280 Ok(metadata) => {
2281 if metadata.is_dir() {
2282 Ok(Value::Object(Arc::new(Object::String(String::from("dir")))))
2283 } else {
2284 Ok(Value::Object(Arc::new(Object::String(String::from("file")))))
2285 }
2286 },
2287 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2288 }
2289}
2290
2291pub fn dir(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2293{
2294 if arg_values.len() != 1 {
2295 return Err(Error::Interp(String::from("invalid number of arguments")));
2296 }
2297 let dir_name = get_first_arg_string(arg_values, "unsupported type for function dir")?;
2298 match read_dir(dir_name.as_str()) {
2299 Ok(entries) => {
2300 let mut name_values: Vec<Value> = Vec::new();
2301 for entry in entries {
2302 match entry {
2303 Ok(entry) => name_values.push(Value::Object(Arc::new(Object::String(entry.file_name().to_string_lossy().into_owned())))),
2304 Err(err) => return Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2305 }
2306 }
2307 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(name_values)))))
2308 },
2309 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2310 }
2311}
2312
2313pub fn mkdir(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2315{
2316 if arg_values.len() != 1 {
2317 return Err(Error::Interp(String::from("invalid number of arguments")));
2318 }
2319 let dir_name = get_first_arg_string(arg_values, "unsupported type for function mkdir")?;
2320 match create_dir(dir_name.as_str()) {
2321 Ok(()) => Ok(Value::Bool(true)),
2322 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2323 }
2324}
2325
2326pub fn rmdir(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2328{
2329 if arg_values.len() != 1 {
2330 return Err(Error::Interp(String::from("invalid number of arguments")));
2331 }
2332 let dir_name = get_first_arg_string(arg_values, "unsupported type for function rmdir")?;
2333 match remove_dir(dir_name.as_str()) {
2334 Ok(()) => Ok(Value::Bool(true)),
2335 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2336 }
2337}
2338
2339pub fn rmfile(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2341{
2342 if arg_values.len() != 1 {
2343 return Err(Error::Interp(String::from("invalid number of arguments")));
2344 }
2345 let file_name = get_first_arg_string(arg_values, "unsupported type for function rmfile")?;
2346 match remove_file(file_name.as_str()) {
2347 Ok(()) => Ok(Value::Bool(true)),
2348 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2349 }
2350}
2351
2352pub fn copy(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2354{
2355 if arg_values.len() != 2 {
2356 return Err(Error::Interp(String::from("invalid number of arguments")));
2357 }
2358 let (src_file_name, dst_file_name) = match (arg_values.get(0), arg_values.get(1)) {
2359 (Some(src_file_name_value), Some(dst_file_name_value)) => {
2360 match (src_file_name_value.to_opt_string(), dst_file_name_value.to_opt_string()) {
2361 (Some(tmp_src_file_name), Some(tmp_dst_file_name)) => (tmp_src_file_name, tmp_dst_file_name),
2362 (_, _) => return Err(Error::Interp(String::from("unsupported types for function copy"))),
2363 }
2364 },
2365 (_, _) => return Err(Error::Interp(String::from("no argument"))),
2366 };
2367 match fs::copy(src_file_name.as_str(), dst_file_name.as_str()) {
2368 Ok(_) => Ok(Value::Bool(true)),
2369 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2370 }
2371}
2372
2373pub fn rename(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2375{
2376 if arg_values.len() != 2 {
2377 return Err(Error::Interp(String::from("invalid number of arguments")));
2378 }
2379 let (src_file_name, dst_file_name) = match (arg_values.get(0), arg_values.get(1)) {
2380 (Some(src_file_name_value), Some(dst_file_name_value)) => {
2381 match (src_file_name_value.to_opt_string(), dst_file_name_value.to_opt_string()) {
2382 (Some(tmp_src_file_name), Some(tmp_dst_file_name)) => (tmp_src_file_name, tmp_dst_file_name),
2383 (_, _) => return Err(Error::Interp(String::from("unsupported types for function rename"))),
2384 }
2385 },
2386 (_, _) => return Err(Error::Interp(String::from("no argument"))),
2387 };
2388 match fs::rename(src_file_name.as_str(), dst_file_name.as_str()) {
2389 Ok(_) => Ok(Value::Bool(true)),
2390 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2391 }
2392}
2393
2394pub fn spawn(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2396{
2397 if arg_values.len() < 1 {
2398 return Err(Error::Interp(String::from("invalid number of arguments")));
2399 }
2400 let cmd_name = get_first_arg_string(arg_values, "unsupported type for function spawn")?;
2401 let mut cmd_args: Vec<String> = Vec::new();
2402 for arg_value in &arg_values[1..] {
2403 cmd_args.push(format!("{}", arg_value));
2404 }
2405 match Command::new(cmd_name).args(cmd_args).spawn() {
2406 Ok(mut child) => {
2407 match child.wait() {
2408 Ok(exit_status) => {
2409 match exit_status.code() {
2410 Some(code) => Ok(Value::Int(code as i64)),
2411 None => Ok(Value::Object(Arc::new(Object::Error(String::from("exitstatus"), String::from("process terminated by signal"))))),
2412 }
2413 },
2414 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2415 }
2416 },
2417 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2418 }
2419}
2420
2421pub fn exit(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2423{
2424 if arg_values.len() != 1 {
2425 return Err(Error::Interp(String::from("invalid number of arguments")));
2426 }
2427 match arg_values.get(0) {
2428 Some(value @ (Value::Int(_) | Value::Float(_))) => Err(Error::Stop(Stop::Exit(value.to_i64() as i32))),
2429 Some(_) => Err(Error::Interp(String::from("unsupported type for fuction exit"))),
2430 None => Err(Error::Interp(String::from("no argument"))),
2431 }
2432}
2433
2434pub fn load(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2436{
2437 if arg_values.len() != 1 {
2438 return Err(Error::Interp(String::from("invalid number of arguments")));
2439 }
2440 let file_name = get_first_arg_string(arg_values, "unsupported type for function load")?;
2441 match load_values(file_name.as_str(), env) {
2442 Ok(values) => Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(values))))),
2443 Err(Error::Io(err)) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2444 Err(err) => Err(err),
2445 }
2446}
2447
2448pub fn save(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2450{
2451 if arg_values.len() < 1 {
2452 return Err(Error::Interp(String::from("invalid number of arguments")));
2453 }
2454 let file_name = get_first_arg_string(arg_values, "unsupported type for function save")?;
2455 match save_values(file_name.as_str(), &arg_values[1..]) {
2456 Ok(()) => Ok(Value::Bool(true)),
2457 Err(Error::Io(err)) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2458 Err(err) => Err(err),
2459 }
2460}
2461
2462pub fn loadstr(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2464{
2465 if arg_values.len() != 1 {
2466 return Err(Error::Interp(String::from("invalid number of arguments")));
2467 }
2468 let file_name = get_first_arg_string(arg_values, "unsupported type for function loadstr")?;
2469 match File::open(file_name.as_str()) {
2470 Ok(mut file) => {
2471 let mut s = String::new();
2472 match file.read_to_string(&mut s) {
2473 Ok(_) => Ok(Value::Object(Arc::new(Object::String(s)))),
2474 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2475 }
2476 },
2477 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2478 }
2479}
2480
2481pub fn savestr(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2483{
2484 if arg_values.len() != 2 {
2485 return Err(Error::Interp(String::from("invalid number of arguments")));
2486 }
2487 let (file_name, str_value) = match (arg_values.get(0), arg_values.get(1)) {
2488 (Some(file_name_value), Some(str_value)) => {
2489 match file_name_value.to_opt_string() {
2490 Some(tmp_file_name) => (tmp_file_name, str_value.clone()),
2491 None => return Err(Error::Interp(String::from("unsupported type for function savestr"))),
2492 }
2493 },
2494 (_, _) => return Err(Error::Interp(String::from("no argument"))),
2495 };
2496 match File::create(file_name.as_str()) {
2497 Ok(file) => {
2498 let mut w = BufWriter::new(file);
2499 match write!(&mut w, "{}", str_value) {
2500 Ok(()) => Ok(Value::Bool(true)),
2501 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2502 }
2503 },
2504 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2505 }
2506}
2507
2508pub fn loadtoml(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2510{
2511 if arg_values.len() != 1 {
2512 return Err(Error::Interp(String::from("invalid number of arguments")));
2513 }
2514 let file_name = get_first_arg_string(arg_values, "unsupported type for function loadtoml")?;
2515 match File::open(file_name.as_str()) {
2516 Ok(mut file) => {
2517 let mut s = String::new();
2518 match file.read_to_string(&mut s) {
2519 Ok(_) => {
2520 match toml::from_str(s.as_str()) {
2521 Ok(value) => Ok(value),
2522 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("toml"), format!("{}", err))))),
2523 }
2524 },
2525 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2526 }
2527 },
2528 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2529 }
2530}
2531
2532pub fn savetoml(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2534{
2535 if arg_values.len() != 2 {
2536 return Err(Error::Interp(String::from("invalid number of arguments")));
2537 }
2538 let (file_name, value) = match (arg_values.get(0), arg_values.get(1)) {
2539 (Some(file_name_value), Some(value)) => {
2540 match file_name_value.to_opt_string() {
2541 Some(tmp_file_name) => (tmp_file_name, value),
2542 None => return Err(Error::Interp(String::from("unsupported type for function savetoml"))),
2543 }
2544 },
2545 (_, _) => return Err(Error::Interp(String::from("no argument"))),
2546 };
2547 match toml::to_string(&value) {
2548 Ok(s) => {
2549 match File::create(file_name.as_str()) {
2550 Ok(file) => {
2551 let mut w = BufWriter::new(file);
2552 match write!(&mut w, "{}", s) {
2553 Ok(()) => Ok(Value::Bool(true)),
2554 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2555 }
2556 },
2557 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2558 }
2559 },
2560 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("toml"), format!("{}", err))))),
2561 }
2562}
2563
2564pub fn loadjson(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2566{
2567 if arg_values.len() != 1 {
2568 return Err(Error::Interp(String::from("invalid number of arguments")));
2569 }
2570 let file_name = get_first_arg_string(arg_values, "unsupported type for function loadjson")?;
2571 match File::open(file_name.as_str()) {
2572 Ok(mut file) => {
2573 let mut s = String::new();
2574 match file.read_to_string(&mut s) {
2575 Ok(_) => {
2576 match serde_json::from_str(s.as_str()) {
2577 Ok(value) => Ok(value),
2578 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("json"), format!("{}", err))))),
2579 }
2580 },
2581 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2582 }
2583 },
2584 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2585 }
2586}
2587
2588pub fn savejson(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2590{
2591 if arg_values.len() != 2 {
2592 return Err(Error::Interp(String::from("invalid number of arguments")));
2593 }
2594 let (file_name, value) = match (arg_values.get(0), arg_values.get(1)) {
2595 (Some(file_name_value), Some(value)) => {
2596 match file_name_value.to_opt_string() {
2597 Some(tmp_file_name) => (tmp_file_name, value),
2598 None => return Err(Error::Interp(String::from("unsupported type for function savejson"))),
2599 }
2600 },
2601 (_, _) => return Err(Error::Interp(String::from("no argument"))),
2602 };
2603 match serde_json::to_string(&value) {
2604 Ok(s) => {
2605 match File::create(file_name.as_str()) {
2606 Ok(file) => {
2607 let mut w = BufWriter::new(file);
2608 match write!(&mut w, "{}", s) {
2609 Ok(()) => Ok(Value::Bool(true)),
2610 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2611 }
2612 },
2613 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("io"), format!("{}", err))))),
2614 }
2615 },
2616 Err(err) => Ok(Value::Object(Arc::new(Object::Error(String::from("json"), format!("{}", err))))),
2617 }
2618}
2619
2620pub fn args(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2622{
2623 if arg_values.len() != 0 {
2624 return Err(Error::Interp(String::from("invalid number of arguments")));
2625 }
2626 let shared_env_g = rw_lock_read(env.shared_env())?;
2627 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(shared_env_g.args().iter().map(|s| Value::Object(Arc::new(Object::String(s.clone())))).collect())))))
2628}
2629
2630pub fn env(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
2632{
2633 if arg_values.len() != 0 {
2634 return Err(Error::Interp(String::from("invalid number of arguments")));
2635 }
2636 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(std::env::vars_os().map(|p| Value::Object(Arc::new(Object::String(format!("{}={}", p.0.to_string_lossy().into_owned(), p.1.to_string_lossy().into_owned()))))).collect())))))
2637}
2638
2639pub fn scriptdir(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2641{
2642 if arg_values.len() != 0 {
2643 return Err(Error::Interp(String::from("invalid number of arguments")));
2644 }
2645 Ok(Value::Object(Arc::new(Object::String(env.script_dir().to_string_lossy().into_owned()))))
2646}
2647
2648pub fn libpath(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2650{
2651 if arg_values.len() != 0 {
2652 return Err(Error::Interp(String::from("invalid number of arguments")));
2653 }
2654 let shared_env_g = rw_lock_read(env.shared_env())?;
2655 Ok(Value::Object(Arc::new(Object::String(shared_env_g.lib_path().to_string_lossy().into_owned()))))
2656}
2657
2658pub fn domain(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2660{
2661 if arg_values.len() != 0 {
2662 return Err(Error::Interp(String::from("invalid number of arguments")));
2663 }
2664 match env.domain() {
2665 Some(domain) => Ok(Value::Object(Arc::new(Object::String(String::from(domain))))),
2666 None => Ok(Value::None),
2667 }
2668}
2669
2670fn name_with_domain(name: &str, env: &Env) -> Result<String>
2671{
2672 if name.contains('/') {
2673 Ok(String::from(name))
2674 } else {
2675 match env.domain() {
2676 Some(domain) => {
2677 let mut new_name = String::from(domain);
2678 new_name.push('/');
2679 new_name.push_str(name);
2680 Ok(new_name)
2681 },
2682 None => Err(Error::Interp(String::from("name library without domain"))),
2683 }
2684 }
2685}
2686
2687fn domain_from_name(name: &str) -> Result<String>
2688{
2689 match name.split_once('/') {
2690 Some((domain, _)) => Ok(String::from(domain)),
2691 None => Err(Error::Interp(String::from("name library without domain"))),
2692 }
2693}
2694
2695fn use_lib(interp: &mut Interp, env: &mut Env, lib_name: &str) -> Result<()>
2696{
2697 let domain = domain_from_name(lib_name)?;
2698 let lib_path = {
2699 let shared_env_g = rw_lock_read(env.shared_env())?;
2700 OsString::from(shared_env_g.lib_path())
2701 };
2702 let mut res: Result<()> = Ok(());
2703 for dir in std::env::split_paths(lib_path.as_os_str()) {
2704 let mut script_dir = dir.clone();
2705 script_dir.push(lib_name.replace('/', path::MAIN_SEPARATOR_STR));
2706 let mut path = script_dir.clone();
2707 path.push("lib.un");
2708 match parse(path) {
2709 Ok(tree) => {
2710 let mut new_env = Env::new_with_script_dir_and_domain_and_shared_env(env.root_mod().clone(), script_dir.clone(), Some(domain), env.shared_env().clone());
2711 new_env.set_stdin(*env.stdin());
2712 new_env.set_stdout(env.stdout().clone());
2713 new_env.set_stderr(env.stderr().clone());
2714 interp.interpret(&mut new_env, &tree)?;
2715 {
2716 let mut shared_env_g = rw_lock_write(env.shared_env())?;
2717 shared_env_g.add_used_lib(String::from(lib_name));
2718 }
2719 return Ok(());
2720 },
2721 Err(Error::ParserIo(path, err)) if err.kind() == ErrorKind::NotFound => res = Err(Error::ParserIo(path, err)),
2722 Err(err) => return Err(err),
2723 }
2724 }
2725 res
2726}
2727
2728pub fn uselib(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2730{
2731 if arg_values.len() != 1 {
2732 return Err(Error::Interp(String::from("invalid number of arguments")));
2733 }
2734 let lib_name = get_first_arg_string(arg_values, "unsupported type for function uselib")?;
2735 let lib_name = name_with_domain(lib_name.as_str(), env)?;
2736 let is_used_lib = {
2737 let shared_env_g = rw_lock_read(env.shared_env())?;
2738 shared_env_g.has_used_lib(&lib_name)
2739 };
2740 if !is_used_lib {
2741 use_lib(interp, env, lib_name.as_str())?;
2742 }
2743 Ok(Value::None)
2744}
2745
2746pub fn reuselib(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2748{
2749 if arg_values.len() != 1 {
2750 return Err(Error::Interp(String::from("invalid number of arguments")));
2751 }
2752 let lib_name = get_first_arg_string(arg_values, "unsupported type for function reuselib")?;
2753 let lib_name = name_with_domain(lib_name.as_str(), env)?;
2754 use_lib(interp, env, lib_name.as_str())?;
2755 Ok(Value::None)
2756}
2757
2758pub fn run(interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2760{
2761 if arg_values.len() != 1 {
2762 return Err(Error::Interp(String::from("invalid number of arguments")));
2763 }
2764 let script_name = get_first_arg_string(arg_values, "unsupported type for function run")?;
2765 let mut path_buf = PathBuf::from(env.script_dir());
2766 path_buf.push(script_name.replace('/', path::MAIN_SEPARATOR_STR).as_str());
2767 let tree = parse(path_buf)?;
2768 let mut new_env = env.clone_without_stack();
2769 interp.interpret(&mut new_env, &tree)?;
2770 Ok(Value::None)
2771}
2772
2773pub fn clock(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2775{
2776 if arg_values.len() != 0 {
2777 return Err(Error::Interp(String::from("invalid number of arguments")));
2778 }
2779 let shared_env_g = rw_lock_read(env.shared_env())?;
2780 Ok(Value::Int(shared_env_g.instant().elapsed().as_millis() as i64))
2781}
2782
2783fn mod_pair_for_name(env: &Env, name: &str, is_var: bool) -> Result<(Arc<RwLock<ModNode<Value, ()>>>, Vec<String>)>
2784{
2785 let name_without_first_colons = if name.starts_with("::") {
2786 &name[2..]
2787 } else {
2788 name
2789 };
2790 let idents: Vec<String> = name_without_first_colons.split("::").map(String::from).collect();
2791 let end = if is_var {
2792 idents.len().saturating_sub(1)
2793 } else {
2794 idents.len()
2795 };
2796 match idents.first() {
2797 Some(ident) if ident == &String::from("root") => {
2798 match ModNode::mod_from(env.root_mod(), &idents[1..cmp::max(end, 1)], false)? {
2799 Some(mod1) => Ok((mod1, (&idents[1..]).to_vec())),
2800 None => Err(Error::Interp(String::from("undefined module"))),
2801 }
2802 },
2803 _ => {
2804 match ModNode::mod_from(env.current_mod(), &idents[0..end], true)? {
2805 Some(mod1) => Ok((mod1, idents)),
2806 None => {
2807 match ModNode::mod_from(env.root_mod(), &idents[0..end], false)? {
2808 Some(mod1) => Ok((mod1, idents)),
2809 None => Err(Error::Interp(String::from("undefined module"))),
2810 }
2811 },
2812 }
2813 },
2814 }
2815}
2816
2817pub fn usemod(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2819{
2820 if arg_values.len() < 1 || arg_values.len() > 2 {
2821 return Err(Error::Interp(String::from("invalid number of arguments")));
2822 }
2823 match arg_values.get(0) {
2824 Some(Value::Object(object)) => {
2825 match &**object {
2826 Object::String(name) => {
2827 let (used_mod, idents) = mod_pair_for_name(env, name, false)?;
2828 let ident = match arg_values.get(1) {
2829 Some(Value::Object(object)) => {
2830 match &**object {
2831 Object::String(tmp_ident) => tmp_ident.clone(),
2832 _ => return Err(Error::Interp(String::from("unsupported types for function usemod"))),
2833 }
2834 },
2835 Some(_) => return Err(Error::Interp(String::from("unsupported types for function usemod"))),
2836 None => {
2837 match idents.last() {
2838 Some(tmp_ident) => tmp_ident.clone(),
2839 None => return Err(Error::Interp(String::from("no last identifier"))),
2840 }
2841 },
2842 };
2843 ModNode::add_used_mod(env.current_mod(), ident, used_mod)?;
2844 Ok(Value::None)
2845 },
2846 _ => Err(Error::Interp(String::from("unsupported types for function usemod"))),
2847 }
2848 },
2849 Some(_) => Err(Error::Interp(String::from("unsupported types for function usemod"))),
2850 None => Err(Error::Interp(String::from("no argument"))),
2851 }
2852}
2853
2854pub fn usemods(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2856{
2857 if arg_values.len() != 1 {
2858 return Err(Error::Interp(String::from("invalid number of arguments")));
2859 }
2860 match arg_values.get(0) {
2861 Some(Value::Object(object)) => {
2862 match &**object {
2863 Object::String(name) => {
2864 let mod1 = mod_pair_for_name(env, name, false)?.0;
2865 let used_mods: Vec<(String, Arc<RwLock<ModNode<Value, ()>>>)> = {
2866 let mod_g = rw_lock_read(&mod1)?;
2867 mod_g.mods().iter().map(|p| (p.0.clone(), p.1.clone())).collect()
2868 };
2869 for (ident, used_mod) in &used_mods {
2870 ModNode::add_used_mod(env.current_mod(), ident.clone(), used_mod.clone())?;
2871 }
2872 Ok(Value::None)
2873 },
2874 _ => Err(Error::Interp(String::from("unsupported type for function usemods"))),
2875 }
2876 },
2877 Some(_) => Err(Error::Interp(String::from("unsupported type for function usemods"))),
2878 None => Err(Error::Interp(String::from("no argument"))),
2879 }
2880}
2881
2882pub fn usevar(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2884{
2885 if arg_values.len() < 1 || arg_values.len() > 2 {
2886 return Err(Error::Interp(String::from("invalid number of arguments")));
2887 }
2888 match arg_values.get(0) {
2889 Some(Value::Object(object)) => {
2890 match &**object {
2891 Object::String(name) => {
2892 let (used_var_mod, idents) = mod_pair_for_name(env, name, true)?;
2893 let (ident, used_var_ident) = match arg_values.get(1) {
2894 Some(Value::Object(object)) => {
2895 match &**object {
2896 Object::String(tmp_ident) => {
2897 match idents.last() {
2898 Some(tmp_used_var_ident) => (tmp_ident.clone(), tmp_used_var_ident.clone()),
2899 None => return Err(Error::Interp(String::from("no last identifier"))),
2900 }
2901 },
2902 _ => return Err(Error::Interp(String::from("unsupported types for function usevar"))),
2903 }
2904 },
2905 Some(_) => return Err(Error::Interp(String::from("unsupported types for function usevar"))),
2906 None => {
2907 match idents.last() {
2908 Some(tmp_used_var_ident) => (tmp_used_var_ident.clone(), tmp_used_var_ident.clone()),
2909 None => return Err(Error::Interp(String::from("no last identifier"))),
2910 }
2911 },
2912 };
2913 {
2914 let used_var_mod_g = rw_lock_read(&used_var_mod)?;
2915 if !used_var_mod_g.has_var(&used_var_ident) {
2916 return Err(Error::Interp(String::from("undefined variable")));
2917 }
2918 }
2919 ModNode::add_used_var(env.current_mod(), ident.clone(), used_var_mod, used_var_ident)?;
2920 Ok(Value::None)
2921 },
2922 _ => Err(Error::Interp(String::from("unsupported types for function usevar"))),
2923 }
2924 },
2925 Some(_) => Err(Error::Interp(String::from("unsupported types for function usevar"))),
2926 None => Err(Error::Interp(String::from("no argument"))),
2927 }
2928}
2929
2930pub fn usevars(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2932{
2933 if arg_values.len() != 1 {
2934 return Err(Error::Interp(String::from("invalid number of arguments")));
2935 }
2936 match arg_values.get(0) {
2937 Some(Value::Object(object)) => {
2938 match &**object {
2939 Object::String(name) => {
2940 let used_var_mod = mod_pair_for_name(env, name, false)?.0;
2941 let used_var_idents: Vec<String> = {
2942 let used_var_mod_g = rw_lock_read(&used_var_mod)?;
2943 used_var_mod_g.vars().keys().map(|s| s.clone()).collect()
2944 };
2945 for used_var_ident in &used_var_idents {
2946 ModNode::add_used_var(env.current_mod(), used_var_ident.clone(), used_var_mod.clone(), used_var_ident.clone())?;
2947 }
2948 Ok(Value::None)
2949 },
2950 _ => Err(Error::Interp(String::from("unsupported type for function usevars"))),
2951 }
2952 },
2953 Some(_) => Err(Error::Interp(String::from("unsupported type for function usevars"))),
2954 None => Err(Error::Interp(String::from("no argument"))),
2955 }
2956}
2957
2958pub fn removeusemod(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2960{
2961 if arg_values.len() != 1 {
2962 return Err(Error::Interp(String::from("invalid number of arguments")));
2963 }
2964 match arg_values.get(0) {
2965 Some(Value::Object(object)) => {
2966 match &**object {
2967 Object::String(ident) => {
2968 let mut current_mod_g = rw_lock_write(env.current_mod())?;
2969 current_mod_g.remove_used_mod(ident);
2970 Ok(Value::None)
2971 },
2972 _ => Err(Error::Interp(String::from("unsupported type for function removeusemod"))),
2973 }
2974 },
2975 Some(_) => Err(Error::Interp(String::from("unsupported type for function removeusemod"))),
2976 None => Err(Error::Interp(String::from("no argument"))),
2977 }
2978}
2979
2980pub fn removeusevar(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
2982{
2983 if arg_values.len() != 1 {
2984 return Err(Error::Interp(String::from("invalid number of arguments")));
2985 }
2986 match arg_values.get(0) {
2987 Some(Value::Object(object)) => {
2988 match &**object {
2989 Object::String(ident) => {
2990 let mut current_mod_g = rw_lock_write(env.current_mod())?;
2991 current_mod_g.remove_used_var(ident);
2992 Ok(Value::None)
2993 },
2994 _ => Err(Error::Interp(String::from("unsupported type for function removeusevar"))),
2995 }
2996 },
2997 Some(_) => Err(Error::Interp(String::from("unsupported type for function removeusevar"))),
2998 None => Err(Error::Interp(String::from("no argument"))),
2999 }
3000}
3001
3002pub fn removemod(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
3004{
3005 if arg_values.len() != 1 {
3006 return Err(Error::Interp(String::from("invalid number of arguments")));
3007 }
3008 match arg_values.get(0) {
3009 Some(Value::Object(object)) => {
3010 match &**object {
3011 Object::String(ident) => {
3012 let mut current_mod_g = rw_lock_write(env.current_mod())?;
3013 current_mod_g.remove_mod(ident)?;
3014 Ok(Value::None)
3015 },
3016 _ => Err(Error::Interp(String::from("unsupported type for function removemod"))),
3017 }
3018 },
3019 Some(_) => Err(Error::Interp(String::from("unsupported type for function removemod"))),
3020 None => Err(Error::Interp(String::from("no argument"))),
3021 }
3022}
3023
3024pub fn removevar(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
3026{
3027 if arg_values.len() != 1 {
3028 return Err(Error::Interp(String::from("invalid number of arguments")));
3029 }
3030 match arg_values.get(0) {
3031 Some(Value::Object(object)) => {
3032 match &**object {
3033 Object::String(ident) => {
3034 let mut current_mod_g = rw_lock_write(env.current_mod())?;
3035 current_mod_g.remove_var(ident);
3036 Ok(Value::None)
3037 },
3038 _ => Err(Error::Interp(String::from("unsupported type for function removevar"))),
3039 }
3040 },
3041 Some(_) => Err(Error::Interp(String::from("unsupported type for function removevar"))),
3042 None => Err(Error::Interp(String::from("no argument"))),
3043 }
3044}
3045
3046pub fn removelocalvar(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
3048{
3049 if arg_values.len() != 1 {
3050 return Err(Error::Interp(String::from("invalid number of arguments")));
3051 }
3052 match arg_values.get(0) {
3053 Some(Value::Object(object)) => {
3054 match &**object {
3055 Object::String(ident) => Ok(Value::Bool(env.remove_local_var(ident))),
3056 _ => Err(Error::Interp(String::from("unsupported type for function removelocalvar"))),
3057 }
3058 },
3059 Some(_) => Err(Error::Interp(String::from("unsupported type for function removelocalvar"))),
3060 None => Err(Error::Interp(String::from("no argument"))),
3061 }
3062}
3063
3064pub fn checkintr(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
3066{
3067 if arg_values.len() != 0 {
3068 return Err(Error::Interp(String::from("invalid number of arguments")));
3069 }
3070 let intr_checker = {
3071 let shared_env_g = rw_lock_read(env.shared_env())?;
3072 shared_env_g.intr_checker().clone()
3073 };
3074 intr_checker.check()?;
3075 Ok(Value::None)
3076}
3077
3078pub fn backend(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
3080{
3081 if arg_values.len() != 0 {
3082 return Err(Error::Interp(String::from("invalid number of arguments")));
3083 }
3084 Ok(Value::Object(Arc::new(Object::String(String::from(matrix_backend_name()?)))))
3085}
3086
3087pub fn version(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
3089{
3090 if arg_values.len() != 0 {
3091 return Err(Error::Interp(String::from("invalid number of arguments")));
3092 }
3093 Ok(Value::Object(Arc::new(Object::String(String::from(env!("CARGO_PKG_VERSION"))))))
3094}
3095
3096pub fn reqver(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
3098{
3099 if arg_values.len() != 1 {
3100 return Err(Error::Interp(String::from("invalid number of arguments")));
3101 }
3102 match arg_values.get(0) {
3103 Some(Value::Object(object)) => {
3104 match &**object {
3105 Object::String(s) => {
3106 let version = Version::parse(env!("CARGO_PKG_VERSION"))?;
3107 let version_req = VersionReq::parse(s.as_str())?;
3108 if version_req.matches(&version) {
3109 Ok(Value::None)
3110 } else {
3111 Err(Error::Interp(format!("unlab-gpu version {} isn't matched to version requirement {}", version, version_req)))
3112 }
3113 },
3114 _ => Err(Error::Interp(String::from("unsupported type for function reqver"))),
3115 }
3116 },
3117 Some(_) => Err(Error::Interp(String::from("unsupported type for function reqver"))),
3118 None => Err(Error::Interp(String::from("no argument"))),
3119 }
3120}
3121
3122
3123pub fn docpath(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
3125{
3126 if arg_values.len() != 0 {
3127 return Err(Error::Interp(String::from("invalid number of arguments")));
3128 }
3129 let shared_env_g = rw_lock_read(env.shared_env())?;
3130 Ok(Value::Object(Arc::new(Object::String(shared_env_g.doc_path().to_string_lossy().into_owned()))))
3131}
3132
3133pub fn doc(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
3135{
3136 if arg_values.len() > 2 {
3137 return Err(Error::Interp(String::from("invalid number of arguments")));
3138 }
3139 let lib_name = match arg_values.get(0) {
3140 Some(arg_value) => {
3141 match arg_value.to_opt_string() {
3142 Some(tmp_lib_name) => tmp_lib_name,
3143 None => return Err(Error::Interp(String::from("unsupported types for function doc"))),
3144 }
3145 },
3146 None => String::from("std/root"),
3147 };
3148 let idents = match arg_values.get(1) {
3149 Some(arg_value) => {
3150 match arg_value.to_opt_string() {
3151 Some(name) => {
3152 let name_without_first_colons = if name.starts_with("::") {
3153 &name[2..]
3154 } else {
3155 name.as_str()
3156 };
3157 let tmp_idents: Vec<String> = name_without_first_colons.split("::").map(String::from).collect();
3158 match tmp_idents.first() {
3159 Some(tmp_ident) if tmp_ident == &String::from("root") => Some((&tmp_idents[1..]).to_vec()),
3160 Some(_) => Some(tmp_idents),
3161 None => Some(Vec::new()),
3162 }
3163 },
3164 None => return Err(Error::Interp(String::from("unsupported types for function doc"))),
3165 }
3166 },
3167 None => None,
3168 };
3169 let doc_path = {
3170 let shared_env_g = rw_lock_read(env.shared_env())?;
3171 OsString::from(shared_env_g.doc_path())
3172 };
3173 let mut res: Result<Value> = Ok(Value::None);
3174 for dir in std::env::split_paths(doc_path.as_os_str()) {
3175 let mut path = dir.clone();
3176 path.push(lib_name.replace('/', path::MAIN_SEPARATOR_STR));
3177 match &idents {
3178 Some(idents) => {
3179 path.push("root");
3180 for ident in idents {
3181 path.push(ident);
3182 }
3183 path.set_extension("html");
3184 },
3185 None => path.push("index.html"),
3186 }
3187 match fs::metadata(path.as_path()) {
3188 Ok(_) => {
3189 let canon_path = match path.canonicalize() {
3190 Ok(tmp_canon_path) => tmp_canon_path,
3191 Err(err) => return Err(Error::Io(err)),
3192 };
3193 match open_browser(canon_path) {
3194 Ok(()) => return Ok(Value::None),
3195 Err(err) => return Err(Error::Opener(Box::new(err))),
3196 }
3197 },
3198 Err(err) if err.kind() == ErrorKind::NotFound => res = Err(Error::Io(err)),
3199 Err(err) => return Err(Error::Io(err)),
3200 }
3201 }
3202 res
3203}
3204
3205fn assert_op<F>(arg_values: &[Value], default_msg: Option<&str>, pair: Option<(Value, Value)>, f: F) -> Result<Value>
3206 where F: FnOnce() -> Result<bool>
3207{
3208 if !f()? {
3209 let msg = if !arg_values.is_empty() {
3210 let mut s = String::new();
3211 for arg_value in arg_values {
3212 s.push_str(format!("{}", arg_value).as_str());
3213 }
3214 Some(s)
3215 } else {
3216 match default_msg {
3217 Some(s) => Some(String::from(s)),
3218 None => None,
3219 }
3220 };
3221 return Err(Error::Assert(msg, pair));
3222 }
3223 Ok(Value::None)
3224}
3225
3226pub fn assert(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
3228{
3229 if arg_values.len() < 1 {
3230 return Err(Error::Interp(String::from("invalid number of arguments")));
3231 }
3232 match arg_values.get(0) {
3233 Some(Value::Bool(b)) => assert_op(&arg_values[1..], None, None, || Ok(*b)),
3234 Some(_) => Err(Error::Interp(String::from("unsupported type for fuction assert"))),
3235 None => Err(Error::Interp(String::from("no argument"))),
3236 }
3237}
3238
3239pub fn asserteq(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
3241{
3242 if arg_values.len() < 2 {
3243 return Err(Error::Interp(String::from("invalid number of arguments")));
3244 }
3245 match (arg_values.get(0), arg_values.get(1)) {
3246 (Some(value), Some(value2)) => assert_op(&arg_values[2..], Some("left isn't equal to right"), Some((value.clone(), value2.clone())), || value.eq_without_types(&value2)),
3247 _ => Err(Error::Interp(String::from("no argument"))),
3248 }
3249}
3250
3251pub fn assertne(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
3253{
3254 if arg_values.len() < 2 {
3255 return Err(Error::Interp(String::from("invalid number of arguments")));
3256 }
3257 match (arg_values.get(0), arg_values.get(1)) {
3258 (Some(value), Some(value2)) => assert_op(&arg_values[2..], Some("left is equal to right"), Some((value.clone(), value2.clone())), || Ok(!value.eq_without_types(&value2)?)),
3259 _ => Err(Error::Interp(String::from("no argument"))),
3260 }
3261}
3262
3263pub fn assertnearlyeq(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
3265{
3266 if arg_values.len() < 3 {
3267 return Err(Error::Interp(String::from("invalid number of arguments")));
3268 }
3269 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
3270 (Some(value), Some(value2), Some(eps_value @ (Value::Int(_) | Value::Float(_)))) => {
3271 let eps = eps_value.to_f32();
3272 assert_op(&arg_values[3..], Some("left isn't nearly equal to right"), Some((value.clone(), value2.clone())), || value.nearly_eq_without_types(&value2, eps))
3273 },
3274 (Some(_), Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for fuction assertnearlyeq"))),
3275 _ => Err(Error::Interp(String::from("no argument"))),
3276 }
3277}
3278
3279pub fn assertnearlyne(_interp: &mut Interp, _env: &mut Env, arg_values: &[Value]) -> Result<Value>
3281{
3282 if arg_values.len() < 3 {
3283 return Err(Error::Interp(String::from("invalid number of arguments")));
3284 }
3285 match (arg_values.get(0), arg_values.get(1), arg_values.get(2)) {
3286 (Some(value), Some(value2), Some(eps_value @ (Value::Int(_) | Value::Float(_)))) => {
3287 let eps = eps_value.to_f32();
3288 assert_op(&arg_values[3..], Some("left is nearly equal to right"), Some((value.clone(), value2.clone())), || Ok(!value.nearly_eq_without_types(&value2, eps)?))
3289 },
3290 (Some(_), Some(_), Some(_)) => Err(Error::Interp(String::from("unsupported types for fuction assertnearlyne"))),
3291 _ => Err(Error::Interp(String::from("no argument"))),
3292 }
3293}
3294
3295pub fn tests(_interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
3297{
3298 if arg_values.len() != 0 {
3299 return Err(Error::Interp(String::from("invalid number of arguments")));
3300 }
3301 let mut shared_env_g = rw_lock_write(env.shared_env())?;
3302 shared_env_g.add_test_suite(env.mod_idents().to_vec());
3303 Ok(Value::None)
3304}
3305
3306pub fn add_builtin_fun(root_mod: &mut ModNode<Value, ()>, ident: String, f: fn(&mut Interp, &mut Env, &[Value]) -> Result<Value>)
3308{ root_mod.add_var(ident.clone(), Value::Object(Arc::new(Object::BuiltinFun(ident, f)))) }
3309
3310pub fn add_alias(root_mod: &mut ModNode<Value, ()>, new_ident: String, old_ident: &String)
3312{
3313 match root_mod.var(old_ident) {
3314 Some(value) => root_mod.add_var(new_ident, value.clone()),
3315 None => (),
3316 }
3317}
3318
3319pub fn add_std_builtin_funs(root_mod: &mut ModNode<Value, ()>)
3321{
3322 root_mod.add_var(String::from("pi"), Value::Float(f32::consts::PI));
3323 root_mod.add_var(String::from("e"), Value::Float(f32::consts::E));
3324 root_mod.add_var(String::from("eps"), Value::Float(f32::EPSILON));
3325 root_mod.add_var(String::from("pathsep"), Value::Object(Arc::new(Object::String(format!("{}", path::MAIN_SEPARATOR)))));
3326 add_builtin_fun(root_mod, String::from("type"), typ);
3327 add_builtin_fun(root_mod, String::from("clone"), clone);
3328 add_builtin_fun(root_mod, String::from("bool"), boolean);
3329 add_builtin_fun(root_mod, String::from("int"), int);
3330 add_builtin_fun(root_mod, String::from("float"), float);
3331 add_builtin_fun(root_mod, String::from("string"), string);
3332 add_builtin_fun(root_mod, String::from("zeros"), zeros);
3333 add_builtin_fun(root_mod, String::from("ones"), ones);
3334 add_builtin_fun(root_mod, String::from("eye"), eye);
3335 add_builtin_fun(root_mod, String::from("init"), init);
3336 add_builtin_fun(root_mod, String::from("initdiag"), initdiag);
3337 add_builtin_fun(root_mod, String::from("matrix"), matrix);
3338 add_builtin_fun(root_mod, String::from("rowvector"), rowvector);
3339 add_builtin_fun(root_mod, String::from("colvector"), colvector);
3340 add_builtin_fun(root_mod, String::from("matrixarray"), matrixarray);
3341 add_builtin_fun(root_mod, String::from("error"), error);
3342 add_builtin_fun(root_mod, String::from("array"), array);
3343 add_builtin_fun(root_mod, String::from("strong"), strong);
3344 add_builtin_fun(root_mod, String::from("weak"), weak);
3345 add_builtin_fun(root_mod, String::from("isempty"), isempty);
3346 add_builtin_fun(root_mod, String::from("length"), length);
3347 add_builtin_fun(root_mod, String::from("rows"), rows);
3348 add_builtin_fun(root_mod, String::from("columns"), columns);
3349 add_builtin_fun(root_mod, String::from("get"), get);
3350 add_builtin_fun(root_mod, String::from("getdiag"), getdiag);
3351 add_builtin_fun(root_mod, String::from("split"), split);
3352 add_builtin_fun(root_mod, String::from("trim"), trim);
3353 add_builtin_fun(root_mod, String::from("contains"), contains);
3354 add_builtin_fun(root_mod, String::from("startswith"), startswith);
3355 add_builtin_fun(root_mod, String::from("endswith"), endswith);
3356 add_builtin_fun(root_mod, String::from("replace"), replace);
3357 add_builtin_fun(root_mod, String::from("upper"), upper);
3358 add_builtin_fun(root_mod, String::from("lower"), lower);
3359 add_builtin_fun(root_mod, String::from("sort"), sort);
3360 add_builtin_fun(root_mod, String::from("reverse"), reverse);
3361 add_builtin_fun(root_mod, String::from("any"), any);
3362 add_builtin_fun(root_mod, String::from("all"), all);
3363 add_builtin_fun(root_mod, String::from("find"), find);
3364 add_builtin_fun(root_mod, String::from("filter"), filter);
3365 add_builtin_fun(root_mod, String::from("max"), max);
3366 add_builtin_fun(root_mod, String::from("min"), min);
3367 add_builtin_fun(root_mod, String::from("imax"), imax);
3368 add_builtin_fun(root_mod, String::from("imin"), imin);
3369 add_builtin_fun(root_mod, String::from("push"), push);
3370 add_builtin_fun(root_mod, String::from("pop"), pop);
3371 add_builtin_fun(root_mod, String::from("append"), append);
3372 add_builtin_fun(root_mod, String::from("insert"), insert);
3373 add_builtin_fun(root_mod, String::from("remove"), remove);
3374 add_builtin_fun(root_mod, String::from("errorkind"), errorkind);
3375 add_builtin_fun(root_mod, String::from("errormsg"), errormsg);
3376 add_builtin_fun(root_mod, String::from("isequal"), isequal);
3377 add_builtin_fun(root_mod, String::from("isnotequal"), isnotequal);
3378 add_builtin_fun(root_mod, String::from("isless"), isless);
3379 add_builtin_fun(root_mod, String::from("isgreaterequal"), isgreaterequal);
3380 add_builtin_fun(root_mod, String::from("isgreater"), isgreater);
3381 add_builtin_fun(root_mod, String::from("islessequal"), islessequal);
3382 add_builtin_fun(root_mod, String::from("sigmoid"), sigmoid);
3383 add_builtin_fun(root_mod, String::from("tanh"), tanh);
3384 add_builtin_fun(root_mod, String::from("swish"), swish);
3385 add_builtin_fun(root_mod, String::from("softmax"), softmax);
3386 add_builtin_fun(root_mod, String::from("sqrt"), sqrt);
3387 add_builtin_fun(root_mod, String::from("reallytranspose"), reallytranspose);
3388 add_alias(root_mod, String::from("rt"), &String::from("reallytranspose"));
3389 add_builtin_fun(root_mod, String::from("repeat"), repeat);
3390 add_builtin_fun(root_mod, String::from("mod"), modulo);
3391 add_builtin_fun(root_mod, String::from("abs"), abs);
3392 add_builtin_fun(root_mod, String::from("pow"), pow);
3393 add_builtin_fun(root_mod, String::from("exp"), exp);
3394 add_builtin_fun(root_mod, String::from("log"), log);
3395 add_builtin_fun(root_mod, String::from("log2"), log2);
3396 add_builtin_fun(root_mod, String::from("log10"), log10);
3397 add_builtin_fun(root_mod, String::from("sin"), sin);
3398 add_builtin_fun(root_mod, String::from("cos"), cos);
3399 add_builtin_fun(root_mod, String::from("tan"), tan);
3400 add_builtin_fun(root_mod, String::from("asin"), asin);
3401 add_builtin_fun(root_mod, String::from("acos"), acos);
3402 add_builtin_fun(root_mod, String::from("atan"), atan);
3403 add_builtin_fun(root_mod, String::from("atan2"), atan2);
3404 add_builtin_fun(root_mod, String::from("sinh"), sinh);
3405 add_builtin_fun(root_mod, String::from("cosh"), cosh);
3406 add_builtin_fun(root_mod, String::from("asinh"), asinh);
3407 add_builtin_fun(root_mod, String::from("acosh"), acosh);
3408 add_builtin_fun(root_mod, String::from("atanh"), atanh);
3409 add_builtin_fun(root_mod, String::from("sign"), sign);
3410 add_builtin_fun(root_mod, String::from("ceil"), ceil);
3411 add_builtin_fun(root_mod, String::from("floor"), floor);
3412 add_builtin_fun(root_mod, String::from("round"), round);
3413 add_builtin_fun(root_mod, String::from("trunc"), trunc);
3414 add_builtin_fun(root_mod, String::from("rand"), rand);
3415 add_builtin_fun(root_mod, String::from("randi"), randi);
3416 add_builtin_fun(root_mod, String::from("str2int"), str2int);
3417 add_builtin_fun(root_mod, String::from("str2float"), str2float);
3418 add_builtin_fun(root_mod, String::from("hex2dec"), hex2dec);
3419 add_builtin_fun(root_mod, String::from("char2code"), char2code);
3420 add_builtin_fun(root_mod, String::from("code2char"), code2char);
3421 add_builtin_fun(root_mod, String::from("formatmillis"), formatmillis);
3422 add_builtin_fun(root_mod, String::from("withwidth"), withwidth);
3423 add_builtin_fun(root_mod, String::from("withzeros"), withzeros);
3424 add_builtin_fun(root_mod, String::from("readline"), readline);
3425 add_builtin_fun(root_mod, String::from("format"), format);
3426 add_builtin_fun(root_mod, String::from("print"), print);
3427 add_builtin_fun(root_mod, String::from("println"), println);
3428 add_builtin_fun(root_mod, String::from("eprint"), eprint);
3429 add_builtin_fun(root_mod, String::from("eprintln"), eprintln);
3430 add_builtin_fun(root_mod, String::from("flush"), flush);
3431 add_builtin_fun(root_mod, String::from("eflush"), eflush);
3432 add_builtin_fun(root_mod, String::from("cd"), cd);
3433 add_builtin_fun(root_mod, String::from("pwd"), pwd);
3434 add_builtin_fun(root_mod, String::from("exist"), exist);
3435 add_builtin_fun(root_mod, String::from("filetype"), filetype);
3436 add_builtin_fun(root_mod, String::from("dir"), dir);
3437 add_alias(root_mod, String::from("ls"), &String::from("dir"));
3438 add_builtin_fun(root_mod, String::from("mkdir"), mkdir);
3439 add_builtin_fun(root_mod, String::from("rmdir"), rmdir);
3440 add_builtin_fun(root_mod, String::from("rmfile"), rmfile);
3441 add_builtin_fun(root_mod, String::from("copy"), copy);
3442 add_builtin_fun(root_mod, String::from("rename"), rename);
3443 add_builtin_fun(root_mod, String::from("spawn"), spawn);
3444 add_builtin_fun(root_mod, String::from("exit"), exit);
3445 add_builtin_fun(root_mod, String::from("load"), load);
3446 add_builtin_fun(root_mod, String::from("save"), save);
3447 add_builtin_fun(root_mod, String::from("loadstr"), loadstr);
3448 add_builtin_fun(root_mod, String::from("savestr"), savestr);
3449 add_builtin_fun(root_mod, String::from("loadtoml"), loadtoml);
3450 add_builtin_fun(root_mod, String::from("savetoml"), savetoml);
3451 add_builtin_fun(root_mod, String::from("loadjson"), loadjson);
3452 add_builtin_fun(root_mod, String::from("savejson"), savejson);
3453 add_builtin_fun(root_mod, String::from("args"), args);
3454 add_builtin_fun(root_mod, String::from("env"), env);
3455 add_builtin_fun(root_mod, String::from("scriptdir"), scriptdir);
3456 add_builtin_fun(root_mod, String::from("libpath"), libpath);
3457 add_builtin_fun(root_mod, String::from("domain"), domain);
3458 add_builtin_fun(root_mod, String::from("uselib"), uselib);
3459 add_builtin_fun(root_mod, String::from("reuselib"), reuselib);
3460 add_builtin_fun(root_mod, String::from("run"), run);
3461 add_alias(root_mod, String::from("runwithdoc"), &String::from("run"));
3462 add_builtin_fun(root_mod, String::from("clock"), clock);
3463 add_builtin_fun(root_mod, String::from("usemod"), usemod);
3464 add_builtin_fun(root_mod, String::from("usemods"), usemods);
3465 add_builtin_fun(root_mod, String::from("usevar"), usevar);
3466 add_builtin_fun(root_mod, String::from("usevars"), usevars);
3467 add_builtin_fun(root_mod, String::from("removeusemod"), removeusemod);
3468 add_builtin_fun(root_mod, String::from("removeusevar"), removeusevar);
3469 add_builtin_fun(root_mod, String::from("removemod"), removemod);
3470 add_builtin_fun(root_mod, String::from("removevar"), removevar);
3471 add_builtin_fun(root_mod, String::from("removelocalvar"), removelocalvar);
3472 add_builtin_fun(root_mod, String::from("checkintr"), checkintr);
3473 add_builtin_fun(root_mod, String::from("backend"), backend);
3474 add_builtin_fun(root_mod, String::from("version"), version);
3475 add_builtin_fun(root_mod, String::from("reqver"), reqver);
3476 add_builtin_fun(root_mod, String::from("docpath"), docpath);
3477 add_builtin_fun(root_mod, String::from("doc"), doc);
3478 add_alias(root_mod, String::from("help"), &String::from("doc"));
3479 add_builtin_fun(root_mod, String::from("assert"), assert);
3480 add_builtin_fun(root_mod, String::from("asserteq"), asserteq);
3481 add_builtin_fun(root_mod, String::from("assertne"), assertne);
3482 add_builtin_fun(root_mod, String::from("assertnearlyeq"), assertnearlyeq);
3483 add_builtin_fun(root_mod, String::from("assertnearlyne"), assertnearlyne);
3484 add_builtin_fun(root_mod, String::from("tests"), tests);
3485 add_builtin_fun(root_mod, String::from("getopts"), getopts);
3486 add_builtin_fun(root_mod, String::from("getoptsusage"), getoptsusage);
3487 #[cfg(feature = "plot")]
3488 add_builtin_fun(root_mod, String::from("plot"), plot);
3489 #[cfg(feature = "plot")]
3490 add_builtin_fun(root_mod, String::from("plot3"), plot3);
3491 #[cfg(feature = "plot")]
3492 add_builtin_fun(root_mod, String::from("histogram"), histogram);
3493 #[cfg(feature = "plot")]
3494 add_alias(root_mod, String::from("hist"), &String::from("histogram"));
3495}
3496
3497#[cfg(test)]
3498mod tests;