M src/interpreter/interpreter_tests.rs => src/interpreter/interpreter_tests.rs +21 -0
@@ 306,3 306,24 @@ fn pointer_works() {
assert_eq!(popped, 3);
}
+
+#[test]
+#[ignore]
+fn switch_works() { }
+
+#[test]
+#[ignore]
+fn roll_works() { }
+
+#[test]
+fn get_utf8_char() {
+ let buffer = "€";
+ assert_eq!(Interpreter::get_utf8_char(&buffer), [0xE2, 0x82, 0xAC]);
+}
+
+#[test]
+fn utf8_to_unicode() {
+ let bytes = [0xE2, 0x82, 0xAC]; // €
+ assert_eq!(Interpreter::utf8_to_unicode(&bytes), 0x20AC);
+
+}
M src/interpreter/mod.rs => src/interpreter/mod.rs +88 -0
@@ 186,6 186,56 @@ impl Interpreter {
}
+ Op::Switch => {
+ if let Some(val) = self.stack.pop() {
+ for _ in 0..(val.abs()) {
+ let new_dir = self.head().codel_chooser().toggle();
+ self.head_as_mut().set_codel_chooser(new_dir);
+ }
+ }
+ Ok(())
+
+ }
+
+ Op::Duplicate => {
+ if let Some(val) = self.stack.pop() {
+ self.stack.push(val);
+ self.stack.push(val);
+ }
+ Ok(())
+ }
+
+ Op::Roll => {
+ if self.stack.len() < 3 {
+ return Err(Error::new(ErrorKind::InvalidInput, "Not enough values on stack!"));
+ }
+
+ let first_pop = self.stack.pop().unwrap();
+ let second_pop = self.stack.pop().unwrap();
+ if second_pop < 0 {
+ // depth is negative -> ignore
+ return Ok(());
+ }
+
+ if first_pop < 0 {
+ for _ in 0..(first_pop.abs()) {
+ let front = self.stack.remove(0);
+ self.stack.insert(second_pop as usize, front);
+ }
+ }
+ else {
+ for _ in 0..first_pop {
+ let third_pop = self.stack.pop().unwrap();
+ self.stack.insert(self.stack.len() - second_pop as usize, third_pop);
+ }
+ }
+ Ok(())
+
+ }
+
+ // Op::InNum => {
+
+ // }
_ => {Ok(())}
@@ 269,6 319,44 @@ impl Interpreter {
}
+ fn get_utf8_char(buffer: &str) -> &[u8] {
+
+ let bytes = buffer.as_bytes();
+ let num_bytes = bytes[0].reverse_bits().trailing_ones() as usize;
+
+
+ return &bytes[..num_bytes];
+
+
+ }
+
+ fn utf8_to_unicode(bytes: &[u8]) -> isize {
+ let num_bytes = bytes[0].reverse_bits().trailing_ones() as usize;
+
+ let mut code_point: Vec<&str> = vec!();
+ let byte_strs: Vec<String> = bytes.iter().map(|byte| format!("{:b}", byte)).collect();
+ let header_str = &byte_strs[0];
+ code_point.push(&header_str[num_bytes+1..]);
+
+ for i in 1..num_bytes {
+ code_point.push(&byte_strs[i][2..]);
+ }
+
+
+ let mut code_point_num: isize = 0;
+ let mut multiplier = 1;
+
+ for bit in code_point.join("").chars().rev() {
+ code_point_num += (bit.to_digit(2).unwrap() as isize) * multiplier;
+ multiplier *= 2;
+
+ }
+
+ code_point_num
+
+ }
+
+
}