featurecomplete

This commit is contained in:
Richard 2025-08-30 16:50:47 +02:00
parent 35b0b5972f
commit 8d48c4bc89
3 changed files with 115 additions and 21 deletions

BIN
data/bootcodex.um Normal file

Binary file not shown.

View File

@ -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(())
}

View File

@ -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))
}
}
}