use super::*;
pub type CallError = mtk::Error;
#[derive(Clone)]
pub struct Routine {
data: Vec<i128>,
env: *mut Env
}
impl Routine {
pub fn new(env: &mut Env) -> Routine {
Routine {
data: Vec::new(),
env
}
}
pub fn from(env: &mut Env, data: Vec<i128>) -> Routine {
Routine { data, env }
}
pub fn push(&mut self, byte: i128) {
self.data.push(byte)
}
pub fn pop(&mut self) -> Option<i128> {
self.data.pop()
}
pub fn get(&self, index: usize) -> Option<&i128> {
self.data.get(index)
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut i128> {
self.data.get_mut(index)
}
pub unsafe fn call(&mut self, argv: Vec<usize>) -> Result<Result<usize, usize>, CallError> {
let mut pc = 0;
let mut c: i128 = 0;
while pc < self.data.len() {
if self.data[pc] == ALLOC {
pc += 1;
let l = match self.data.get(pc) {
Some(some) => *some,
None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
};
c = match (*self.env).alloc(l as usize) {
Ok(ok) => ok as i128,
Err(err) => return Err(err.clone())
};
} else if self.data[pc] == DEALLOC {
pc += 1;
let l = match self.data.get(pc) {
Some(some) => *some,
None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
};
c = match (*self.env).dealloc(l as usize) {
Ok(ok) => ok as i128,
Err(err) => return Err(err.clone())
};
} else if self.data[pc] == THROW {
pc += 1;
let l = match self.data.get(pc) {
Some(some) => *some,
None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
};
return Ok(Err(l as usize));
} else if self.data[pc] == RETURN {
pc += 1;
let l = match self.data.get(pc) {
Some(some) => *some,
None => return Err(CallError::from(format!("can not get from index {}", pc + 1)))
};
return Ok(Ok(l as usize));
} else {
pc += 1;
}
}
Ok(Ok(0))
}
}