exec: hello world works, factorial almost works
This commit is contained in:
89
src/main.rs
89
src/main.rs
@@ -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;
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user