Heap bonus!

This commit is contained in:
2018-05-23 14:22:01 +02:00
parent 7e044abb53
commit a652dc1a17
6 changed files with 120 additions and 3 deletions

View File

@@ -8,8 +8,9 @@ authors = ["Jur van den Berg <Jurl.berg@gmail.com>"]
[features]
default = ["bonus", "extra"]
bonus = ["bonus:network"]
bonus = ["bonus:network", "bonus:heap"]
"bonus:network" = []
"bonus:heap" = []
extra = ["extra:sleep"]
"extra:sleep" = []

25
src/heap.rs Normal file
View File

@@ -0,0 +1,25 @@
#[derive(Debug)]
pub struct Heap {
pub heaps: Vec<Vec<i32>>
}
impl Heap {
pub fn new() -> Heap {
Heap {
heaps: Vec::new()
}
}
pub fn len(&self) -> usize {
self.heaps.len()
}
pub fn get(&mut self, i: usize) -> &mut Vec<i32> {
&mut self.heaps[i]
}
pub fn alloc(&mut self, size: usize) -> usize {
self.heaps.push(vec![0; size]);
self.len() - 1
}
}

View File

@@ -8,6 +8,9 @@ pub mod pool;
pub mod frame;
pub mod netstack;
#[cfg(feature = "bonus:heap")]
pub mod heap;
type Result<T> = ::std::result::Result<T, &'static str>;
pub use machine::Machine;

View File

@@ -12,6 +12,9 @@ use Result;
use std::sync::Mutex;
use std::rc::Rc;
#[cfg(feature = "bonus:heap")]
use heap::Heap;
const MAGIC_HEADER:u32 = 0x1DEA_DFAD;
const ANTI_BS_SIZE:usize = 0xFFFF;
@@ -23,6 +26,9 @@ pub struct Machine {
pub frame: Vec<Frame>,
pub net: NetStack,
#[cfg(feature = "bonus:heap")]
pub heap: Heap,
pub stream_in: Box<Read>,
pub stream_out: Rc<Mutex<Write>>,
@@ -36,9 +42,13 @@ impl Machine {
pool,
block,
frame: vec![Frame::new(ANTI_BS_SIZE)],
net: NetStack::new(),
stream_in: Box::new(::std::io::stdin()),
stream_out: Rc::new(Mutex::new(::std::io::stdout())),
net: NetStack::new(),
#[cfg(feature = "bonus:heap")]
heap: Heap::new(),
}
}

View File

@@ -53,6 +53,13 @@ pub fn num_to_op(op: u8) -> Operation {
#[cfg(feature = "bonus:network")]
0xE5 => Operation::Op("NETCLOSE", netclose),
#[cfg(feature = "bonus:heap")]
0xD1 => Operation::Op("NEWARRAY", newarray),
#[cfg(feature = "bonus:heap")]
0xD2 => Operation::Op("IALOAD", iaload),
#[cfg(feature = "bonus:heap")]
0xD3 => Operation::Op("IASTORE", iastore),
x => Operation::Invalid(x)
}
}
@@ -282,4 +289,39 @@ fn netout(machine: &mut Machine) -> Result<()> {
#[cfg(feature = "bonus:network")]
fn netclose(machine: &mut Machine) -> Result<()> {
machine.net.close()
}
}
#[cfg(feature = "bonus:heap")]
fn newarray(machine: &mut Machine) -> Result<()> {
let size = machine.cur_stack().pop()? as usize;
let heapref = machine.heap.alloc(size);
machine.cur_stack().push(heapref as i32);
Ok(())
}
#[cfg(feature = "bonus:heap")]
fn iastore(machine: &mut Machine) -> Result<()> {
let heapref = machine.cur_stack().pop()? as usize;
let index = machine.cur_stack().pop()? as usize;
let value = machine.cur_stack().pop()?;
let heap = machine.heap.get(heapref);
heap[index] = value;
Ok(())
}
#[cfg(feature = "bonus:heap")]
fn iaload(machine: &mut Machine) -> Result<()> {
let heapref = machine.cur_stack().pop()? as usize;
let index = machine.cur_stack().pop()? as usize;
let value: i32;
{
let heap = machine.heap.get(heapref);
value = heap[index];
}
machine.cur_stack().push(value);
Ok(())
}

36
tests/bonusheap.rs Normal file
View File

@@ -0,0 +1,36 @@
extern crate rustijvm;
use std::fs::File;
use std::rc::Rc;
use std::sync::Mutex;
use std::io::{Cursor, Seek, SeekFrom, Read};
fn run_bfi(file: &str) -> String {
let file = File::open(file).expect("Missing bf file");
let rc = Rc::new(Mutex::new(Cursor::new(Vec::new())));
let mut machine = rustijvm::Machine::new_from_file("files/bonus/bfi.ijvm").unwrap();
machine.set_output(rc.clone());
machine.set_input(Box::new(file));
machine.run().unwrap();
let mut out = rc.lock().unwrap();
let mut string = String::new();
out.seek(SeekFrom::Start(0)).unwrap();
out.read_to_string(&mut string).unwrap();
string
}
#[test]
fn bonusheap_hello_world() {
let output = run_bfi("files/bonus/brainfuck/hello_world.bf");
assert_eq!(output, "Hello World!\n");
}
#[test]
fn bonusheap_dank() {
let output = run_bfi("files/bonus/brainfuck/dank.bf");
assert_eq!(output, "MoarTests");
}