1pub mod command_parser;
2
3use std;
4use std::fs::File;
5use std::io;
6use std::io::{Read};
7use std::net::TcpStream;
8use std::num::ParseIntError;
9use std::path::Path;
10use std::sync::mpsc;
11use std::sync::mpsc::{Receiver, Sender};
12
13use nom::types::CompleteStr;
14
15use assembler::program_parsers::program;
16use assembler::Assembler;
17use cluster;
18use repl::command_parser::CommandParser;
19use scheduler::Scheduler;
20use vm::VM;
21const COMMAND_PREFIX: char = '!';
22
23pub static REMOTE_BANNER: &'static str = "Welcome to Iridium! Let's be productive!";
24pub static PROMPT: &'static str = ">>> ";
25
26#[derive(Default)]
28pub struct REPL {
29 command_buffer: Vec<String>,
30 vm: VM,
31 asm: Assembler,
32 scheduler: Scheduler,
33 pub tx_pipe: Option<Box<Sender<String>>>,
34 pub rx_pipe: Option<Box<Receiver<String>>>,
35}
36
37impl REPL {
38 pub fn new(vm: VM) -> REPL {
40 let (tx, rx): (Sender<String>, Receiver<String>) = mpsc::channel();
41 REPL {
42 vm,
43 command_buffer: vec![],
44 asm: Assembler::new(),
45 scheduler: Scheduler::new(),
46 tx_pipe: Some(Box::new(tx)),
47 rx_pipe: Some(Box::new(rx)),
48 }
49 }
50
51 pub fn run(&mut self) {
54 debug!("Starting REPL run loop with VM ID of {:?}", self.vm.alias);
55 self.send_message(REMOTE_BANNER.to_string());
56 self.send_prompt();
57 loop {
58 let mut buffer = String::new();
61
62 let stdin = io::stdin();
64
65 stdin
67 .read_line(&mut buffer)
68 .expect("Unable to read line from user");
69
70 let historical_copy = buffer.clone();
71 self.command_buffer.push(historical_copy);
72
73 if buffer.starts_with(COMMAND_PREFIX) {
74 self.execute_command(&buffer);
75 } else {
76 let program = match program(CompleteStr(&buffer)) {
77 Ok((_remainder, program)) => program,
78 Err(e) => {
79 self.send_message(format!("There was an error executing the program: {:?}", e));
80 continue;
81 }
82 };
83 self.vm
84 .program
85 .append(&mut program.to_bytes(&self.asm.symbols));
86 self.vm.run_once();
87 }
88 }
89 }
90
91 pub fn run_single(&mut self, buffer: &str) -> Option<String> {
92 if buffer.starts_with(COMMAND_PREFIX) {
93 self.execute_command(&buffer);
94 None
95 } else {
96 let program = match program(CompleteStr(&buffer)) {
97 Ok((_remainder, program)) => Some(program),
98 Err(e) => {
99 self.send_message(format!("Unable to parse input: {:?}", e));
100 None
101 }
102 };
103 match program {
104 Some(p) => {
105 let mut bytes = p.to_bytes(&self.asm.symbols);
106 self.vm.program.append(&mut bytes);
107 self.vm.run_once();
108 None
109 }
110 None => None,
111 }
112 }
113 }
114
115 pub fn send_message(&mut self, msg: String) {
116 match &self.tx_pipe {
117 Some(pipe) => {
118 match pipe.send(msg) {
119 Ok(_) => {}
120 Err(_e) => {}
121 };
122 }
123 None => {}
124 }
125 }
126 pub fn send_prompt(&mut self) {
127 match &self.tx_pipe {
128 Some(pipe) => match pipe.send(PROMPT.to_owned()) {
129 Ok(_) => {}
130 Err(_e) => {}
131 },
132 None => {}
133 }
134 }
135
136 fn get_data_from_load(&mut self) -> Option<String> {
137 let stdin = io::stdin();
138 self.send_message("Please enter the path to the file you wish to load: ".to_string());
139 let mut tmp = String::new();
140
141 stdin
142 .read_line(&mut tmp)
143 .expect("Unable to read line from user");
144 self.send_message("Attempting to load program from file...".to_string());
145
146 let tmp = tmp.trim();
147 let filename = Path::new(&tmp);
148 let mut f = match File::open(&filename) {
149 Ok(f) => f,
150 Err(e) => {
151 self.send_message(format!("There was an error opening that file: {:?}", e));
152 return None;
153 }
154 };
155 let mut contents = String::new();
156 match f.read_to_string(&mut contents) {
157 Ok(_bytes_read) => Some(contents),
158 Err(e) => {
159 self.send_message(format!("there was an error reading that file: {:?}", e));
160 None
161 }
162 }
163 }
164
165 #[allow(dead_code)]
168 fn parse_hex(&mut self, i: &str) -> Result<Vec<u8>, ParseIntError> {
169 let split = i.split(' ').collect::<Vec<&str>>();
170 let mut results: Vec<u8> = vec![];
171 for hex_string in split {
172 let byte = u8::from_str_radix(&hex_string, 16);
173 match byte {
174 Ok(result) => {
175 results.push(result);
176 }
177 Err(e) => {
178 return Err(e);
179 }
180 }
181 }
182 Ok(results)
183 }
184
185 fn execute_command(&mut self, input: &str) {
186 let args = CommandParser::tokenize(input);
187 match args[0] {
188 "!quit" => self.quit(&args[1..]),
189 "!history" => self.history(&args[1..]),
190 "!program" => self.program(&args[1..]),
191 "!clear_program" => self.clear_program(&args[1..]),
192 "!clear_registers" => self.clear_registers(&args[1..]),
193 "!registers" => self.registers(&args[1..]),
194 "!symbols" => self.symbols(&args[1..]),
195 "!load_file" => self.load_file(&args[1..]),
196 "!spawn" => self.spawn(&args[1..]),
197 "!start_cluster" => self.start_cluster(&args[1..]),
198 "!join_cluster" => self.join_cluster(&args[1..]),
199 "!cluster_members" => self.cluster_members(&args[1..]),
200 _ => {
201 self.send_message("Invalid command!".to_string());
202 }
203 };
204 }
205
206 fn quit(&mut self, _args: &[&str]) {
207 self.send_message("Farewell! Have a great day!".to_string());
208 std::process::exit(0);
209 }
210
211 fn history(&mut self, _args: &[&str]) {
212 let mut results = vec![];
213 for command in &self.command_buffer {
214 results.push(command.clone());
215 }
216 self.send_message(format!("{:#?}", results));
217 }
218
219 fn program(&mut self, _args: &[&str]) {
220 self.send_message("Listing instructions currently in VM's program vector: ".to_string());
221 let mut results = vec![];
222 for instruction in &self.vm.program {
223 results.push(instruction.clone())
224 }
225 self.send_message(format!("{:#?}", results));
226 self.send_message("End of Program Listing".to_string());
227 }
228
229 fn clear_program(&mut self, _args: &[&str]) {
230 self.vm.program.clear();
231 }
232
233 fn clear_registers(&mut self, _args: &[&str]) {
234 self.send_message("Setting all registers to 0".to_string());
235 for i in 0..self.vm.registers.len() {
236 self.vm.registers[i] = 0;
237 }
238 self.send_message("Done!".to_string());
239 }
240
241 fn registers(&mut self, _args: &[&str]) {
242 self.send_message("Listing registers and all contents:".to_string());
243 let mut results = vec![];
244 for register in &self.vm.registers {
245 results.push(register.clone());
246 }
247 self.send_message(format!("{:#?}", results));
248 self.send_message("End of Register Listing".to_string());
249 }
250
251 fn symbols(&mut self, _args: &[&str]) {
252 let mut results = vec![];
253 for symbol in &self.asm.symbols.symbols {
254 results.push(symbol.clone());
255 }
256 self.send_message("Listing symbols table:".to_string());
257 self.send_message(format!("{:#?}", results));
258 self.send_message("End of Symbols Listing".to_string());
259 }
260
261 fn load_file(&mut self, _args: &[&str]) {
262 let contents = self.get_data_from_load();
263 if let Some(contents) = contents {
264 match self.asm.assemble(&contents) {
265 Ok(mut assembled_program) => {
266 self.send_message("Sending assembled program to VM".to_string());
267 self.vm.program.append(&mut assembled_program);
268 self.vm.run();
269 }
270 Err(errors) => {
271 for error in errors {
272 self.send_message(format!("Unable to parse input: {}", error));
273 }
274 return;
275 }
276 }
277 } else {
278 return;
279 }
280 }
281
282 fn spawn(&mut self, _args: &[&str]) {
283 let contents = self.get_data_from_load();
284 self.send_message(format!("Loaded contents: {:#?}", contents));
285 if let Some(contents) = contents {
286 match self.asm.assemble(&contents) {
287 Ok(mut assembled_program) => {
288 self.send_message("Sending assembled program to VM".to_string());
289 self.vm.program.append(&mut assembled_program);
290 self.scheduler.get_thread(self.vm.clone());
291 }
292 Err(errors) => {
293 for error in errors {
294 self.send_message(format!("Unable to parse input: {}", error));
295 }
296 return;
297 }
298 }
299 } else {
300 return;
301 }
302 }
303
304 fn start_cluster(&mut self, _args: &[&str]) {
305 self.send_message("Started cluster server!".to_string());
306 self.vm.bind_cluster_server();
307 }
308
309 fn join_cluster(&mut self, args: &[&str]) {
310 debug!("Joining cluster with VM ID: {:?}", self.vm.alias);
311 self.send_message("Attempting to join cluster...".to_string());
312 let ip = args[0];
313 let port = args[1];
314 let addr = ip.to_owned() + ":" + port.clone();
315 if let Ok(stream) = TcpStream::connect(addr) {
316 self.send_message("Connected to cluster!".to_string());
317 let mut cc =
318 cluster::client::ClusterClient::new(stream, self.vm.connection_manager.clone(), self.vm.server_port.clone().unwrap()).with_alias(self.vm.alias.clone().unwrap());
319 debug!("CC Hello is: {:#?}", cc);
320 cc.send_hello();
321 if let Some(ref a) = self.vm.alias {
322 if let Ok(mut lock) = self.vm.connection_manager.write() {
323 let client_tuple = (a.to_string(), cc.ip_as_string().unwrap(), cc.port_as_string().unwrap());
324 lock.add_client(client_tuple, cc);
325 }
326 }
327 } else {
328 self.send_message("Could not connect to cluster!".to_string());
329 }
330 }
331
332 fn cluster_members(&mut self, _args: &[&str]) {
333 self.send_message("Listing Known Nodes:".to_string());
334 let cluster_members = self
335 .vm
336 .connection_manager
337 .read()
338 .unwrap()
339 .get_client_names();
340 self.send_message(format!("{:#?}", cluster_members));
341 }
342}