From be1a75c1ca7c1877eed0d2849b227ae367f356a9 Mon Sep 17 00:00:00 2001 From: hellerve Date: Sun, 4 Jun 2017 22:42:18 -0400 Subject: [PATCH] exec: hello world works, factorial almost works --- src/main.rs | 91 ++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9e83062..0413165 100644 --- a/src/main.rs +++ b/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(stack: &mut Vec, fun: F) where F: Fn(i64, i64) -> i64 { /* Casting abound. You have been warned. */ fn exec(instructions: Vec, _ip: usize) -> i64 { let mut stack: Vec = Vec::new(); - let mut data: Vec = Vec::new(); + let mut data: Vec = 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, _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); }