exec: hello world works, factorial almost works

This commit is contained in:
2017-06-04 22:42:18 -04:00
parent 6e5fdbc8a4
commit be1a75c1ca

View File

@@ -4,9 +4,9 @@ use std::env;
use std::fs::File;
use std::io;
use std::io::Read;
use std::process;
const EXEC_RPR: [(&'static str, i32); 28] = [
("entry", 1),
const EXEC_RPR: [(&'static str, i32); 27] = [
("add", 0),
("sub", 0),
("mult", 0),
@@ -100,86 +100,84 @@ fn binop<F>(stack: &mut Vec<i64>, fun: F) where F: Fn(i64, 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 data: Vec<i64> = Vec::new();
let mut data: Vec<i64> = vec![0; 1024];
let ilen = instructions.len();
let mut ip: usize = _ip;
let mut fp: usize = 0;
while ip < ilen {
match instructions[ip] {
/* ENT */ 0 => (),
/* ADD */ 1 => binop(&mut stack, |x, y| x + y),
/* SUB */ 2 => binop(&mut stack, |x, y| x - y),
/* MUL */ 3 => binop(&mut stack, |x, y| x * y),
/* DIV */ 4 => binop(&mut stack, |x, y| x / y),
/* MOD */ 5 => binop(&mut stack, |x, y| x % y),
/* LT */ 6 => 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),
/* BR */ 9 => {
ip = instructions[ip+1] as usize;
},
/* BRT */ 10 => {
ip += 1;
ip += 1;
match instructions[ip-1] {
/* ADD */ 0 => binop(&mut stack, |x, y| x + y),
/* SUB */ 1 => binop(&mut stack, |x, y| x - y),
/* MUL */ 2 => binop(&mut stack, |x, y| x * y),
/* DIV */ 3 => binop(&mut stack, |x, y| x / y),
/* MOD */ 4 => binop(&mut stack, |x, y| x % y),
/* LT */ 5 => binop(&mut stack, |x, y| (x < y) as i64),
/* EQ */ 6 => binop(&mut stack, |x, y| (x == y) as i64),
/* GT */ 7 => binop(&mut stack, |x, y| (x > y) as i64),
/* BR */ 8 => ip = instructions[ip+1] as usize,
/* BRT */ 9 => {
let addr = instructions[ip];
if let Some(x) = stack.pop() {
if x != 0 { ip = addr as usize; }
else { ip += 1; }
}
},
/* BRF */ 11 => {
ip += 1;
/* BRF */ 10 => {
let addr = instructions[ip];
if let Some(x) = stack.pop() {
if x == 0 { ip = addr as usize; }
else { ip += 1; }
}
},
/* CST */ 12 => {
/* CST */ 11 => {
stack.push(instructions[ip]);
ip += 1;
stack.push(instructions[ip])
},
/* LD */ 13 => {
/* LD */ 12 => {
stack.push(instructions[ip+fp]);
ip += 1;
stack.push(instructions[ip+fp])
},
/* GLD */ 14 => {
ip += 1;
/* GLD */ 13 => {
stack.push(data[instructions[ip] as usize]);
},
/* ST */ 15 => {
ip += 1;
},
/* ST */ 14 => {
if let Some(x) = stack.pop() {
stack[fp+instructions[ip] as usize] = x;
}
},
/* GST */ 16 => {
ip += 1;
},
/* GST */ 15 => {
if let Some(x) = stack.pop() {
data[instructions[ip] as usize] = x;
}
ip += 1;
},
/* PRN */ 17 => {
/* PRN */ 16 => {
if let Some(x) = stack.last() {
if let Some(x) = char::from_digit(*x as u32, 10) {
if let Some(x) = char::from_u32(*x as u32) {
print!("{}", x);
}
}
},
/* POP */ 18 => {
/* POP */ 17 => {
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 => {
let addr = instructions[ip+1];
let nargs = instructions[ip+2];
/* HLT */ 18 => return 0,
/* LEQ */ 19 => binop(&mut stack, |x, y| (x <= y) as i64),
/* GEQ */ 20 => binop(&mut stack, |x, y| (x >= y) as i64),
/* CAL */ 21 => {
let addr = instructions[ip];
let nargs = instructions[ip+1];
stack.push(nargs);
stack.push(fp as i64);
stack.push((ip+2) as i64);
stack.push((ip+1) as i64);
fp = stack.len() as usize;
ip = addr as usize;
},
/* RET */ 23 => {
/* RET */ 22 => {
if let Some(addr) = stack.pop() {
let mut nargs = 0;
stack.truncate(addr as usize);
@@ -197,25 +195,24 @@ fn exec(instructions: Vec<i64>, _ip: usize) -> i64 {
stack.push(addr);
}
},
/* IPR */ 24 => {
/* IPR */ 23 => {
if let Some(x) = stack.last() {
print!("{}", x);
};
},
/* FET */ 25 => (),
/* INC */ 26 => {
/* FET */ 24 => (),
/* INC */ 25 => {
if let Some(x) = stack.pop() {
stack.push(x+1);
}
},
/* DEC */ 27 => {
/* DEC */ 26 => {
if let Some(x) = stack.pop() {
stack.push(x-1);
}
},
/* IMP */ x => panic!("Unknown instruction {}!", x)
}
ip += 1;
}
return *stack.first().unwrap_or(&0);
}
@@ -243,5 +240,5 @@ fn main() {
let (parsed, ip) = parse(contents, opcodes);
println!("{}", exec(parsed, ip));
process::exit(exec(parsed, ip) as i32);
}