1use std::cmp::Ordering;
10use std::collections::BTreeMap;
11use std::collections::BTreeSet;
12use std::fmt;
13use std::ops::Neg;
14use std::ops::Not;
15use std::ops::Add;
16use std::ops::AddAssign;
17use std::ops::Sub;
18use std::ops::SubAssign;
19use std::ops::Mul;
20use std::ops::MulAssign;
21use std::ops::Div;
22use std::ops::DivAssign;
23use std::result;
24use std::str::Chars;
25use std::sync::Arc;
26use std::sync::RwLock;
27use std::sync::Weak;
28use crate::serde::de;
29use crate::serde::de::MapAccess;
30use crate::serde::de::SeqAccess;
31use crate::serde::de::Visitor;
32use crate::serde::ser;
33use crate::serde::ser::SerializeSeq;
34use crate::serde::ser::SerializeMap;
35use crate::serde::Deserialize;
36use crate::serde::Deserializer;
37use crate::serde::Serialize;
38use crate::serde::Serializer;
39use crate::matrix::Matrix;
40#[cfg(feature = "plot")]
41use crate::winit;
42use crate::env::*;
43use crate::error::*;
44use crate::interp::*;
45use crate::tree::*;
46use crate::utils::*;
47
48#[cfg(feature = "plot")]
50pub type WindowId = winit::window::WindowId;
51
52#[cfg(not(feature = "plot"))]
54#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
55pub struct WindowId(());
56
57fn nearly_eq(a: f32, b: f32, eps: f32) -> bool
58{
59 if a == b {
60 true
61 } else {
62 (a - b).abs() <= eps
63 }
64}
65
66#[derive(Clone, Debug)]
70pub enum Value
71{
72 None,
74 Bool(bool),
76 Int(i64),
78 Float(f32),
80 Object(Arc<Object>),
82 Ref(Arc<RwLock<MutObject>>),
84 Weak(Weak<RwLock<MutObject>>),
86}
87
88impl Value
89{
90 pub fn to_bool(&self) -> bool
92 {
93 match self {
94 Value::None => false,
95 Value::Bool(a) => *a,
96 Value::Int(a) => *a != 0,
97 Value::Float(a) => *a != 0.0,
98 Value::Object(object) => {
99 match &**object {
100 Object::Error(_, _) => false,
101 _ => true,
102 }
103 },
104 _ => true,
105 }
106 }
107
108 pub fn to_i64(&self) -> i64
110 {
111 match self {
112 Value::None => 0,
113 Value::Bool(a) => if *a { 1 } else { 0 },
114 Value::Int(a) => *a,
115 Value::Float(a) => *a as i64,
116 Value::Object(object) => {
117 match &**object {
118 Object::Error(_, _) => 0,
119 _ => 1,
120 }
121 },
122 _ => 1,
123 }
124 }
125
126 pub fn to_f32(&self) -> f32
128 {
129 match self {
130 Value::None => 0.0,
131 Value::Bool(a) => if *a { 1.0 } else { 0.0 },
132 Value::Int(a) => *a as f32,
133 Value::Float(a) => *a,
134 Value::Object(object) => {
135 match &**object {
136 Object::Error(_, _) => 0.0,
137 _ => 1.0,
138 }
139 },
140 _ => 1.0,
141 }
142 }
143
144 pub fn to_opt_bool(&self) -> Option<bool>
147 {
148 match self {
149 Value::Bool(a) => Some(*a),
150 _ => None,
151 }
152 }
153
154 pub fn to_opt_i64(&self) -> Option<i64>
157 {
158 match self {
159 Value::Int(a) => Some(*a),
160 Value::Float(a) => Some(*a as i64),
161 _ => None,
162 }
163 }
164
165 pub fn to_opt_f32(&self) -> Option<f32>
168 {
169 match self {
170 Value::Int(a) => Some(*a as f32),
171 Value::Float(a) => Some(*a),
172 _ => None,
173 }
174 }
175
176 pub fn to_opt_string(&self) -> Option<String>
179 {
180 match self {
181 Value::Object(object) => {
182 match &**object {
183 Object::String(s) => Some(s.clone()),
184 _ => None,
185 }
186 },
187 _ => None,
188 }
189 }
190
191 pub fn is_fun(&self) -> bool
193 {
194 match self {
195 Value::Object(object) => {
196 match &**object {
197 Object::Fun(_, _, _) | Object::BuiltinFun(_, _) => true,
198 _ => false,
199 }
200 },
201 _ => false,
202 }
203 }
204
205 pub fn eq_with_types(&self, value: &Value) -> Result<bool>
212 {
213 match (self, value) {
214 (Value::None, Value::None) => Ok(true),
215 (Value::Bool(a), Value::Bool(b)) => Ok(a == b),
216 (Value::Int(a), Value::Int(b)) => Ok(a == b),
217 (Value::Float(a), Value::Float(b)) => Ok(a == b),
218 (Value::Object(object), Value::Object(object2)) => {
219 if Arc::ptr_eq(object, object2) {
220 return Ok(true);
221 }
222 object.priv_eq(&**object2)
223 },
224 (Value::Ref(object), Value::Ref(object2)) => {
225 if Arc::ptr_eq(object, object2) {
226 return Ok(true);
227 }
228 let object_g = rw_lock_read(&**object)?;
229 let object2_g = rw_lock_read(&**object2)?;
230 object_g.priv_eq(&*object2_g, Self::eq_with_types)
231 },
232 (Value::Weak(object), Value::Weak(object2)) => {
233 match (object.upgrade(), object2.upgrade()) {
234 (Some(object), Some(object2)) => Ok(Arc::ptr_eq(&object, &object2)),
235 (None, None) => Ok(true),
236 (_, _) => Ok(false),
237 }
238 },
239 (_, _) => Ok(false),
240 }
241 }
242
243 pub fn eq_without_types(&self, value: &Value) -> Result<bool>
250 {
251 match (self, value) {
252 (Value::None, Value::None) => Ok(true),
253 (Value::Bool(a), Value::Bool(b)) => Ok(a == b),
254 (Value::Int(a), Value::Int(b)) => Ok(a == b),
255 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(self.to_f32() == value.to_f32()),
256 (Value::Object(object), Value::Object(object2)) => {
257 if Arc::ptr_eq(object, object2) {
258 return Ok(true);
259 }
260 object.priv_eq(&**object2)
261 },
262 (Value::Ref(object), Value::Ref(object2)) => {
263 if Arc::ptr_eq(object, object2) {
264 return Ok(true);
265 }
266 let object_g = rw_lock_read(&**object)?;
267 let object2_g = rw_lock_read(&**object2)?;
268 object_g.priv_eq(&*object2_g, Self::eq_without_types)
269 },
270 (Value::Weak(object), Value::Weak(object2)) => {
271 match (object.upgrade(), object2.upgrade()) {
272 (Some(object), Some(object2)) => Ok(Arc::ptr_eq(&object, &object2)),
273 (None, None) => Ok(true),
274 (_, _) => Ok(false),
275 }
276 },
277 (_, _) => Ok(false),
278 }
279 }
280
281 pub fn nearly_eq_with_types(&self, value: &Value, eps: f32) -> Result<bool>
287 {
288 match (self, value) {
289 (Value::Float(a), Value::Float(b)) => Ok(nearly_eq(*a, *b, eps)),
290 (Value::Object(object), Value::Object(object2)) => {
291 if Arc::ptr_eq(object, object2) {
292 return Ok(true);
293 }
294 object.priv_nearly_eq(&**object2, eps)
295 },
296 (Value::Ref(object), Value::Ref(object2)) => {
297 if Arc::ptr_eq(object, object2) {
298 return Ok(true);
299 }
300 let object_g = rw_lock_read(&**object)?;
301 let object2_g = rw_lock_read(&**object2)?;
302 object_g.priv_nearly_eq(&*object2_g, eps, Self::nearly_eq_with_types)
303 },
304 (Value::Weak(object), Value::Weak(object2)) => {
305 match (object.upgrade(), object2.upgrade()) {
306 (Some(object), Some(object2)) => Ok(Arc::ptr_eq(&object, &object2)),
307 (None, None) => Ok(true),
308 (_, _) => Ok(false),
309 }
310 },
311 (_, _) => self.eq_with_types(value),
312 }
313 }
314
315 pub fn nearly_eq_without_types(&self, value: &Value, eps: f32) -> Result<bool>
321 {
322 match (self, value) {
323 (Value::Int(a), Value::Int(b)) => Ok(nearly_eq(*a as f32, *b as f32, eps)),
324 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(nearly_eq(self.to_f32(), value.to_f32(), eps)),
325 (Value::Object(object), Value::Object(object2)) => {
326 if Arc::ptr_eq(object, object2) {
327 return Ok(true);
328 }
329 object.priv_nearly_eq(&**object2, eps)
330 },
331 (Value::Ref(object), Value::Ref(object2)) => {
332 if Arc::ptr_eq(object, object2) {
333 return Ok(true);
334 }
335 let object_g = rw_lock_read(&**object)?;
336 let object2_g = rw_lock_read(&**object2)?;
337 object_g.priv_nearly_eq(&*object2_g, eps, Self::nearly_eq_without_types)
338 },
339 (Value::Weak(object), Value::Weak(object2)) => {
340 match (object.upgrade(), object2.upgrade()) {
341 (Some(object), Some(object2)) => Ok(Arc::ptr_eq(&object, &object2)),
342 (None, None) => Ok(true),
343 (_, _) => Ok(false),
344 }
345 },
346 (_, _) => self.eq_without_types(value),
347 }
348 }
349
350 fn dot1_for_elem_with_fun_ref<F>(&self, err_msg: &str, f: &mut F) -> Result<Value>
351 where F: FnMut(&Value) -> Result<Value>
352 {
353 match self {
354 Value::Float(_) => f(self),
355 Value::Object(object) => {
356 match &**object {
357 Object::Matrix(_) => f(self),
358 _ => Ok(self.clone()),
359 }
360 },
361 Value::Ref(_) => self.dot1_with_fun_ref(err_msg, f),
362 _ => Ok(self.clone()),
363 }
364 }
365
366 fn dot1_with_fun_ref<F>(&self, err_msg: &str, f: &mut F) -> Result<Value>
367 where F: FnMut(&Value) -> Result<Value>
368 {
369 match self {
370 Value::Ref(object) => {
371 let object_g = rw_lock_read(&**object)?;
372 match &*object_g {
373 MutObject::Array(elems) => {
374 let mut new_elems: Vec<Value> = Vec::new();
375 for elem in elems {
376 new_elems.push(elem.dot1_for_elem_with_fun_ref(err_msg, f)?);
377 }
378 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(new_elems)))))
379 },
380 MutObject::Struct(fields) => {
381 let mut new_fields: BTreeMap<String, Value> = BTreeMap::new();
382 for (ident, field) in fields {
383 new_fields.insert(ident.clone(), field.dot1_for_elem_with_fun_ref(err_msg, f)?);
384 }
385 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Struct(new_fields)))))
386 },
387 }
388 },
389 _ => Err(Error::Interp(String::from(err_msg))),
390 }
391 }
392
393 pub fn dot1<F>(&self, err_msg: &str, mut f: F) -> Result<Value>
402 where F: FnMut(&Value) -> Result<Value>
403 { self.dot1_with_fun_ref(err_msg, &mut f) }
404
405 fn dot2_for_elem_with_fun_ref<F>(&self, value: &Value, err_msg: &str, f: &mut F) -> Result<Value>
406 where F: FnMut(&Value, &Value) -> Result<Value>
407 {
408 match (self, value) {
409 (Value::Float(_), Value::Float(_)) => f(self, value),
410 (Value::Object(object), Value::Object(object2)) => {
411 match (&**object, &**object2) {
412 (Object::Matrix(_), Object::Matrix(_)) => f(self, value),
413 (_, _) => {
414 if !self.eq_with_types(value)? {
415 return Err(Error::Interp(String::from("two values aren't equal")))
416 }
417 Ok(self.clone())
418 },
419 }
420 },
421 (Value::Ref(_), Value::Ref(_)) => self.dot2_with_fun_ref(value, err_msg, f),
422 (Value::Weak(_), Value::Weak(_)) => Err(Error::Interp(String::from("two values are weak references"))),
423 (_, _) => {
424 if !self.eq_with_types(value)? {
425 return Err(Error::Interp(String::from("two values aren't equal")))
426 }
427 Ok(self.clone())
428 },
429 }
430 }
431
432 fn dot2_with_fun_ref<F>(&self, value: &Value, err_msg: &str, f: &mut F) -> Result<Value>
433 where F: FnMut(&Value, &Value) -> Result<Value>
434 {
435 match (self, value) {
436 (Value::Ref(object), Value::Ref(object2)) => {
437 let object_g = rw_lock_read(&**object)?;
438 let object2_g = rw_lock_read(&**object2)?;
439 match (&*object_g, &*object2_g) {
440 (MutObject::Array(elems), MutObject::Array(elems2)) => {
441 if elems.len() != elems2.len() {
442 return Err(Error::Interp(String::from("lengths of two arrays aren't equal")));
443 }
444 let mut new_elems: Vec<Value> = Vec::new();
445 for (elem, elem2) in elems.iter().zip(elems2.iter()) {
446 new_elems.push(elem.dot2_for_elem_with_fun_ref(elem2, err_msg, f)?);
447 }
448 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(new_elems)))))
449 },
450 (MutObject::Struct(fields), MutObject::Struct(fields2)) => {
451 let idents: BTreeSet<&String> = fields.keys().collect();
452 let idents2: BTreeSet<&String> = fields2.keys().collect();
453 if idents != idents2 {
454 return Err(Error::Interp(String::from("field names of two structures aren't equal")));
455 }
456 let mut new_fields: BTreeMap<String, Value> = BTreeMap::new();
457 for ident in &idents {
458 match (fields.get(*ident), fields2.get(*ident)) {
459 (Some(field), Some(field2)) => {
460 new_fields.insert((*ident).clone(), field.dot2_for_elem_with_fun_ref(field2, err_msg, f)?);
461 },
462 (_, _) => return Err(Error::Interp(String::from("no field value"))),
463 }
464 }
465 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Struct(new_fields)))))
466 },
467 (_, _) => Err(Error::Interp(String::from("two types aren't equal"))),
468 }
469 },
470 (_, _) => Err(Error::Interp(String::from(err_msg))),
471 }
472 }
473
474 pub fn dot2<F>(&self, value: &Value, err_msg: &str, mut f: F) -> Result<Value>
484 where F: FnMut(&Value, &Value) -> Result<Value>
485 { self.dot2_with_fun_ref(value, err_msg, &mut f) }
486
487 pub fn apply(&self, interp: &mut Interp, env: &mut Env, arg_values: &[Value]) -> Result<Value>
491 { interp.apply_fun(env, self, arg_values) }
492
493 pub fn elem(&self, idx_value: &Value) -> Result<Value>
499 {
500 match self {
501 Value::Object(object) => {
502 match &**object {
503 Object::String(s) => {
504 match idx_value {
505 Value::Int(_) | Value::Float(_) => {
506 let i = idx_value.to_i64();
507 if i < 1 || i > (s.chars().count() as i64) {
508 return Err(Error::Interp(String::from("index out of bounds")));
509 }
510 match s.chars().nth((i - 1) as usize) {
511 Some(c) => {
512 let mut t = String::new();
513 t.push(c);
514 Ok(Value::Object(Arc::new(Object::String(t))))
515 }
516 None => Err(Error::Interp(String::from("no character"))),
517 }
518 },
519 _ => Err(Error::Interp(String::from("unsupported index type for indexing"))),
520 }
521 },
522 Object::MatrixArray(row_count, _, _, _) => {
523 match idx_value {
524 Value::Int(_) | Value::Float(_) => {
525 let i = idx_value.to_i64();
526 if i < 1 || i > (*row_count as i64) {
527 return Err(Error::Interp(String::from("index out of bounds")));
528 }
529 Ok(Value::Object(Arc::new(Object::MatrixRowSlice(object.clone(), (i - 1) as usize))))
530 },
531 _ => Err(Error::Interp(String::from("unsupported index type for indexing"))),
532 }
533 },
534 Object::MatrixRowSlice(matrix_array, i) => {
535 match idx_value {
536 Value::Int(_) | Value::Float(_) => {
537 let j = idx_value.to_i64();
538 match &**matrix_array {
539 Object::MatrixArray(row_count, col_count, transpose_flag, xs) => {
540 if j < 1 || j > (*col_count as i64) {
541 return Err(Error::Interp(String::from("index out of bounds")));
542 }
543 let k = match transpose_flag {
544 TransposeFlag::NoTranspose => i * (*col_count) + ((j - 1) as usize),
545 TransposeFlag::Transpose => ((j - 1) as usize) * (*row_count) + i,
546 };
547 match xs.get(k) {
548 Some(x) => Ok(Value::Float(*x)),
549 None => Err(Error::Interp(String::from("no element"))),
550 }
551 },
552 _ => Err(Error::Interp(String::from("invalid matrix array type"))),
553 }
554 },
555 _ => Err(Error::Interp(String::from("unsupported index type for indexing"))),
556 }
557 },
558 _ => Err(Error::Interp(String::from("unsupported type for indexing"))),
559 }
560 },
561 Value::Ref(object) => {
562 let object_g = rw_lock_read(&**object)?;
563 match &*object_g {
564 MutObject::Array(elems) => {
565 match idx_value {
566 Value::Int(_) | Value::Float(_) => {
567 let i = idx_value.to_i64();
568 if i < 1 || i > (elems.len() as i64) {
569 return Err(Error::Interp(String::from("index out of bounds")));
570 }
571 match elems.get((i - 1) as usize) {
572 Some(elem) => Ok(elem.clone()),
573 None => Err(Error::Interp(String::from("no element"))),
574 }
575 },
576 _ => Err(Error::Interp(String::from("unsupported index type for indexing"))),
577 }
578 },
579 MutObject::Struct(fields) => {
580 match idx_value {
581 Value::Object(idx_object) => {
582 match &**idx_object {
583 Object::String(ident) => {
584 match fields.get(ident) {
585 Some(field) => Ok(field.clone()),
586 None => Err(Error::Interp(String::from("not found key")))
587 }
588 },
589 _ => Err(Error::Interp(String::from("unsupported index type for indexing"))),
590 }
591 },
592 _ => Err(Error::Interp(String::from("unsupported index type for indexing"))),
593 }
594 },
595 }
596 },
597 _ => Err(Error::Interp(String::from("unsupported type for indexing"))),
598 }
599 }
600
601 pub fn set_elem(&self, idx_value: &Value, value: Value) -> Result<()>
605 {
606 match self {
607 Value::Ref(object) => {
608 let mut object_g = rw_lock_write(&**object)?;
609 match &mut *object_g {
610 MutObject::Array(elems) => {
611 match idx_value {
612 Value::Int(_) | Value::Float(_) => {
613 let i = idx_value.to_i64();
614 if i < 1 || i > (elems.len() as i64) {
615 return Err(Error::Interp(String::from("index out of bounds")));
616 }
617 match elems.get_mut((i - 1) as usize) {
618 Some(elem) => {
619 *elem = value;
620 Ok(())
621 }
622 None => Err(Error::Interp(String::from("no element"))),
623 }
624 },
625 _ => Err(Error::Interp(String::from("unsupported index type for indexing"))),
626 }
627 },
628 MutObject::Struct(fields) => {
629 match idx_value {
630 Value::Object(idx_object) => {
631 match &**idx_object {
632 Object::String(ident) => {
633 fields.insert(ident.clone(), value);
634 Ok(())
635 },
636 _ => Err(Error::Interp(String::from("unsupported index type for indexing"))),
637 }
638 },
639 _ => Err(Error::Interp(String::from("unsupported index type for indexing"))),
640 }
641 },
642 }
643 },
644 _ => Err(Error::Interp(String::from("unsupported type for indexing"))),
645 }
646 }
647
648 pub fn field(&self, ident: &String) -> Result<Value>
652 {
653 match self {
654 Value::Ref(object) => {
655 let object_g = rw_lock_read(&**object)?;
656 match &*object_g {
657 MutObject::Struct(fields) => {
658 match fields.get(ident) {
659 Some(field) => Ok(field.clone()),
660 None => Err(Error::Interp(format!("structure hasn't field {}", ident))),
661 }
662 },
663 _ => Err(Error::Interp(format!("unsupported type for field {}", ident))),
664 }
665 },
666 _ => Err(Error::Interp(format!("unsupported type for field {}", ident))),
667 }
668 }
669
670 pub fn set_field(&self, ident: String, value: Value) -> Result<()>
674 {
675 match self {
676 Value::Ref(object) => {
677 let mut object_g = rw_lock_write(&**object)?;
678 match &mut *object_g {
679 MutObject::Struct(fields) => {
680 fields.insert(ident.clone(), value);
681 Ok(())
682 },
683 _ => Err(Error::Interp(format!("unsupported type for field {}", ident))),
684 }
685 },
686 _ => Err(Error::Interp(format!("unsupported type for field {}", ident))),
687 }
688 }
689
690 pub fn unary_op(&self, op: UnaryOp) -> Result<Value>
692 {
693 match op {
694 UnaryOp::Neg => {
695 match self {
696 Value::Int(a) => {
697 match a.checked_neg() {
698 Some(b) => Ok(Value::Int(b)),
699 None => Err(Error::Interp(String::from("overflow in negation"))),
700 }
701 },
702 Value::Float(a) => Ok(Value::Float(-a)),
703 Value::Object(object) => {
704 match &**object {
705 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_rsub_for_scalar(a, 0.0)?)))),
706 _ => Err(Error::Interp(String::from("unsupported type for negation"))),
707 }
708 },
709 _ => Err(Error::Interp(String::from("unsupported type for negation"))),
710 }
711 },
712 UnaryOp::DotNeg => {
713 match self {
714 Value::Int(_) | Value::Float(_) => Ok(Value::Float(-self.to_f32())),
715 Value::Object(object) => {
716 match &**object {
717 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_rsub_for_scalar(a, 0.0)?)))),
718 _ => Err(Error::Interp(String::from("unsupported type for dot negation"))),
719 }
720 },
721 _ => self.dot1("unsupported type for dot negation", |v| v.unary_op(op)),
722 }
723 },
724 UnaryOp::Not => Ok(Value::Bool(!self.to_bool())),
725 UnaryOp::Transpose => {
726 match self {
727 Value::Int(_) | Value::Float(_) => Ok(self.clone()),
728 Value::Object(object) => {
729 match &**object {
730 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(a.transpose())))),
731 _ => Err(Error::Interp(String::from("unsupported type for transpose"))),
732 }
733 },
734 _ => Err(Error::Interp(String::from("unsupported type for transpose"))),
735 }
736 },
737 }
738 }
739
740 pub fn bin_op(&self, op: BinOp, value: &Value) -> Result<Value>
742 {
743 match op {
744 BinOp::Index => self.elem(value),
745 BinOp::Mul => {
746 match (self, value) {
747 (Value::Int(a), Value::Int(b)) => {
748 match a.checked_mul(*b) {
749 Some(c) => Ok(Value::Int(c)),
750 None => Err(Error::Interp(String::from("overflow in multiplication"))),
751 }
752 },
753 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(Value::Float(self.to_f32() * value.to_f32())),
754 (Value::Object(object), Value::Int(_) | Value::Float(_)) => {
755 match &**object {
756 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_mul_for_scalar(a, value.to_f32())?)))),
757 _ => Err(Error::Interp(String::from("unsupported types for multiplication"))),
758 }
759 },
760 (Value::Int(_) | Value::Float(_), Value::Object(object2)) => {
761 match &**object2 {
762 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_mul_for_scalar(b, self.to_f32())?)))),
763 _ => Err(Error::Interp(String::from("unsupported types for multiplication"))),
764 }
765 },
766 (Value::Object(object), Value::Object(object2)) => {
767 match (&**object, &**object2) {
768 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_mul(a, b)?)))),
769 _ => Err(Error::Interp(String::from("unsupported types for multiplication"))),
770 }
771 },
772 _ => Err(Error::Interp(String::from("unsupported types for multiplication"))),
773 }
774 },
775 BinOp::DotMul => {
776 match (self, value) {
777 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(Value::Float(self.to_f32() * value.to_f32())),
778 (Value::Object(object), Value::Int(_) | Value::Float(_)) => {
779 match &**object {
780 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_mul_for_scalar(a, value.to_f32())?)))),
781 _ => Err(Error::Interp(String::from("unsupported types for dot multiplication"))),
782 }
783 },
784 (Value::Int(_) | Value::Float(_), Value::Object(object2)) => {
785 match &**object2 {
786 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_mul_for_scalar(b, self.to_f32())?)))),
787 _ => Err(Error::Interp(String::from("unsupported types for dot multiplication"))),
788 }
789 },
790 (Value::Object(object), Value::Object(object2)) => {
791 match (&**object, &**object2) {
792 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_mul_elems(a, b)?)))),
793 _ => Err(Error::Interp(String::from("unsupported types for dot multiplication"))),
794 }
795 },
796 (Value::Ref(_), Value::Int(_) | Value::Float(_)) => self.dot1("unsupported types for dot multiplication", |v| v.bin_op(op, value)),
797 (Value::Int(_) | Value::Float(_), Value::Ref(_)) => value.dot1("unsupported types for dot multiplication", |v| self.bin_op(op, v)),
798 _ => self.dot2(value, "unsupported types for dot multiplication", |v, w| v.bin_op(op, w)),
799 }
800 },
801 BinOp::Div => {
802 match (self, value) {
803 (Value::Int(a), Value::Int(b)) => {
804 match a.checked_div(*b) {
805 Some(c) => Ok(Value::Int(c)),
806 None => {
807 if *b == 0 {
808 Err(Error::Interp(String::from("division by zero")))
809 } else {
810 Err(Error::Interp(String::from("overflow in division")))
811 }
812 },
813 }
814 },
815 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(Value::Float(self.to_f32() / value.to_f32())),
816 (Value::Object(object), Value::Int(_) | Value::Float(_)) => {
817 match &**object {
818 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_div_for_scalar(a, value.to_f32())?)))),
819 _ => Err(Error::Interp(String::from("unsupported types for division"))),
820 }
821 },
822 (Value::Int(_) | Value::Float(_), Value::Object(object2)) => {
823 match &**object2 {
824 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_rdiv_for_scalar(b, self.to_f32())?)))),
825 _ => Err(Error::Interp(String::from("unsupported types for division"))),
826 }
827 },
828 (_, _) => Err(Error::Interp(String::from("unsupported types for division"))),
829 }
830 },
831 BinOp::DotDiv => {
832 match (self, value) {
833 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(Value::Float(self.to_f32() / value.to_f32())),
834 (Value::Object(object), Value::Int(_) | Value::Float(_)) => {
835 match &**object {
836 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_div_for_scalar(a, value.to_f32())?)))),
837 _ => Err(Error::Interp(String::from("unsupported types for dot division"))),
838 }
839 },
840 (Value::Int(_) | Value::Float(_), Value::Object(object2)) => {
841 match &**object2 {
842 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_rdiv_for_scalar(b, self.to_f32())?)))),
843 _ => Err(Error::Interp(String::from("unsupported types for dot division"))),
844 }
845 },
846 (Value::Object(object), Value::Object(object2)) => {
847 match (&**object, &**object2) {
848 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_div_elems(a, b)?)))),
849 _ => Err(Error::Interp(String::from("unsupported types for dot division"))),
850 }
851 },
852 (Value::Ref(_), Value::Int(_) | Value::Float(_)) => self.dot1("unsupported types for dot division", |v| v.bin_op(op, value)),
853 (Value::Int(_) | Value::Float(_), Value::Ref(_)) => value.dot1("unsupported types for dot division", |v| self.bin_op(op, v)),
854 (_, _) => self.dot2(value, "unsupported types for dot division", |v, w| v.bin_op(op, w)),
855 }
856 },
857 BinOp::Add => {
858 match (self, value) {
859 (Value::Int(a), Value::Int(b)) => {
860 match a.checked_add(*b) {
861 Some(c) => Ok(Value::Int(c)),
862 None => Err(Error::Interp(String::from("overflow in addition"))),
863 }
864 },
865 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(Value::Float(self.to_f32() + value.to_f32())),
866 (Value::Object(object), Value::Int(_) | Value::Float(_)) => {
867 match &**object {
868 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_add_for_scalar(a, value.to_f32())?)))),
869 _ => Err(Error::Interp(String::from("unsupported types for addition"))),
870 }
871 },
872 (Value::Int(_) | Value::Float(_), Value::Object(object2)) => {
873 match &**object2 {
874 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_add_for_scalar(b, self.to_f32())?)))),
875 _ => Err(Error::Interp(String::from("unsupported types for addition"))),
876 }
877 },
878 (Value::Object(object), Value::Object(object2)) => {
879 match (&**object, &**object2) {
880 (Object::String(s), Object::String(t)) => Ok(Value::Object(Arc::new(Object::String(s.clone() + t.as_str())))),
881 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_add(a, b)?)))),
882 _ => Err(Error::Interp(String::from("unsupported types for addition"))),
883 }
884 },
885 (Value::Ref(object), Value::Ref(object2)) => {
886 let object_g = rw_lock_read(&**object)?;
887 let object2_g = rw_lock_read(&**object2)?;
888 match (&*object_g, &*object2_g) {
889 (MutObject::Array(elems), MutObject::Array(elems2)) => {
890 let mut new_elems = elems.clone();
891 new_elems.extend_from_slice(elems2.as_slice());
892 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(new_elems)))))
893 },
894 (MutObject::Struct(fields), MutObject::Struct(fields2)) => {
895 let mut new_fields: BTreeMap<String, Value> = BTreeMap::new();
896 let idents: BTreeSet<&String> = fields.keys().collect();
897 let idents2: BTreeSet<&String> = fields2.keys().collect();
898 let idents3: Vec<&String> = idents.union(&idents2).map(|s| *s).collect();
899 for ident in &idents3 {
900 match fields.get(*ident) {
901 Some(field) => {
902 new_fields.insert((*ident).clone(), field.clone());
903 },
904 None => {
905 match fields2.get(*ident) {
906 Some(field2) => {
907 new_fields.insert((*ident).clone(), field2.clone());
908 },
909 None => return Err(Error::Interp(String::from("no field"))),
910 }
911 },
912 }
913 }
914 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Struct(new_fields)))))
915 },
916 _ => Err(Error::Interp(String::from("unsupported types for addition"))),
917 }
918 },
919 (_, _) => Err(Error::Interp(String::from("unsupported types for addition"))),
920 }
921 },
922 BinOp::DotAdd => {
923 match (self, value) {
924 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(Value::Float(self.to_f32() + value.to_f32())),
925 (Value::Object(object), Value::Int(_) | Value::Float(_)) => {
926 match &**object {
927 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_add_for_scalar(a, value.to_f32())?)))),
928 _ => Err(Error::Interp(String::from("unsupported types for dot addition"))),
929 }
930 },
931 (Value::Int(_) | Value::Float(_), Value::Object(object2)) => {
932 match &**object2 {
933 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_add_for_scalar(b, self.to_f32())?)))),
934 _ => Err(Error::Interp(String::from("unsupported types for dot addition"))),
935 }
936 },
937 (Value::Object(object), Value::Object(object2)) => {
938 match (&**object, &**object2) {
939 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_add(a, b)?)))),
940 _ => Err(Error::Interp(String::from("unsupported types for dot addition"))),
941 }
942 },
943 (Value::Ref(_), Value::Int(_) | Value::Float(_)) => self.dot1("unsupported types for dot addition", |v| v.bin_op(op, value)),
944 (Value::Int(_) | Value::Float(_), Value::Ref(_)) => value.dot1("unsupported types for dot addition", |v| self.bin_op(op, v)),
945 (_, _) => self.dot2(value, "unsupported types for dot addition", |v, w| v.bin_op(op, w)),
946 }
947 },
948 BinOp::Sub => {
949 match (self, value) {
950 (Value::Int(a), Value::Int(b)) => {
951 match a.checked_sub(*b) {
952 Some(c) => Ok(Value::Int(c)),
953 None => Err(Error::Interp(String::from("overflow in subtraction"))),
954 }
955 },
956 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(Value::Float(self.to_f32() - value.to_f32())),
957 (Value::Object(object), Value::Int(_) | Value::Float(_)) => {
958 match &**object {
959 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_sub_for_scalar(a, value.to_f32())?)))),
960 _ => Err(Error::Interp(String::from("unsupported types for subtraction"))),
961 }
962 },
963 (Value::Int(_) | Value::Float(_), Value::Object(object2)) => {
964 match &**object2 {
965 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_rsub_for_scalar(b, self.to_f32())?)))),
966 _ => Err(Error::Interp(String::from("unsupported types for subtraction"))),
967 }
968 },
969 (Value::Object(object), Value::Object(object2)) => {
970 match (&**object, &**object2) {
971 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_sub(a, b)?)))),
972 _ => Err(Error::Interp(String::from("unsupported types for subtraction"))),
973 }
974 },
975 (_, _) => Err(Error::Interp(String::from("unsupported types for subtraction"))),
976 }
977 },
978 BinOp::DotSub => {
979 match (self, value) {
980 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(Value::Float(self.to_f32() - value.to_f32())),
981 (Value::Object(object), Value::Int(_) | Value::Float(_)) => {
982 match &**object {
983 Object::Matrix(a) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_sub_for_scalar(a, value.to_f32())?)))),
984 _ => Err(Error::Interp(String::from("unsupported types for dot subtraction"))),
985 }
986 },
987 (Value::Int(_) | Value::Float(_), Value::Object(object2)) => {
988 match &**object2 {
989 Object::Matrix(b) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_rsub_for_scalar(b, self.to_f32())?)))),
990 _ => Err(Error::Interp(String::from("unsupported types for dot subtraction"))),
991 }
992 },
993 (Value::Object(object), Value::Object(object2)) => {
994 match (&**object, &**object2) {
995 (Object::Matrix(a), Object::Matrix(b)) => Ok(Value::Object(Arc::new(Object::Matrix(matrix_sub(a, b)?)))),
996 _ => Err(Error::Interp(String::from("unsupported types for dot subtraction"))),
997 }
998 },
999 (Value::Ref(_), Value::Int(_) | Value::Float(_)) => self.dot1("unsupported types for dot subtraction", |v| v.bin_op(op, value)),
1000 (Value::Int(_) | Value::Float(_), Value::Ref(_)) => value.dot1("unsupported types for dot subtraction", |v| self.bin_op(op, v)),
1001 (_, _) => self.dot2(value, "unsupported types for dot subtraction", |v, w| v.bin_op(op, w)),
1002 }
1003 },
1004 BinOp::Lt => {
1005 match (self, value) {
1006 (Value::Bool(a), Value::Bool(b)) => Ok(Value::Bool(a < b)),
1007 (Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a < b)),
1008 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => Ok(Value::Bool(self.to_f32() < value.to_f32())),
1009 (Value::Object(object), Value::Object(object2)) => {
1010 match (&**object, &**object2) {
1011 (Object::String(s), Object::String(t)) => Ok(Value::Bool(s < t)),
1012 (_, _) => Err(Error::Interp(String::from("unsupported types for comparison"))),
1013 }
1014 },
1015 (_, _) => Err(Error::Interp(String::from("unsupported types for comparison"))),
1016 }
1017 },
1018 BinOp::Ge => Ok(Value::Bool(!self.bin_op(BinOp::Lt, value)?.to_bool())),
1019 BinOp::Gt => Ok(Value::Bool(value.bin_op(BinOp::Lt, self)?.to_bool())),
1020 BinOp::Le => Ok(Value::Bool(!value.bin_op(BinOp::Lt, self)?.to_bool())),
1021 BinOp::Eq => Ok(Value::Bool(self.eq_without_types(value)?)),
1022 BinOp::Ne => Ok(Value::Bool(!self.bin_op(BinOp::Eq, value)?.to_bool())),
1023 }
1024 }
1025
1026 pub fn iter(&self) -> Result<Option<Iter<'_>>>
1028 {
1029 match self {
1030 Value::Object(object) => {
1031 match &**object {
1032 Object::String(s) => Ok(Some(Iter::new(IterEnum::String(s.chars())))),
1033 Object::IntRange(a, b, c) => Ok(Some(Iter::new(IterEnum::IntRange(*a, *b, *c, false)))),
1034 Object::FloatRange(a, b, c) => Ok(Some(Iter::new(IterEnum::FloatRange(*a, *b, *c, false)))),
1035 Object::MatrixArray(_, _, _, _) => Ok(Some(Iter::new(IterEnum::MatrixArray(object.clone(), 0, false)))),
1036 Object::MatrixRowSlice(matrix_array, i) => Ok(Some(Iter::new(IterEnum::MatrixRowSlice(matrix_array.clone(), *i, 0, false)))),
1037 _ => Ok(None),
1038 }
1039 },
1040 Value::Ref(object) => {
1041 let object_g = rw_lock_read(&**object)?;
1042 match &*object_g {
1043 MutObject::Array(_) => Ok(Some(Iter::new(IterEnum::Array(object.clone(), 0, false)))),
1044 _ => Ok(None),
1045 }
1046 }
1047 _ => Ok(None),
1048 }
1049 }
1050
1051 pub fn to_matrix_array(&self) -> Result<Value>
1055 {
1056 match self {
1057 Value::Object(object) => {
1058 match &**object {
1059 Object::Matrix(a) => Ok(Value::Object(Arc::new(matrix_to_matrix_array(a)?))),
1060 Object::MatrixArray(_, _, _, _) => Ok(self.clone()),
1061 _ => Err(Error::Interp(String::from("unsupported type for conversion to matrix array"))),
1062 }
1063 },
1064 _ => Err(Error::Interp(String::from("unsupported type for conversion to matrix array"))),
1065 }
1066 }
1067
1068 fn fmt_with_indent(&self, f: &mut fmt::Formatter<'_>, indent: usize, is_width: bool) -> fmt::Result
1069 {
1070 let width = if is_width { 11 } else { 0 };
1071 match self {
1072 Value::None => write!(f, "{:>width$}", "none")?,
1073 Value::Bool(false) => write!(f, "{:>width$}", "false")?,
1074 Value::Bool(true) => write!(f, "{:>width$}", "true")?,
1075 Value::Int(a) => write!(f, "{:>width$}", a)?,
1076 Value::Float(a) => {
1077 if a.floor() == *a {
1078 if format!("{}", a).len() > 11 {
1079 write!(f, "{:>width$.4e}", a)?;
1080 } else {
1081 write!(f, "{:>width$}", a)?;
1082 }
1083 } else {
1084 if format!("{:.4}", a).len() > 11 || (a.abs() < 0.0001 && *a != 0.0) {
1085 write!(f, "{:>width$.4e}", a)?;
1086 } else {
1087 write!(f, "{:>width$.4}", a)?;
1088 }
1089 }
1090 },
1091 Value::Object(object) => {
1092 match &**object {
1093 Object::String(s) => write!(f, "{}", s)?,
1094 Object::IntRange(a, b, c) => {
1095 Value::Int(*a).fmt_with_indent(f, indent, is_width)?;
1096 write!(f, " to ")?;
1097 Value::Int(*b).fmt_with_indent(f, indent, is_width)?;
1098 write!(f, " by ")?;
1099 Value::Int(*c).fmt_with_indent(f, indent, is_width)?;
1100 },
1101 Object::FloatRange(a, b, c) => {
1102 Value::Float(*a).fmt_with_indent(f, indent, is_width)?;
1103 write!(f, " to ")?;
1104 Value::Float(*b).fmt_with_indent(f, indent, is_width)?;
1105 write!(f, " by ")?;
1106 Value::Float(*c).fmt_with_indent(f, indent, is_width)?;
1107 },
1108 Object::Matrix(_) => self.to_matrix_array().unwrap().fmt_with_indent(f, indent, is_width)?,
1109 Object::Fun(idents, ident, _) => {
1110 for ident2 in idents {
1111 write!(f, "{}::", ident2)?;
1112 }
1113 write!(f, "{}", ident)?;
1114 },
1115 Object::BuiltinFun(ident, _) => write!(f, "{}", ident)?,
1116 Object::MatrixArray(row_count, col_count, transpose_flag, xs) => {
1117 if *row_count > 0 && *col_count > 0 {
1118 let new_indent = indent + 4;
1119 writeln!(f, "[")?;
1120 for i in 0..*row_count {
1121 write!(f, "{:new_indent$}", "")?;
1122 for j in 0..*col_count {
1123 let k = match transpose_flag {
1124 TransposeFlag::NoTranspose => i * (*col_count) + j,
1125 TransposeFlag::Transpose => j * (*row_count) + i,
1126 };
1127 Value::Float(xs[k]).fmt_with_indent(f, new_indent, true)?;
1128 if j + 1 < *col_count {
1129 write!(f, " ")?;
1130 }
1131 }
1132 writeln!(f, "")?;
1133 }
1134 write!(f, "{:indent$}]", "")?;
1135 } else {
1136 write!(f, "[]")?;
1137 }
1138 },
1139 Object::MatrixRowSlice(matrix_array, i) => {
1140 match &**matrix_array {
1141 Object::MatrixArray(row_count, col_count, transpose_flag, xs) => {
1142 if *col_count > 0 {
1143 let new_indent = indent + 4;
1144 write!(f, "[")?;
1145 for j in 0..*col_count {
1146 let k = match transpose_flag {
1147 TransposeFlag::NoTranspose => (*i) * (*col_count) + j,
1148 TransposeFlag::Transpose => j * (*row_count) + (*i),
1149 };
1150 write!(f, " ")?;
1151 Value::Float(xs[k]).fmt_with_indent(f, new_indent, is_width)?;
1152 }
1153 write!(f, " ]")?;
1154 } else {
1155 write!(f, "[]")?;
1156 }
1157 },
1158 _ => write!(f, "[]")?,
1159 }
1160 },
1161 Object::Error(_, msg) => write!(f, "{}", msg)?,
1162 Object::WindowId(_) => write!(f, "windowid(...)")?,
1163 }
1164 },
1165 Value::Ref(object) => {
1166 let object_g = rw_lock_read(&**object).unwrap();
1167 match &*object_g {
1168 MutObject::Array(elems) => {
1169 if !elems.is_empty() {
1170 let new_indent = indent + 4;
1171 write!(f, ".[")?;
1172 for elem in elems {
1173 write!(f, " ")?;
1174 elem.fmt_with_indent(f, new_indent, is_width)?;
1175 }
1176 write!(f, " .]")?;
1177 } else {
1178 write!(f, ".[.]")?;
1179 }
1180 },
1181 MutObject::Struct(fields) => {
1182 if !fields.is_empty() {
1183 let new_indent = indent + 4;
1184 writeln!(f, "{{")?;
1185 for (ident, field) in fields {
1186 write!(f, "{:new_indent$}{}: ", "", ident)?;
1187 field.fmt_with_indent(f, new_indent, is_width)?;
1188 writeln!(f, "")?;
1189 }
1190 write!(f, "{:indent$}}}", "")?;
1191 } else {
1192 write!(f, "{{}}")?;
1193 }
1194 },
1195 }
1196 },
1197 Value::Weak(object) => {
1198 match object.upgrade() {
1199 Some(_) => write!(f, "weak(...)")?,
1200 None => write!(f, "weak()")?,
1201 }
1202 },
1203 }
1204 Ok(())
1205 }
1206}
1207
1208impl Neg for Value
1209{
1210 type Output = Self;
1211
1212 fn neg(self) -> Self::Output
1213 { self.unary_op(UnaryOp::Neg).unwrap() }
1214}
1215
1216impl Neg for &Value
1217{
1218 type Output = Value;
1219
1220 fn neg(self) -> Self::Output
1221 { self.unary_op(UnaryOp::Neg).unwrap() }
1222}
1223
1224impl Not for Value
1225{
1226 type Output = Self;
1227
1228 fn not(self) -> Self::Output
1229 { self.unary_op(UnaryOp::Not).unwrap() }
1230}
1231
1232impl Not for &Value
1233{
1234 type Output = Value;
1235
1236 fn not(self) -> Self::Output
1237 { self.unary_op(UnaryOp::Not).unwrap() }
1238}
1239
1240impl Add for Value
1241{
1242 type Output = Self;
1243
1244 fn add(self, rhs: Self) -> Self::Output
1245 { self.bin_op(BinOp::Add, &rhs).unwrap() }
1246}
1247
1248impl Add<&Value> for Value
1249{
1250 type Output = Self;
1251
1252 fn add(self, rhs: &Value) -> Self::Output
1253 { self.bin_op(BinOp::Add, rhs).unwrap() }
1254}
1255
1256impl Add<Value> for &Value
1257{
1258 type Output = Value;
1259
1260 fn add(self, rhs: Value) -> Self::Output
1261 { self.bin_op(BinOp::Add, &rhs).unwrap() }
1262}
1263
1264impl Add<&Value> for &Value
1265{
1266 type Output = Value;
1267
1268 fn add(self, rhs: &Value) -> Self::Output
1269 { self.bin_op(BinOp::Add, rhs).unwrap() }
1270}
1271
1272impl AddAssign for Value
1273{
1274 fn add_assign(&mut self, rhs: Self)
1275 { *self = self.bin_op(BinOp::Add, &rhs).unwrap(); }
1276}
1277
1278impl AddAssign<&Value> for Value
1279{
1280 fn add_assign(&mut self, rhs: &Self)
1281 { *self = self.bin_op(BinOp::Add, rhs).unwrap(); }
1282}
1283
1284impl Sub for Value
1285{
1286 type Output = Self;
1287
1288 fn sub(self, rhs: Self) -> Self::Output
1289 { self.bin_op(BinOp::Sub, &rhs).unwrap() }
1290}
1291
1292impl Sub<&Value> for Value
1293{
1294 type Output = Self;
1295
1296 fn sub(self, rhs: &Value) -> Self::Output
1297 { self.bin_op(BinOp::Sub, rhs).unwrap() }
1298}
1299
1300impl Sub<Value> for &Value
1301{
1302 type Output = Value;
1303
1304 fn sub(self, rhs: Value) -> Self::Output
1305 { self.bin_op(BinOp::Sub, &rhs).unwrap() }
1306}
1307
1308impl Sub<&Value> for &Value
1309{
1310 type Output = Value;
1311
1312 fn sub(self, rhs: &Value) -> Self::Output
1313 { self.bin_op(BinOp::Sub, rhs).unwrap() }
1314}
1315
1316impl SubAssign for Value
1317{
1318 fn sub_assign(&mut self, rhs: Self)
1319 { *self = self.bin_op(BinOp::Sub, &rhs).unwrap(); }
1320}
1321
1322impl SubAssign<&Value> for Value
1323{
1324 fn sub_assign(&mut self, rhs: &Self)
1325 { *self = self.bin_op(BinOp::Sub, rhs).unwrap(); }
1326}
1327
1328impl Mul for Value
1329{
1330 type Output = Self;
1331
1332 fn mul(self, rhs: Self) -> Self::Output
1333 { self.bin_op(BinOp::Mul, &rhs).unwrap() }
1334}
1335
1336impl Mul<&Value> for Value
1337{
1338 type Output = Self;
1339
1340 fn mul(self, rhs: &Value) -> Self::Output
1341 { self.bin_op(BinOp::Mul, rhs).unwrap() }
1342}
1343
1344impl Mul<Value> for &Value
1345{
1346 type Output = Value;
1347
1348 fn mul(self, rhs: Value) -> Self::Output
1349 { self.bin_op(BinOp::Mul, &rhs).unwrap() }
1350}
1351
1352impl Mul<&Value> for &Value
1353{
1354 type Output = Value;
1355
1356 fn mul(self, rhs: &Value) -> Self::Output
1357 { self.bin_op(BinOp::Mul, rhs).unwrap() }
1358}
1359
1360impl MulAssign for Value
1361{
1362 fn mul_assign(&mut self, rhs: Self)
1363 { *self = self.bin_op(BinOp::Mul, &rhs).unwrap(); }
1364}
1365
1366impl MulAssign<&Value> for Value
1367{
1368 fn mul_assign(&mut self, rhs: &Self)
1369 { *self = self.bin_op(BinOp::Mul, rhs).unwrap(); }
1370}
1371
1372impl Div for Value
1373{
1374 type Output = Self;
1375
1376 fn div(self, rhs: Self) -> Self::Output
1377 { self.bin_op(BinOp::Div, &rhs).unwrap() }
1378}
1379
1380impl Div<&Value> for Value
1381{
1382 type Output = Self;
1383
1384 fn div(self, rhs: &Value) -> Self::Output
1385 { self.bin_op(BinOp::Div, rhs).unwrap() }
1386}
1387
1388impl Div<Value> for &Value
1389{
1390 type Output = Value;
1391
1392 fn div(self, rhs: Value) -> Self::Output
1393 { self.bin_op(BinOp::Div, &rhs).unwrap() }
1394}
1395
1396impl Div<&Value> for &Value
1397{
1398 type Output = Value;
1399
1400 fn div(self, rhs: &Value) -> Self::Output
1401 { self.bin_op(BinOp::Div, rhs).unwrap() }
1402}
1403
1404impl DivAssign for Value
1405{
1406 fn div_assign(&mut self, rhs: Self)
1407 { *self = self.bin_op(BinOp::Div, &rhs).unwrap(); }
1408}
1409
1410impl DivAssign<&Value> for Value
1411{
1412 fn div_assign(&mut self, rhs: &Self)
1413 { *self = self.bin_op(BinOp::Div, rhs).unwrap(); }
1414}
1415
1416impl PartialEq for Value
1417{
1418 fn eq(&self, other: &Self) -> bool
1419 { self.bin_op(BinOp::Eq, other).unwrap().to_bool() }
1420}
1421
1422impl PartialOrd for Value
1423{
1424 fn partial_cmp(&self, other: &Self) -> Option<Ordering>
1425 {
1426 match (self, other) {
1427 (Value::Bool(a), Value::Bool(b)) => a.partial_cmp(b),
1428 (Value::Int(a), Value::Int(b)) => a.partial_cmp(b),
1429 (Value::Int(_) | Value::Float(_), Value::Int(_) | Value::Float(_)) => self.to_f32().partial_cmp(&other.to_f32()),
1430 (Value::Object(object), Value::Object(object2)) => {
1431 match (&**object, &**object2) {
1432 (Object::String(s), Object::String(t)) => s.partial_cmp(t),
1433 (_, _) => None,
1434 }
1435 },
1436 (_, _) => None,
1437 }
1438 }
1439}
1440
1441impl fmt::Display for Value
1442{
1443 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
1444 { self.fmt_with_indent(f, 0, false) }
1445}
1446
1447impl Serialize for Value
1448{
1449 fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
1450 where S: Serializer
1451 {
1452 match self {
1453 Value::None => serializer.serialize_unit(),
1454 Value::Bool(a) => serializer.serialize_bool(*a),
1455 Value::Int(a) => serializer.serialize_i64(*a),
1456 Value::Float(a) => serializer.serialize_f32(*a),
1457 Value::Object(object) => {
1458 match &**object {
1459 Object::String(s) => serializer.serialize_str(s.as_str()),
1460 _ => Err(ser::Error::custom("unsupported type for serialization")),
1461 }
1462 },
1463 Value::Ref(object) => {
1464 let object_g = match rw_lock_read(&**object) {
1465 Ok(tmp_object_g) => tmp_object_g,
1466 Err(err) => return Err(ser::Error::custom(format!("{}", err))),
1467 };
1468 match &*object_g {
1469 MutObject::Array(elems) => {
1470 let mut seq = serializer.serialize_seq(Some(elems.len()))?;
1471 for elem in elems {
1472 seq.serialize_element(elem)?;
1473 }
1474 seq.end()
1475 },
1476 MutObject::Struct(fields) => {
1477 let mut map = serializer.serialize_map(Some(fields.len()))?;
1478 for (ident, field) in fields {
1479 map.serialize_entry(ident, field)?;
1480 }
1481 map.end()
1482 },
1483 }
1484 },
1485 _ => Err(ser::Error::custom("unsupported type for serialization")),
1486 }
1487 }
1488}
1489
1490struct ValueVisitor;
1491
1492impl<'de> Visitor<'de> for ValueVisitor
1493{
1494 type Value = Value;
1495
1496 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result
1497 { write!(formatter, "a value") }
1498
1499 fn visit_unit<E>(self) -> result::Result<Self::Value, E>
1500 where E: de::Error
1501 { Ok(Value::None) }
1502
1503 fn visit_bool<E>(self, v: bool) -> result::Result<Self::Value, E>
1504 where E: de::Error
1505 { Ok(Value::Bool(v)) }
1506
1507 fn visit_i64<E>(self, v: i64) -> result::Result<Self::Value, E>
1508 where E: de::Error
1509 { Ok(Value::Int(v)) }
1510
1511 fn visit_u64<E>(self, v: u64) -> result::Result<Self::Value, E>
1512 where E: de::Error
1513 {
1514 if v <= (i64::MAX as u64) {
1515 Ok(Value::Int(v as i64))
1516 } else {
1517 Err(E::custom(String::from("too large integer number")))
1518 }
1519 }
1520
1521 fn visit_f32<E>(self, v: f32) -> result::Result<Self::Value, E>
1522 where E: de::Error
1523 { Ok(Value::Float(v)) }
1524
1525 fn visit_f64<E>(self, v: f64) -> result::Result<Self::Value, E>
1526 where E: de::Error
1527 { Ok(Value::Float(v as f32)) }
1528
1529 fn visit_str<E>(self, v: &str) -> result::Result<Self::Value, E>
1530 where E: de::Error
1531 { Ok(Value::Object(Arc::new(Object::String(String::from(v))))) }
1532
1533 fn visit_seq<A>(self, mut seq: A) -> result::Result<Self::Value, A::Error>
1534 where A: SeqAccess<'de>
1535 {
1536 let mut elems: Vec<Value> = Vec::new();
1537 loop {
1538 match seq.next_element()? {
1539 Some(elem) => elems.push(elem),
1540 None => break,
1541 }
1542 }
1543 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Array(elems)))))
1544 }
1545
1546 fn visit_map<A>(self, mut map: A) -> result::Result<Self::Value, A::Error>
1547 where A: MapAccess<'de>
1548 {
1549 let mut fields: BTreeMap<String, Value> = BTreeMap::new();
1550 loop {
1551 match map.next_key()? {
1552 Some(ident) => {
1553 fields.insert(ident, map.next_value()?);
1554 },
1555 None => break,
1556 }
1557 }
1558 Ok(Value::Ref(Arc::new(RwLock::new(MutObject::Struct(fields)))))
1559 }
1560}
1561
1562impl<'de> Deserialize<'de> for Value
1563{
1564 fn deserialize<D>(deserializer: D) -> result::Result<Self, D::Error>
1565 where D: Deserializer<'de>
1566 { deserializer.deserialize_any(ValueVisitor) }
1567}
1568
1569#[derive(Clone, Debug)]
1571pub enum Object
1572{
1573 String(String),
1575 IntRange(i64, i64, i64),
1577 FloatRange(f32, f32, f32),
1579 Matrix(Matrix),
1581 Fun(Vec<String>, String, Arc<Fun>),
1583 BuiltinFun(String, fn(&mut Interp, &mut Env, &[Value]) -> Result<Value>),
1585 MatrixArray(usize, usize, TransposeFlag, Vec<f32>),
1587 MatrixRowSlice(Arc<Object>, usize),
1589 Error(String, String),
1591 WindowId(WindowId),
1593}
1594
1595impl Object
1596{
1597 fn priv_eq(&self, object: &Object) -> Result<bool>
1598 {
1599 match (self, object) {
1600 (Object::String(s), Object::String(t)) => Ok(s == t),
1601 (Object::IntRange(a, b, c), Object::IntRange(d, e, f)) => Ok(a == d && b == e && c == f),
1602 (Object::FloatRange(a, b, c), Object::FloatRange(d, e, f)) => Ok(a == d && b == e && c == f),
1603 (Object::Fun(idents, ident, fun), Object::Fun(idents2, ident2, fun2)) => Ok(idents == idents2 && ident == ident2 && Arc::ptr_eq(fun, fun2)),
1604 (Object::BuiltinFun(ident, f), Object::BuiltinFun(ident2, g)) => Ok(ident == ident2 && f == g),
1605 (Object::MatrixArray(a_row_count, a_col_count, a_transpose_flag, xs), Object::MatrixArray(b_row_count, b_col_count, b_transpose_flag, ys)) => {
1606 if a_row_count != b_row_count || a_col_count != b_col_count {
1607 return Ok(false);
1608 }
1609 for i in 0..(*a_row_count) {
1610 for j in 0..(*a_col_count) {
1611 let ak = match a_transpose_flag {
1612 TransposeFlag::NoTranspose => i * (*a_col_count) + j,
1613 TransposeFlag::Transpose => j * (*a_row_count) + i,
1614 };
1615 let bk = match b_transpose_flag {
1616 TransposeFlag::NoTranspose => i * (*b_col_count) + j,
1617 TransposeFlag::Transpose => j * (*b_row_count) + i,
1618 };
1619 match (xs.get(ak), ys.get(bk)) {
1620 (Some(x), Some(y)) => {
1621 if x != y {
1622 return Ok(false);
1623 }
1624 },
1625 (_, _) => return Err(Error::Interp(String::from("no element"))),
1626 }
1627 }
1628 }
1629 Ok(true)
1630 },
1631 (Object::MatrixRowSlice(matrix_array, ai), Object::MatrixRowSlice(matrix_array2, bi)) => {
1632 match (&**matrix_array, &**matrix_array2) {
1633 (Object::MatrixArray(a_row_count, a_col_count, a_transpose_flag, xs), Object::MatrixArray(b_row_count, b_col_count, b_transpose_flag, ys)) => {
1634 if a_col_count != b_col_count {
1635 return Ok(false);
1636 }
1637 for j in 0..(*a_col_count) {
1638 let ak = match a_transpose_flag {
1639 TransposeFlag::NoTranspose => (*ai) * (*a_col_count) + j,
1640 TransposeFlag::Transpose => j * (*a_row_count) + (*ai),
1641 };
1642 let bk = match b_transpose_flag {
1643 TransposeFlag::NoTranspose => (*bi) * (*b_col_count) + j,
1644 TransposeFlag::Transpose => j * (*b_row_count) + (*bi),
1645 };
1646 match (xs.get(ak), ys.get(bk)) {
1647 (Some(x), Some(y)) => {
1648 if x != y {
1649 return Ok(false);
1650 }
1651 },
1652 (_, _) => return Err(Error::Interp(String::from("no element"))),
1653 }
1654 }
1655 Ok(true)
1656 },
1657 (_, _) => return Err(Error::Interp(String::from("invalid matrix array type")))
1658 }
1659 },
1660 (Object::Error(kind, msg), Object::Error(kind2, msg2)) => Ok(kind == kind2 && msg == msg2),
1661 (Object::WindowId(window_id), Object::WindowId(window_id2)) => Ok(window_id == window_id2),
1662 (_, _) => Ok(false),
1663 }
1664 }
1665
1666 fn priv_nearly_eq(&self, object: &Object, eps: f32) -> Result<bool>
1667 {
1668 match (self, object) {
1669 (Object::MatrixArray(a_row_count, a_col_count, a_transpose_flag, xs), Object::MatrixArray(b_row_count, b_col_count, b_transpose_flag, ys)) => {
1670 if a_row_count != b_row_count || a_col_count != b_col_count {
1671 return Ok(false);
1672 }
1673 for i in 0..(*a_row_count) {
1674 for j in 0..(*a_col_count) {
1675 let ak = match a_transpose_flag {
1676 TransposeFlag::NoTranspose => i * (*a_col_count) + j,
1677 TransposeFlag::Transpose => j * (*a_row_count) + i,
1678 };
1679 let bk = match b_transpose_flag {
1680 TransposeFlag::NoTranspose => i * (*b_col_count) + j,
1681 TransposeFlag::Transpose => j * (*b_row_count) + i,
1682 };
1683 match (xs.get(ak), ys.get(bk)) {
1684 (Some(x), Some(y)) => {
1685 if !nearly_eq(*x, *y, eps) {
1686 return Ok(false);
1687 }
1688 },
1689 (_, _) => return Err(Error::Interp(String::from("no element"))),
1690 }
1691 }
1692 }
1693 Ok(true)
1694 },
1695 (Object::MatrixRowSlice(matrix_array, ai), Object::MatrixRowSlice(matrix_array2, bi)) => {
1696 match (&**matrix_array, &**matrix_array2) {
1697 (Object::MatrixArray(a_row_count, a_col_count, a_transpose_flag, xs), Object::MatrixArray(b_row_count, b_col_count, b_transpose_flag, ys)) => {
1698 if a_col_count != b_col_count {
1699 return Ok(false);
1700 }
1701 for j in 0..(*a_col_count) {
1702 let ak = match a_transpose_flag {
1703 TransposeFlag::NoTranspose => (*ai) * (*a_col_count) + j,
1704 TransposeFlag::Transpose => j * (*a_row_count) + (*ai),
1705 };
1706 let bk = match b_transpose_flag {
1707 TransposeFlag::NoTranspose => (*bi) * (*b_col_count) + j,
1708 TransposeFlag::Transpose => j * (*b_row_count) + (*bi),
1709 };
1710 match (xs.get(ak), ys.get(bk)) {
1711 (Some(x), Some(y)) => {
1712 if !nearly_eq(*x, *y, eps) {
1713 return Ok(false);
1714 }
1715 },
1716 (_, _) => return Err(Error::Interp(String::from("no element"))),
1717 }
1718 }
1719 Ok(true)
1720 },
1721 (_, _) => return Err(Error::Interp(String::from("invalid matrix array type")))
1722 }
1723 },
1724 (_, _) => self.priv_eq(object),
1725 }
1726 }
1727}
1728
1729#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
1733pub enum TransposeFlag
1734{
1735 NoTranspose,
1737 Transpose,
1739}
1740
1741#[derive(Clone, Debug)]
1743pub enum MutObject
1744{
1745 Array(Vec<Value>),
1747 Struct(BTreeMap<String, Value>),
1749}
1750
1751impl MutObject
1752{
1753 fn priv_eq<F>(&self, object: &MutObject, mut f: F) -> Result<bool>
1754 where F: FnMut(&Value, &Value) -> Result<bool>
1755 {
1756 match (self, object) {
1757 (MutObject::Array(elems), MutObject::Array(elems2)) => {
1758 if elems.len() != elems2.len() {
1759 return Ok(false);
1760 }
1761 for (elem, elem2) in elems.iter().zip(elems2.iter()) {
1762 if !f(elem, elem2)? {
1763 return Ok(false);
1764 }
1765 }
1766 Ok(true)
1767 },
1768 (MutObject::Struct(fields), MutObject::Struct(fields2)) => {
1769 let idents: BTreeSet<&String> = fields.keys().collect();
1770 let idents2: BTreeSet<&String> = fields2.keys().collect();
1771 if idents != idents2 {
1772 return Ok(false);
1773 }
1774 for ident in &idents {
1775 match (fields.get(*ident), fields2.get(*ident)) {
1776 (Some(field), Some(field2)) => {
1777 if !f(field, field2)? {
1778 return Ok(false);
1779 }
1780 },
1781 (_, _) => return Err(Error::Interp(String::from("no field"))),
1782 }
1783 }
1784 Ok(true)
1785 },
1786 (_, _) => Ok(false),
1787 }
1788 }
1789
1790 fn priv_nearly_eq<F>(&self, object: &MutObject, eps: f32, mut f: F) -> Result<bool>
1791 where F: FnMut(&Value, &Value, f32) -> Result<bool>
1792 {
1793 match (self, object) {
1794 (MutObject::Array(elems), MutObject::Array(elems2)) => {
1795 if elems.len() != elems2.len() {
1796 return Ok(false);
1797 }
1798 for (elem, elem2) in elems.iter().zip(elems2.iter()) {
1799 if !f(elem, elem2, eps)? {
1800 return Ok(false);
1801 }
1802 }
1803 Ok(true)
1804 },
1805 (MutObject::Struct(fields), MutObject::Struct(fields2)) => {
1806 let idents: BTreeSet<&String> = fields.keys().collect();
1807 let idents2: BTreeSet<&String> = fields2.keys().collect();
1808 if idents != idents2 {
1809 return Ok(false);
1810 }
1811 for ident in &idents {
1812 match (fields.get(*ident), fields2.get(*ident)) {
1813 (Some(field), Some(field2)) => {
1814 if !f(field, field2, eps)? {
1815 return Ok(false);
1816 }
1817 },
1818 (_, _) => return Err(Error::Interp(String::from("no field"))),
1819 }
1820 }
1821 Ok(true)
1822 },
1823 (_, _) => Ok(false),
1824 }
1825 }
1826}
1827
1828#[derive(Clone, Debug)]
1830pub struct Iter<'a>
1831{
1832 iter_enum: IterEnum<'a>,
1833}
1834
1835impl<'a> Iter<'a>
1836{
1837 fn new(iter_enum: IterEnum<'a>) -> Self
1838 { Iter { iter_enum, } }
1839}
1840
1841impl<'a> Iterator for Iter<'a>
1842{
1843 type Item = Result<Value>;
1844
1845 fn next(&mut self) -> Option<Self::Item>
1846 {
1847 match &mut self.iter_enum {
1848 IterEnum::String(cs) => {
1849 match cs.next() {
1850 Some(c) => {
1851 let mut s = String::new();
1852 s.push(c);
1853 Some(Ok(Value::Object(Arc::new(Object::String(s)))))
1854 },
1855 None => None,
1856 }
1857 },
1858 IterEnum::IntRange(from, to, step, is_stopped) => {
1859 if !*is_stopped {
1860 let current = if *step > 0 {
1861 let tmp_current = if *from <= *to {
1862 Some(*from)
1863 } else {
1864 None
1865 };
1866 if *from < *to {
1867 match from.checked_add(*step) {
1868 Some(tmp_from) => *from = tmp_from,
1869 None => {
1870 *is_stopped = true;
1871 return Some(Err(Error::Interp(String::from("overflow in iteration"))));
1872 },
1873 }
1874 } else {
1875 *is_stopped = true;
1876 }
1877 tmp_current
1878 } else if *step < 0 {
1879 let tmp_current = if *from >= *to {
1880 Some(*from)
1881 } else {
1882 None
1883 };
1884 if *from > *to {
1885 match from.checked_add(*step) {
1886 Some(tmp_from) => *from = tmp_from,
1887 None => {
1888 *is_stopped = true;
1889 return Some(Err(Error::Interp(String::from("overflow in iteration"))));
1890 },
1891 }
1892 } else {
1893 *is_stopped = true;
1894 }
1895 tmp_current
1896 } else {
1897 *is_stopped = true;
1898 return Some(Err(Error::Interp(String::from("range step is zero"))));
1899 };
1900 match current {
1901 Some(current) => Some(Ok(Value::Int(current))),
1902 None => None,
1903 }
1904 } else {
1905 None
1906 }
1907 },
1908 IterEnum::FloatRange(from, to, step, is_stopped) => {
1909 if !*is_stopped {
1910 let current = if *step > 0.0 {
1911 let tmp_current = if *from <= *to {
1912 Some(*from)
1913 } else {
1914 None
1915 };
1916 if *from < *to {
1917 *from += *step;
1918 } else {
1919 *is_stopped = true;
1920 }
1921 tmp_current
1922 } else if *step < 0.0 {
1923 let tmp_current = if *from >= *to {
1924 Some(*from)
1925 } else {
1926 None
1927 };
1928 if *from > *to {
1929 *from += *step;
1930 } else {
1931 *is_stopped = true;
1932 }
1933 tmp_current
1934 } else {
1935 *is_stopped = true;
1936 return Some(Err(Error::Interp(String::from("range step is zero"))));
1937 };
1938 match current {
1939 Some(current) => Some(Ok(Value::Float(current))),
1940 None => None,
1941 }
1942 } else {
1943 None
1944 }
1945 },
1946 IterEnum::MatrixArray(matrix_array, i, is_stopped) => {
1947 if !*is_stopped {
1948 match &**matrix_array {
1949 Object::MatrixArray(row_count, _, _, _) => {
1950 if *i < *row_count {
1951 let j = *i;
1952 *i += 1;
1953 Some(Ok(Value::Object(Arc::new(Object::MatrixRowSlice(matrix_array.clone(), j)))))
1954 } else {
1955 None
1956 }
1957 },
1958 _ => {
1959 *is_stopped = true;
1960 Some(Err(Error::Interp(String::from("invalid matrix array type"))))
1961 },
1962 }
1963 } else {
1964 None
1965 }
1966 },
1967 IterEnum::MatrixRowSlice(matrix_array, i, j, is_stopped) => {
1968 if !*is_stopped {
1969 match &**matrix_array {
1970 Object::MatrixArray(row_count, col_count, transpose_flag, xs) => {
1971 if *j < *col_count {
1972 let k = match transpose_flag {
1973 TransposeFlag::NoTranspose => (*i) * (*col_count) + (*j),
1974 TransposeFlag::Transpose => (*j) * (*row_count) + (*i),
1975 };
1976 *j += 1;
1977 match xs.get(k) {
1978 Some(x) => Some(Ok(Value::Float(*x))),
1979 None => {
1980 *is_stopped = true;
1981 Some(Err(Error::Interp(String::from("invalid index"))))
1982 },
1983 }
1984 } else {
1985 None
1986 }
1987 },
1988 _ => {
1989 *is_stopped = true;
1990 Some(Err(Error::Interp(String::from("invalid matrix array type"))))
1991 },
1992 }
1993 } else {
1994 None
1995 }
1996 },
1997 IterEnum::Array(array, i, is_stopped) => {
1998 if !*is_stopped {
1999 match rw_lock_read(&**array) {
2000 Ok(array_g) => {
2001 match &*array_g {
2002 MutObject::Array(elems) => {
2003 if *i < elems.len() {
2004 let j = *i;
2005 *i += 1;
2006 match elems.get(j) {
2007 Some(elem) => Some(Ok(elem.clone())),
2008 None => {
2009 *is_stopped = true;
2010 Some(Err(Error::Interp(String::from("invalid index"))))
2011 },
2012 }
2013 } else {
2014 None
2015 }
2016 },
2017 _ => {
2018 *is_stopped = true;
2019 Some(Err(Error::Interp(String::from("invalid array type"))))
2020 },
2021 }
2022 },
2023 Err(err) => {
2024 *is_stopped = true;
2025 Some(Err(err))
2026 },
2027 }
2028 } else {
2029 None
2030 }
2031 },
2032 }
2033 }
2034}
2035
2036#[derive(Clone, Debug)]
2037enum IterEnum<'a>
2038{
2039 String(Chars<'a>),
2040 IntRange(i64, i64, i64, bool),
2041 FloatRange(f32, f32, f32, bool),
2042 MatrixArray(Arc<Object>, usize, bool),
2043 MatrixRowSlice(Arc<Object>, usize, usize, bool),
2044 Array(Arc<RwLock<MutObject>>, usize, bool),
2045}
2046
2047#[cfg(test)]
2048mod tests;