1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
use json::dump_state;
#[derive(Serialize, Debug, Clone, Copy)]
pub enum Value {
Number{value: i32},
Character{value: char}
}
#[derive(Serialize, Debug, Clone, Copy)]
pub enum Location {
Cell(usize),
Address(usize)
}
#[derive(Serialize, Debug, Clone, Copy)]
pub enum Operation {
Inbox,
Outbox,
Add{cell: Location},
Sub{cell: Location},
CopyFrom{cell: Location},
CopyTo{cell: Location},
Label,
Jump{next_operation: usize},
JumpEqualsZero{next_operation: usize},
JumpNegative{next_operation: usize},
BumpPlus{cell: Location},
BumpMinus{cell: Location},
}
pub mod json;
pub mod memory;
pub mod operators;
pub mod state;
pub struct CodeIterator<'a> {
pub state: &'a mut state::InternalState,
pub operations: Vec<Operation>,
has_errored: bool,
dump_file_path: &'a str
}
impl<'a> CodeIterator<'a> {
pub fn new(_state: &'a mut state::InternalState, _operations: Vec<Operation>, dump_file_path: &'a str) -> Self {
CodeIterator{state: _state, operations: _operations, has_errored: false, dump_file_path}
}
}
impl<'a> Iterator for CodeIterator<'a> {
type Item = Result<state::InternalState, String>;
fn next(&mut self) -> Option<Self::Item> {
let srcpath = self.dump_file_path;
if self.has_errored {
None
}
else if self.state.executed_instructions() > 10000 {
self.has_errored = true;
let result: Result<(), String> = Err(String::from("instructions limit reached"));
dump_state(&self.state, srcpath, &result.err().unwrap());
return None;
}
else if self.state.instruction_counter < self.operations.len() {
let _operation = self.operations[self.state.instruction_counter];
let result = self.state.apply(_operation);
if result.is_err() {
if let Operation::Inbox = _operation {
self.has_errored = false;
dump_state(&self.state, srcpath, &result.err().unwrap());
return None;
}
else {
dump_state(&self.state, srcpath, &result.err().unwrap());
self.has_errored = true;
}
}
dump_state(&self.state, srcpath, &String::new());
Some(Ok(self.state.clone()))
}
else {
dump_state(&self.state, srcpath, &String::new());
None
}
}
}