Heap bonus!
This commit is contained in:
@@ -8,8 +8,9 @@ authors = ["Jur van den Berg <Jurl.berg@gmail.com>"]
|
|||||||
[features]
|
[features]
|
||||||
default = ["bonus", "extra"]
|
default = ["bonus", "extra"]
|
||||||
|
|
||||||
bonus = ["bonus:network"]
|
bonus = ["bonus:network", "bonus:heap"]
|
||||||
"bonus:network" = []
|
"bonus:network" = []
|
||||||
|
"bonus:heap" = []
|
||||||
|
|
||||||
extra = ["extra:sleep"]
|
extra = ["extra:sleep"]
|
||||||
"extra:sleep" = []
|
"extra:sleep" = []
|
||||||
|
|||||||
25
src/heap.rs
Normal file
25
src/heap.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,9 @@ pub mod pool;
|
|||||||
pub mod frame;
|
pub mod frame;
|
||||||
pub mod netstack;
|
pub mod netstack;
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:heap")]
|
||||||
|
pub mod heap;
|
||||||
|
|
||||||
type Result<T> = ::std::result::Result<T, &'static str>;
|
type Result<T> = ::std::result::Result<T, &'static str>;
|
||||||
|
|
||||||
pub use machine::Machine;
|
pub use machine::Machine;
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ use Result;
|
|||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:heap")]
|
||||||
|
use heap::Heap;
|
||||||
|
|
||||||
const MAGIC_HEADER:u32 = 0x1DEA_DFAD;
|
const MAGIC_HEADER:u32 = 0x1DEA_DFAD;
|
||||||
const ANTI_BS_SIZE:usize = 0xFFFF;
|
const ANTI_BS_SIZE:usize = 0xFFFF;
|
||||||
|
|
||||||
@@ -23,6 +26,9 @@ pub struct Machine {
|
|||||||
pub frame: Vec<Frame>,
|
pub frame: Vec<Frame>,
|
||||||
pub net: NetStack,
|
pub net: NetStack,
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:heap")]
|
||||||
|
pub heap: Heap,
|
||||||
|
|
||||||
pub stream_in: Box<Read>,
|
pub stream_in: Box<Read>,
|
||||||
pub stream_out: Rc<Mutex<Write>>,
|
pub stream_out: Rc<Mutex<Write>>,
|
||||||
|
|
||||||
@@ -36,9 +42,13 @@ impl Machine {
|
|||||||
pool,
|
pool,
|
||||||
block,
|
block,
|
||||||
frame: vec![Frame::new(ANTI_BS_SIZE)],
|
frame: vec![Frame::new(ANTI_BS_SIZE)],
|
||||||
net: NetStack::new(),
|
|
||||||
stream_in: Box::new(::std::io::stdin()),
|
stream_in: Box::new(::std::io::stdin()),
|
||||||
stream_out: Rc::new(Mutex::new(::std::io::stdout())),
|
stream_out: Rc::new(Mutex::new(::std::io::stdout())),
|
||||||
|
|
||||||
|
net: NetStack::new(),
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:heap")]
|
||||||
|
heap: Heap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
src/ops.rs
42
src/ops.rs
@@ -53,6 +53,13 @@ pub fn num_to_op(op: u8) -> Operation {
|
|||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus:network")]
|
||||||
0xE5 => Operation::Op("NETCLOSE", netclose),
|
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)
|
x => Operation::Invalid(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,3 +290,38 @@ fn netout(machine: &mut Machine) -> Result<()> {
|
|||||||
fn netclose(machine: &mut Machine) -> Result<()> {
|
fn netclose(machine: &mut Machine) -> Result<()> {
|
||||||
machine.net.close()
|
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
36
tests/bonusheap.rs
Normal 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");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user