use std::fs; use std::env; use std::fmt; use std::usize; use std::collections::HashMap; mod eval; struct Program { data: Vec, pc: usize, vars: HashMap } impl Program { fn from_string(program: String) -> Program { let mut op_list: Vec = Vec::new(); for opcode in program.split(" ").collect::>() { let mut new_op = opcode.to_owned(); new_op = new_op.replace("\n", ""); if new_op.len() != 0 { op_list.push(new_op.to_owned()); } } return Program{ data: op_list, pc: 0, vars: HashMap::new() }; } fn args_or_vars<'a>(&self, arguments: &'a str) -> String { let mut deconstructed: Vec = arguments.chars().collect(); for (index, char) in arguments.chars().enumerate() { let value = self.vars.get(&char); match value { Some(content) => deconstructed[index] = *content, None => {} } } deconstructed.into_iter().collect() } fn add_var(&mut self, arguments: &str) { let argument_vec: Vec = arguments.chars().collect(); self.vars.insert(argument_vec[0], argument_vec[1]); } fn parse(&mut self, instruction: &String) { let opcode = instruction.chars().collect::>()[0]; let arguments = &instruction[1..]; match opcode { 'p' => println!("{}", self.args_or_vars(arguments)), 'a' => println!("{}", eval::do_math(self.args_or_vars(arguments), '+')), 's' => println!("{}", eval::do_math(self.args_or_vars(arguments), '-')), 'm' => println!("{}", eval::do_math(self.args_or_vars(arguments), '*')), 'd' => println!("{}", eval::do_math(self.args_or_vars(arguments), '/')), 'l' => self.add_var(arguments), _ => panic!("SyntaxError at opcode {}!", self.pc) } } fn run(&mut self) { println!("{}", self); while self.pc < self.data.len() { let instruction = self.data[self.pc].to_owned(); self.parse(&instruction); self.pc = self.pc + 1; } } } impl fmt::Display for Program { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Program ({:?})", self.data) } } fn main() { let args: Vec = env::args().collect(); if args.len() == 1 { panic!("You must provide a filename!"); } let filename = &args[1]; let contents = fs::read_to_string(filename).expect("Something went wrong reading the file"); let mut prog = Program::from_string(contents); prog.run(); }