use super::*;
pub type RTError = mtk::BasicError;
pub struct Routine {
bytes: Vec<Byte>,
mems: *mut Vec<*mut Mem>
}
impl Routine {
pub fn new(mems: &mut Vec<*mut Mem>) -> Routine {
Routine {
bytes: Vec::new(),
mems
}
}
pub fn from(bytes: Vec<Byte>, mems: &mut Vec<*mut Mem>) -> Routine {
Routine { bytes, mems }
}
pub fn push(&mut self, byte: Byte) {
self.bytes.push(byte);
}
pub fn push_vec(&mut self, bytes: Vec<Byte>) {
for byte in bytes {
self.bytes.push(byte);
}
}
pub fn call(&mut self) -> Option<RTError> {
let mut b: Byte;
let mut i: usize = 0;
while i != self.len() {
b = match self.bytes.get(i) {
Some(some) => *some,
None => return Some(RTError::with_message(format!("{}", i)))
};
if b == SYS_EXIT {
break;
} else if b == SYS_WRITE {
i = i + 1;
let l = match self.bytes.get(i) {
Some(some) => *some,
None => return Some(RTError::with_message(format!("{}", i)))
};
i = i + 1;
let r = match self.bytes.get(i) {
Some(some) => *some,
None => return Some(RTError::with_message(format!("{}", i)))
};
let raw_copy = unsafe {
match (*self.mems).get(r as usize) {
Some(some) => (**some).clone_into_vec(),
None => return Some(RTError::with_message(format!("{}", i)))
}
};
let mut string: String = String::new();
for byte in raw_copy {
string.push(byte as u8 as char);
}
if l == stdout() {
print!("{}", string);
} else if l == stderr() {
print!("{}", string);
} else {
return Some(RTError::with_message(format!("{}: SYS_WRITE: unknown output device pointer {}", i, l)));
}
}
}
None
}
pub fn len(&self) -> usize {
self.bytes.len()
}
pub fn clone_into_vec(&self) -> Vec<Byte> {
self.bytes.clone()
}
}