mech_interpreter/stdlib/
range.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#[macro_use]
use crate::stdlib::*;
use std::iter::Step;

// ----------------------------------------------------------------------------
// Range Library
// ----------------------------------------------------------------------------

// Exclusive ------------------------------------------------------------------

#[derive(Debug)]
struct RangeExclusiveScalar<T> {
  max: Ref<T>,
  min: Ref<T>,
  out: Ref<RowDVector<T>>,
}

impl<T> MechFunction for RangeExclusiveScalar<T>
where
    T: Copy + Debug + Clone + Sync + Send + Step + PartialEq + 'static,
    Ref<RowDVector<T>>: ToValue
{
  fn solve(&self) {
    let max_ptr = self.max.as_ptr();
    let min_ptr = self.min.as_ptr();
    let out_ptr = self.out.as_ptr();
    
    unsafe {
      let rng = (*min_ptr..*max_ptr).collect::<Vec<T>>();
      *out_ptr = RowDVector::from_vec(rng);
    }
  }
  fn out(&self) -> Value { self.out.to_value() }
  fn to_string(&self) -> String { format!("{:?}", self)}
}

pub struct RangeExclusive {}

impl NativeFunctionCompiler for RangeExclusive {
  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
    if arguments.len() != 2 {
      return Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
    }
    match (arguments[0].clone(), arguments[1].clone()) {
      (Value::I8(min),   Value::I8(max))   => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::I16(min),  Value::I16(max))  => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::I32(min),  Value::I32(max))  => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::I64(min),  Value::I64(max))  => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::I128(min), Value::I128(max)) => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U8(min),   Value::U8(max))   => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U16(min),  Value::U16(max))  => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U32(min),  Value::U32(max))  => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U64(min),  Value::U64(max))  => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U128(min), Value::U128(max)) => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::F32(min),  Value::F32(max))  => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,F32::new(0.0)))})),
      (Value::F64(min),  Value::F64(max))  => Ok(Box::new(RangeExclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,F64::new(0.0)))})),
      x => Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}),
    }
  }
}

// Inclusive ------------------------------------------------------------------

#[derive(Debug)]
struct RangeInclusiveScalar<T> {
  max: Ref<T>,
  min: Ref<T>,
  out: Ref<RowDVector<T>>,
}

impl<T> MechFunction for RangeInclusiveScalar<T>
where
    T: Copy + Debug + Clone + Sync + Send + Step + PartialEq + 'static,
    Ref<RowDVector<T>>: ToValue
{
  fn solve(&self) {
    let max_ptr = self.max.as_ptr();
    let min_ptr = self.min.as_ptr();
    let out_ptr = self.out.as_ptr();
    
    unsafe {
      let rng = (*min_ptr..=*max_ptr).collect::<Vec<T>>();
      *out_ptr = RowDVector::from_vec(rng);
    }
  }
  fn out(&self) -> Value { self.out.to_value() }
  fn to_string(&self) -> String { format!("{:?}", self)}
}

pub struct RangeInclusive {}

impl NativeFunctionCompiler for RangeInclusive {
  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
    if arguments.len() != 2 {
      return Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
    }
    match (arguments[0].clone(), arguments[1].clone()) {
      (Value::I8(min),   Value::I8(max))   => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::I16(min),  Value::I16(max))  => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::I32(min),  Value::I32(max))  => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::I64(min),  Value::I64(max))  => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::I128(min), Value::I128(max)) => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U8(min),   Value::U8(max))   => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U16(min),  Value::U16(max))  => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U32(min),  Value::U32(max))  => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U64(min),  Value::U64(max))  => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::U128(min), Value::U128(max)) => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,0))})),
      (Value::F32(min),  Value::F32(max))  => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,F32::new(0.0)))})),
      (Value::F64(min),  Value::F64(max))  => Ok(Box::new(RangeInclusiveScalar{max,min, out: new_ref(RowDVector::from_element(1,F64::new(0.0)))})),
      x => Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind})
    }
  }
}