use osiris_data::data::atomic::Word;
use osiris_data::data::composite::Array;
use osiris_data::data::identification::Identifier;
use crate::register::{RegisterId, RegisterRange, REGISTERS_IN_BANK};
pub type VectorApplication = fn(&[Number]) -> Number;
#[derive(Copy, Clone, Debug, Default)]
pub struct Number(f64);
impl Number {
pub fn new(data: f64) -> Self { Self(data) }
pub fn to_f64(&self) -> f64 { self.0 }
pub fn from_u64(data: u64) -> Self { Self::new(f64::from_bits(data)) }
pub fn from_word(data: Word) -> Self { Self::new(f64::from_bits(data.to_u64())) }
pub fn to_u64(&self) -> u64 { self.0.to_bits() }
pub fn to_word(&self) -> Word { Word::new(self.to_u64()) }
pub fn from_words_slice(from: &[Word]) -> Vec<Self> {
let mut slice = vec![];
for e in from {
slice.push(Self::from_word(*e));
}
slice
}
pub fn slice_to_array(from: &[Self]) -> Array {
let mut array:Array = Array::new(0);
for e in from {
array.push(e.to_word());
}
array
}
}
#[derive(Clone, Debug)]
pub struct Vector {
registers: Vec<Number>,
}
impl Vector {
pub fn new() -> Self {
Self { registers: vec![Number::default(); REGISTERS_IN_BANK] }
}
pub fn set(&mut self, register: RegisterId, number: Number) {
if register.to_usize() > REGISTERS_IN_BANK {
return;
}
self.registers[register.to_usize()] = number;
}
pub fn get(&self, register: RegisterId) -> Number {
self.registers[register.to_usize()]
}
pub fn apply(&self, range: RegisterRange, function: VectorApplication) -> Number {
let slice = &self.registers[range.to_usize_range()];
function(slice)
}
pub fn slice(&self, range: RegisterRange) -> &[Number] {
&self.registers[range.to_usize_range()]
}
pub fn copy(&mut self, to: RegisterId, slice: &[Number]) {
let mut index = to.to_usize();
for w in slice {
self.registers[index] = *w;
index += 1;
}
}
}
impl Default for Vector {
fn default() -> Self { Self::new() }
}