exec: implemented; still doesnt work
This commit is contained in:
97
src/main.rs
97
src/main.rs
@@ -55,13 +55,23 @@ fn get_contents(fname: String) -> Result<String, io::Error> {
|
|||||||
Ok(contents)
|
Ok(contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(contents: String, opcodes: HashMap<&'static str, (i64, i32)>) -> Vec<i64> {
|
fn parse(contents: String, opcodes: HashMap<&'static str, (i64, i32)>) -> (Vec<i64>, usize) {
|
||||||
let mut code = Vec::new();
|
let mut code = Vec::new();
|
||||||
|
let mut ip = 0;
|
||||||
for line in contents.split("\n") {
|
for line in contents.split("\n") {
|
||||||
if line.is_empty() { continue }
|
if line.is_empty() { continue }
|
||||||
let tmp = line.split(" ").map(String::from).collect::<Vec<String>>();
|
let tmp = line.split(" ").map(String::from).collect::<Vec<String>>();
|
||||||
let (op, args) = tmp.split_first().expect("malformatted line!");
|
let (op, args) = tmp.split_first().expect("malformatted line!");
|
||||||
let opcode: &str = &op.to_lowercase()[..];
|
let opcode: &str = &op.to_lowercase()[..];
|
||||||
|
|
||||||
|
// Special case: ENTRY
|
||||||
|
if opcode == "entry" {
|
||||||
|
if let Ok(_ip) = args[0].parse::<usize>() {
|
||||||
|
ip = _ip;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(v) = opcodes.get(opcode) {
|
if let Some(v) = opcodes.get(opcode) {
|
||||||
code.push(v.0);
|
code.push(v.0);
|
||||||
if args.len() as i32 != v.1 {
|
if args.len() as i32 != v.1 {
|
||||||
@@ -74,7 +84,7 @@ fn parse(contents: String, opcodes: HashMap<&'static str, (i64, i32)>) -> Vec<i6
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return code
|
return (code, ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binop<F>(stack: &mut Vec<i64>, fun: F) where F: Fn(i64, i64) -> i64 {
|
fn binop<F>(stack: &mut Vec<i64>, fun: F) where F: Fn(i64, i64) -> i64 {
|
||||||
@@ -87,11 +97,13 @@ fn binop<F>(stack: &mut Vec<i64>, fun: F) where F: Fn(i64, i64) -> i64 {
|
|||||||
panic!("pop needs at least two elements on the stack");
|
panic!("pop needs at least two elements on the stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec(instructions: Vec<i64>) -> i64 {
|
/* Casting abound. You have been warned. */
|
||||||
|
fn exec(instructions: Vec<i64>, _ip: usize) -> i64 {
|
||||||
let mut stack: Vec<i64> = Vec::new();
|
let mut stack: Vec<i64> = Vec::new();
|
||||||
let mut data: Vec<i64> = Vec::new();
|
let mut data: Vec<i64> = Vec::new();
|
||||||
let ilen = instructions.len();
|
let ilen = instructions.len();
|
||||||
let mut ip = 0;
|
let mut ip: usize = _ip;
|
||||||
|
let mut fp: usize = 0;
|
||||||
while ip < ilen {
|
while ip < ilen {
|
||||||
match instructions[ip] {
|
match instructions[ip] {
|
||||||
/* ENT */ 0 => (),
|
/* ENT */ 0 => (),
|
||||||
@@ -103,17 +115,47 @@ fn exec(instructions: Vec<i64>) -> i64 {
|
|||||||
/* LT */ 6 => binop(&mut stack, |x, y| (x < y) as i64),
|
/* LT */ 6 => binop(&mut stack, |x, y| (x < y) as i64),
|
||||||
/* EQ */ 7 => binop(&mut stack, |x, y| (x == y) as i64),
|
/* EQ */ 7 => binop(&mut stack, |x, y| (x == y) as i64),
|
||||||
/* GT */ 8 => binop(&mut stack, |x, y| (x > y) as i64),
|
/* GT */ 8 => binop(&mut stack, |x, y| (x > y) as i64),
|
||||||
/* BR */ 9 => (),
|
/* BR */ 9 => {
|
||||||
/* BRT */ 10 => (),
|
ip = instructions[ip+1] as usize;
|
||||||
/* BRF */ 11 => (),
|
},
|
||||||
|
/* BRT */ 10 => {
|
||||||
|
ip += 1;
|
||||||
|
let addr = instructions[ip];
|
||||||
|
if let Some(x) = stack.pop() {
|
||||||
|
if x != 0 { ip = addr as usize; }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* BRF */ 11 => {
|
||||||
|
ip += 1;
|
||||||
|
let addr = instructions[ip];
|
||||||
|
if let Some(x) = stack.pop() {
|
||||||
|
if x == 0 { ip = addr as usize; }
|
||||||
|
}
|
||||||
|
},
|
||||||
/* CST */ 12 => {
|
/* CST */ 12 => {
|
||||||
ip += 1;
|
ip += 1;
|
||||||
stack.push(instructions[ip])
|
stack.push(instructions[ip])
|
||||||
},
|
},
|
||||||
/* LD */ 13 => (),
|
/* LD */ 13 => {
|
||||||
/* GLD */ 14 => (),
|
ip += 1;
|
||||||
/* ST */ 15 => (),
|
stack.push(instructions[ip+fp])
|
||||||
/* GST */ 16 => (),
|
},
|
||||||
|
/* GLD */ 14 => {
|
||||||
|
ip += 1;
|
||||||
|
stack.push(data[instructions[ip] as usize]);
|
||||||
|
},
|
||||||
|
/* ST */ 15 => {
|
||||||
|
ip += 1;
|
||||||
|
if let Some(x) = stack.pop() {
|
||||||
|
stack[fp+instructions[ip] as usize] = x;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* GST */ 16 => {
|
||||||
|
ip += 1;
|
||||||
|
if let Some(x) = stack.pop() {
|
||||||
|
data[instructions[ip] as usize] = x;
|
||||||
|
}
|
||||||
|
},
|
||||||
/* PRN */ 17 => {
|
/* PRN */ 17 => {
|
||||||
if let Some(x) = stack.last() {
|
if let Some(x) = stack.last() {
|
||||||
if let Some(x) = char::from_digit(*x as u32, 10) {
|
if let Some(x) = char::from_digit(*x as u32, 10) {
|
||||||
@@ -128,8 +170,33 @@ fn exec(instructions: Vec<i64>) -> i64 {
|
|||||||
/* HLT */ 19 => break,
|
/* HLT */ 19 => break,
|
||||||
/* LEQ */ 20 => binop(&mut stack, |x, y| (x <= y) as i64),
|
/* LEQ */ 20 => binop(&mut stack, |x, y| (x <= y) as i64),
|
||||||
/* GEQ */ 21 => binop(&mut stack, |x, y| (x >= y) as i64),
|
/* GEQ */ 21 => binop(&mut stack, |x, y| (x >= y) as i64),
|
||||||
/* CAL */ 22 => (),
|
/* CAL */ 22 => {
|
||||||
/* RET */ 23 => (),
|
let addr = instructions[ip+1];
|
||||||
|
let nargs = instructions[ip+2];
|
||||||
|
stack.push(nargs);
|
||||||
|
stack.push(fp as i64);
|
||||||
|
stack.push((ip+2) as i64);
|
||||||
|
fp = stack.len() as usize;
|
||||||
|
ip = addr as usize;
|
||||||
|
},
|
||||||
|
/* RET */ 23 => {
|
||||||
|
if let Some(addr) = stack.pop() {
|
||||||
|
let mut nargs = 0;
|
||||||
|
stack.truncate(addr as usize);
|
||||||
|
if let Some(_ip) = stack.pop() {
|
||||||
|
ip = _ip as usize;
|
||||||
|
}
|
||||||
|
if let Some(_fp) = stack.pop() {
|
||||||
|
fp = _fp as usize;
|
||||||
|
}
|
||||||
|
if let Some(_nargs) = stack.pop() {
|
||||||
|
nargs = _nargs;
|
||||||
|
}
|
||||||
|
let stl = stack.len();
|
||||||
|
stack.truncate(stl-nargs as usize);
|
||||||
|
stack.push(addr);
|
||||||
|
}
|
||||||
|
},
|
||||||
/* IPR */ 24 => {
|
/* IPR */ 24 => {
|
||||||
if let Some(x) = stack.last() {
|
if let Some(x) = stack.last() {
|
||||||
print!("{}", x);
|
print!("{}", x);
|
||||||
@@ -174,7 +241,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let parsed = parse(contents, opcodes);
|
let (parsed, ip) = parse(contents, opcodes);
|
||||||
|
|
||||||
println!("{}", exec(parsed));
|
println!("{}", exec(parsed, ip));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user