featurecomplete
This commit is contained in:
parent
35b0b5972f
commit
8d48c4bc89
BIN
data/bootcodex.um
Normal file
BIN
data/bootcodex.um
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
extern crate um;
|
||||
use um::cpu::{Cpu};
|
||||
use um::cpu::{Cpu,Console};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::fs::File;
|
||||
@ -9,8 +9,43 @@ use clap::Parser;
|
||||
/// Run a um program
|
||||
#[derive(Parser)]
|
||||
struct Cli {
|
||||
// debug level
|
||||
#[clap(short, long, default_value_t = 0)]
|
||||
debug: u32,
|
||||
/// The path to the program to load
|
||||
program: std::path::PathBuf,
|
||||
program: std::path::PathBuf
|
||||
|
||||
}
|
||||
|
||||
struct IoConsole {
|
||||
inptr: usize,
|
||||
inbuf: String
|
||||
}
|
||||
|
||||
impl IoConsole {
|
||||
pub fn make() -> IoConsole {
|
||||
IoConsole {
|
||||
inptr: 0,
|
||||
inbuf: String::from("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Console for IoConsole {
|
||||
fn read(&mut self) -> Option<u8> {
|
||||
if self.inptr >= self.inbuf.len() {
|
||||
if let Err(_) = std::io::stdin().read_line(&mut self.inbuf) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
let r = self.inbuf.bytes().nth(self.inptr).unwrap();
|
||||
self.inptr +=1;
|
||||
Some(r)
|
||||
}
|
||||
fn write(&mut self, c: u8) {
|
||||
let buf = [c;1];
|
||||
let _ = std::io::stdout().write(&buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -36,21 +71,11 @@ fn main() -> io::Result<()> {
|
||||
}
|
||||
|
||||
let mut c = Cpu::new(pgm);
|
||||
cont = true;
|
||||
println!("start\n{}", c.state());
|
||||
while cont {
|
||||
let r = c.step();
|
||||
cont = match r {
|
||||
Ok(_) => {
|
||||
println!("ok\n{}", c.state());
|
||||
true
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Error {:?}", e);
|
||||
false
|
||||
}
|
||||
};
|
||||
c.set_debug(args.debug);
|
||||
let mut cons = IoConsole::make();
|
||||
match c.run(&mut cons) {
|
||||
Err(e) => println!("Error {:?}", e),
|
||||
Ok(_) => ()
|
||||
}
|
||||
Ok(())
|
||||
|
||||
}
|
77
src/cpu.rs
77
src/cpu.rs
@ -27,7 +27,8 @@ pub struct Cpu {
|
||||
iarr: u32,
|
||||
finger: u32,
|
||||
out: Option<u8>,
|
||||
in_reg: Option<u8>
|
||||
in_reg: Option<u8>,
|
||||
debug: u32
|
||||
}
|
||||
|
||||
|
||||
@ -41,10 +42,14 @@ impl Cpu {
|
||||
iarr: 1,
|
||||
finger: 0,
|
||||
in_reg: None,
|
||||
out: None
|
||||
out: None,
|
||||
debug: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_debug(&mut self, debug: u32) {
|
||||
self.debug = debug;
|
||||
}
|
||||
fn gr(&self, r: u8) -> u32{
|
||||
self.reg[r as usize]
|
||||
}
|
||||
@ -215,6 +220,22 @@ impl Cpu {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_lod(&mut self, i:NormalInstruction) -> Result<(), CpuError>{
|
||||
let aidx = self.gr(i.b);
|
||||
let aoff = self.gr(i.c);
|
||||
if let Some(arr) = self.arr.get(&aidx){
|
||||
if arr.len() > aoff as usize {
|
||||
self.arr.insert(0, arr.clone());
|
||||
self.finger = aoff;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(CpuError::ArrayOutOfBounds)
|
||||
}
|
||||
} else {
|
||||
Err(CpuError::InvalidArray)
|
||||
}
|
||||
}
|
||||
|
||||
fn exec(&mut self, instruction: Instruction)-> Result<(), CpuError>{
|
||||
//println!("{:?}", instruction);
|
||||
match instruction {
|
||||
@ -231,7 +252,8 @@ impl Cpu {
|
||||
Instruction::Abandon(i) => self.handle_abn(i),
|
||||
Instruction::Output(i) => self.handle_out(i),
|
||||
Instruction::Input(i) => self.handle_inp(i),
|
||||
_ => Err(CpuError::InvalidInstruction)
|
||||
Instruction::Load(i) => self.handle_lod(i),
|
||||
//_ => Err(CpuError::InvalidInstruction)
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,14 +261,19 @@ impl Cpu {
|
||||
self.out = None;
|
||||
self.in_reg = None;
|
||||
let i = self.ins()?;
|
||||
self.exec(i)?;
|
||||
self.finger += 1;
|
||||
self.exec(i)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run(&mut self, console: &mut impl Console) -> Result<(), CpuError> {
|
||||
let mut cont = true;
|
||||
|
||||
while cont {
|
||||
if self.debug > 5 {
|
||||
println!("{:?}", self.ins());
|
||||
println!("{}", self.state());
|
||||
}
|
||||
cont = match self.step() {
|
||||
Ok(_) => true,
|
||||
Err(CpuError::ProgramEnd) => false,
|
||||
@ -632,4 +659,46 @@ mod tests{
|
||||
assert_eq!(c.reg, exp);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lod() -> Result<(), CpuError> {
|
||||
let pgm = vec!( ezop(12, 1, 2, 3) );
|
||||
let mut c = Cpu::new(pgm);
|
||||
c.arr.insert(1338, vec![0,0,0,1339]);
|
||||
c.reg = [0, 0, 1338, 3, 0, 0, 0, 0];
|
||||
c.step()?;
|
||||
assert_eq!(c.finger, 3);
|
||||
if let Some(arr) = c.arr.get(&0){
|
||||
assert_eq!(arr,&vec![0,0,0,1339] );
|
||||
Ok(())
|
||||
} else {
|
||||
Err(CpuError::InvalidArray)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lod_inv() -> Result<(), String> {
|
||||
let pgm = vec!( ezop(12, 1, 2, 3) );
|
||||
let mut c = Cpu::new(pgm);
|
||||
c.reg = [0, 0, 1338, 3, 0, 0, 0, 0];
|
||||
|
||||
match c.step() {
|
||||
Err(CpuError::InvalidArray) => Ok(()),
|
||||
Ok(_) => Err(format!("unexpected ok")),
|
||||
Err(e) => Err(format!("unexpected err {:?}", e))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lod_off() -> Result<(), String> {
|
||||
let pgm = vec!( ezop(12, 1, 2, 3) );
|
||||
let mut c = Cpu::new(pgm);
|
||||
c.reg = [0, 0, 1338, 3, 0, 0, 0, 0];
|
||||
c.arr.insert(1338, vec![0]);
|
||||
match c.step() {
|
||||
Err(CpuError::ArrayOutOfBounds) => Ok(()),
|
||||
Ok(_) => Err(format!("unexpected ok")),
|
||||
Err(e) => Err(format!("unexpected err {:?}", e))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user