diff --git a/src/main.rs b/src/main.rs index 0cac004..f5b3d3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ +use std::char; +use std::collections::HashMap; +use std::env; use std::fs::File; use std::io; use std::io::Read; -use std::env; -use std::collections::HashMap; const EXEC_RPR: [(&'static str, i32); 28] = [ ("entry", 1), @@ -61,44 +62,37 @@ fn parse(contents: String, opcodes: HashMap<&'static str, (i64, i32)>) -> Vec>(); let (op, args) = tmp.split_first().expect("malformatted line!"); let opcode: &str = &op.to_lowercase()[..]; - match opcodes.get(opcode) { - Some(v) => { - code.push(v.0); - if args.len() as i32 != v.1 { - panic!("Expected {} arguments for opcode {}, but got {}!", v.1, opcode, args.len()); - } - for elem in args { - match elem.parse::() { - Ok(v) => code.push(v), - _ => panic!("Could not parse argument {} to instruction {} as number!", elem, opcode) - } + if let Some(v) = opcodes.get(opcode) { + code.push(v.0); + if args.len() as i32 != v.1 { + panic!("Expected {} arguments for opcode {}, but got {}!", v.1, opcode, args.len()); + } + for elem in args { + if let Ok(v) = elem.parse::() { + code.push(v); } } - None => panic!("Do not know opcode {}!", opcode) } } return code } fn binop(stack: &mut Vec, fun: F) where F: Fn(i64, i64) -> i64 { - let x = stack.pop(); - let y = stack.pop(); - match x { - Some(x) => - match y { - Some(y) => stack.push(fun(x, y)), - _ => panic!("pop needs at least two elements on the stack") - }, - _ => panic!("pop needs at least two elements on the stack") + if let Some(x) = stack.pop() { + if let Some(y) = stack.pop() { + stack.push(fun(x, y)); + return; + } } + panic!("pop needs at least two elements on the stack"); } fn exec(instructions: Vec) -> i64 { let mut stack: Vec = Vec::new(); + let mut data: Vec = Vec::new(); let ilen = instructions.len(); let mut ip = 0; while ip < ilen { - ip += 1; /* TMP */ match instructions[ip] { /* ENT */ 0 => (), /* ADD */ 1 => binop(&mut stack, |x, y| x + y), @@ -112,24 +106,49 @@ fn exec(instructions: Vec) -> i64 { /* BR */ 9 => (), /* BRT */ 10 => (), /* BRF */ 11 => (), - /* CST */ 12 => (), + /* CST */ 12 => { + ip += 1; + stack.push(instructions[ip]) + }, /* LD */ 13 => (), /* GLD */ 14 => (), /* ST */ 15 => (), /* GST */ 16 => (), - /* PRN */ 17 => (), - /* POP */ 18 => (), + /* PRN */ 17 => { + if let Some(x) = stack.last() { + if let Some(x) = char::from_digit(*x as u32, 10) { + print!("{}", x); + } + } + }, + /* POP */ 18 => { + stack.pop(); + (); + } /* HLT */ 19 => break, /* LEQ */ 20 => binop(&mut stack, |x, y| (x <= y) as i64), /* GEQ */ 21 => binop(&mut stack, |x, y| (x >= y) as i64), /* CAL */ 22 => (), /* RET */ 23 => (), - /* IPR */ 24 => (), + /* IPR */ 24 => { + if let Some(x) = stack.last() { + print!("{}", x); + }; + }, /* FET */ 25 => (), - /* INC */ 26 => (), - /* DEC */ 27 => (), + /* INC */ 26 => { + if let Some(x) = stack.pop() { + stack.push(x+1); + } + }, + /* DEC */ 27 => { + if let Some(x) = stack.pop() { + stack.push(x-1); + } + }, /* IMP */ x => panic!("Unknown instruction {}!", x) } + ip += 1; } return *stack.first().unwrap_or(&0); }