Skip to content

Commit

Permalink
Format, some fixes and add tests for scopes
Browse files Browse the repository at this point in the history
  • Loading branch information
Sellig6792 committed Dec 27, 2022
1 parent d1e09d2 commit 723fb9e
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 60 deletions.
21 changes: 6 additions & 15 deletions src/evaluation/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,27 @@ use crate::ast::instructions::{InstructionTrait, InstructionType};
use crate::evaluation::{Cell, Scopes};

pub struct Evaluator<T: InstructionTrait<T>>
where
T: Clone,
where
T: Clone,
{
program: Vec<T>,

scopes: Scopes<T>,
scope_pointer: usize,

memory_pointer: usize,
input: Vec<u8>,
output_buffer: Vec<u8>,
}

impl<T: InstructionTrait<T> + 'static> Evaluator<T>
where
T: Clone,
where
T: Clone,
{
pub fn new(instructions: Vec<T>) -> Evaluator<T> {
Evaluator {
program: instructions,

scopes: Scopes::new(),

scope_pointer: 0,

memory_pointer: 0,

input: vec![],
output_buffer: vec![],
}
Expand Down Expand Up @@ -105,13 +99,10 @@ where
}

InstructionType::MoveLeftScope => {
self.scopes
.move_left_scope(instruction.get_amount() as usize);
self.scopes.move_left_scope(instruction.get_amount() as usize);
}
InstructionType::MoveRightScope => {
if self.scope_pointer != self.scopes.len() - 1 {
self.scope_pointer += 1;
}
self.scopes.move_right_scope(instruction.get_amount() as usize);
}

InstructionType::Random => {
Expand Down
147 changes: 103 additions & 44 deletions src/evaluation/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::evaluation::Cell;

#[derive(Clone)]
pub struct Scope<T: InstructionTrait<T>> {
memory: Vec<Cell>,
function_memory: Vec<T>,
memory: Box<[Cell; 30000]>,
function_memory: Box<[T; 30000]>,
}

impl<T: InstructionTrait<T>> Scope<T> {
Expand All @@ -16,29 +16,17 @@ impl<T: InstructionTrait<T>> Scope<T> {
}

Scope {
memory: vec![Cell::new(0); 30000],
memory: Box::new([Cell::new(0); 30000]),
function_memory: match function_memory_vec.try_into() {
Ok(function_memory) => function_memory,
Err(_) => panic!("Could not convert Vec to Box<[T; 30000]>"),
},
}
}

pub fn get_cell(&self, index: usize) -> &Cell {
&self.memory[index]
}

pub fn get_cell_mut(&mut self, index: usize) -> &mut Cell {
&mut self.memory[index]
}

pub fn get_function(&self, index: usize) -> &T {
&self.function_memory[index]
}

pub fn get_function_mut(&mut self, index: usize) -> &mut T {
&mut self.function_memory[index]
}
}

pub struct Scopes<T>
Expand Down Expand Up @@ -82,38 +70,26 @@ where
self.scopes.get(index)
}

pub fn get_scope_at_mut(&mut self, index: usize) -> Option<&mut Scope<T>> {
self.scopes.get_mut(index)
}
pub fn move_right(&mut self, amount: usize) {
let sum: usize = self.index + amount;

pub fn len(&self) -> usize {
self.scopes.len()
}
self.index = if sum > 29999 {
sum - 30000
} else {
sum
};

pub fn move_right(&mut self, amount: usize) {
// If the index exceeds the memory size, add a new cell to the memory and set the index to the new cell
let new_index = self.index + amount;

match self.get_cell_at(new_index) {
Some(_) => self.index = new_index,
None => {
let exceed = new_index - self.get_current_scope().memory.len();
let new_cells = vec![Cell::new(0); exceed];
self.get_current_scope_mut().memory.extend(new_cells);
self.index = new_index;
}
}
}

pub fn move_left(&mut self, amount: usize) {
// If the index is less than 0, set the index to the last cell
let sub: isize = self.index as isize - amount as isize;

self.index = if sub < 0 {
self.get_current_scope().memory.len() - (sub.abs() as usize - 1) - 1
30000 - (sub.abs() as usize)
} else {
sub as usize
};
}
}

pub fn move_right_scope(&mut self, amount: usize) {
Expand Down Expand Up @@ -150,18 +126,10 @@ where
self.get_current_scope_mut().memory.get_mut(index)
}

pub fn get_current_function(&self) -> &T {
self.get_function_at(self.index).unwrap()
}

pub fn get_current_function_mut(&mut self) -> &mut T {
self.get_function_at_mut(self.index).unwrap()
}

pub fn get_function_at(&self, index: usize) -> Option<&T> {
self.get_current_scope().function_memory.get(index)
}

pub fn get_function_at_mut(&mut self, index: usize) -> Option<&mut T> {
self.get_current_scope_mut().function_memory.get_mut(index)
}
Expand All @@ -176,3 +144,94 @@ where
self.scope_index -= 1;
}
}


#[cfg(test)]
mod tests {
use crate::ast::instructions::Instruction;
use super::*;

#[test]
fn test_move_right() {
let mut scopes = Scopes::<Instruction>::new();

scopes.move_right(1);
assert_eq!(scopes.get_index(), 1);
}

#[test]
fn test_move_left() {
let mut scopes = Scopes::<Instruction>::new();

scopes.index = 5;
scopes.move_left(1);
assert_eq!(scopes.get_index(), 4);
}

#[test]
fn test_move_right_overflow() {
let mut scopes = Scopes::<Instruction>::new();

scopes.index = 29999;
scopes.move_right(5);
assert_eq!(scopes.get_index(), 4);
}

#[test]
fn test_move_left_overflow() {
let mut scopes = Scopes::<Instruction>::new();

scopes.index = 5;
scopes.move_left(10);
assert_eq!(scopes.get_index(), 29995);
}

#[test]
fn test_move_right_scope_if_only_one_scope() {
let mut scopes = Scopes::<Instruction>::new();

scopes.move_right_scope(1);
assert_eq!(scopes.get_scope_index(), 0);
}

#[test]
fn test_move_right_scope_if_multiple_scopes() {
let mut scopes = Scopes::<Instruction>::new();

scopes.push();
scopes.move_left_scope(1); // Because .push() add 1 to the scope index

scopes.move_right_scope(1);
assert_eq!(scopes.get_scope_index(), 1);
}

#[test]
fn test_move_right_scope_if_multiple_scopes_overflow() {
let mut scopes = Scopes::<Instruction>::new();

scopes.push();
scopes.move_left_scope(1); // Because .push() add 1 to the scope index

scopes.move_right_scope(2);
assert_eq!(scopes.get_scope_index(), 1);
}

#[test]
fn test_move_left_scope_if_at_first_scope() {
let mut scopes = Scopes::<Instruction>::new();

scopes.move_left_scope(1);
assert_eq!(scopes.get_scope_index(), 0);
}

#[test]
fn test_move_left_scope_if_multiple_scopes() {
let mut scopes = Scopes::<Instruction>::new();

scopes.push();
scopes.move_left_scope(1); // Because .push() add 1 to the scope index

scopes.move_left_scope(8);
assert_eq!(scopes.get_scope_index(), 0);
}
}
1 change: 0 additions & 1 deletion src/optimization/optimizer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::ast::instructions::{Instruction, InstructionTrait, InstructionType};
use std::ops::Deref;

use crate::optimization::optimized_instructions::OptimizedInstruction;

Expand Down

0 comments on commit 723fb9e

Please sign in to comment.