Added valider
This commit is contained in:
parent
e67d512f89
commit
bb3a472eeb
|
@ -9,7 +9,7 @@ macro_rules! constmod {
|
||||||
}
|
}
|
||||||
|
|
||||||
constmod!(pub opcode(u8) {
|
constmod!(pub opcode(u8) {
|
||||||
NOP = 0, // _
|
NOP = 0, // N
|
||||||
ADD = 1, // RRR
|
ADD = 1, // RRR
|
||||||
SUB = 2, // RRR
|
SUB = 2, // RRR
|
||||||
MUL = 3, // RRR
|
MUL = 3, // RRR
|
||||||
|
@ -37,8 +37,8 @@ constmod!(pub opcode(u8) {
|
||||||
|
|
||||||
JMP = 100, // I
|
JMP = 100, // I
|
||||||
JMPCOND = 101, // I
|
JMPCOND = 101, // I
|
||||||
RET = 103, // _
|
RET = 103, // N
|
||||||
ECALL = 255, // _
|
ECALL = 255, // N
|
||||||
});
|
});
|
||||||
|
|
||||||
#[repr(packed)] pub struct ParamRRR(pub u8, pub u8, pub u8);
|
#[repr(packed)] pub struct ParamRRR(pub u8, pub u8, pub u8);
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
use hbvm::{vm::Vm, RuntimeErrors};
|
use hbvm::{validate::validate, vm::Vm, RuntimeErrors};
|
||||||
|
|
||||||
fn main() -> Result<(), RuntimeErrors> {
|
fn main() -> Result<(), RuntimeErrors> {
|
||||||
// TODO: Grab program from cmdline
|
// TODO: Grab program from cmdline
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let prog = &[];
|
let prog = &[];
|
||||||
|
|
||||||
|
if let Err(e) = validate(prog) {
|
||||||
|
eprintln!("Program validation error: {e:?}");
|
||||||
|
return Ok(());
|
||||||
|
} else {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut vm = Vm::new_unchecked(prog);
|
let mut vm = Vm::new_unchecked(prog);
|
||||||
vm.run();
|
vm.run();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
macro_rules! bail {
|
||||||
|
($kind:ident, $start:expr, $curr:expr, $offset:expr) => {
|
||||||
|
return Err(Error {
|
||||||
|
kind: ErrorKind::$kind,
|
||||||
|
index: ($curr.as_ptr() as usize) - ($start.as_ptr() as usize) + $offset
|
||||||
|
})
|
||||||
|
};
|
||||||
|
($kind:ident, $start:expr, $curr:expr) => {
|
||||||
|
bail!($kind, $start, $curr, 0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub enum ErrorKind {
|
||||||
|
InvalidInstruction,
|
||||||
|
InvalidRegister,
|
||||||
|
Unimplemented,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub struct Error {
|
||||||
|
kind: ErrorKind,
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn validate(mut program: &[u8]) -> Result<(), Error> {
|
||||||
|
use crate::bytecode::opcode::*;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn reg(regs: &[u8]) -> Option<usize> {
|
||||||
|
regs.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(n, &r)| (r > 59).then_some(n))
|
||||||
|
.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
let start = program;
|
||||||
|
loop {
|
||||||
|
program = match program {
|
||||||
|
[] => return Ok(()),
|
||||||
|
// N
|
||||||
|
[NOP | RET | ECALL, rest @ ..] => rest,
|
||||||
|
// RRR
|
||||||
|
[ADD..=XOR | ADDF..=DIVF, _, _, _, rest @ ..] => {
|
||||||
|
if let Some(n) = reg(&program[1..=3]) {
|
||||||
|
bail!(InvalidRegister, start, program, n + 1)
|
||||||
|
}
|
||||||
|
rest
|
||||||
|
}
|
||||||
|
// RR
|
||||||
|
[NOT, _, _, rest @ ..] => {
|
||||||
|
if let Some(n) = reg(&program[1..=2]) {
|
||||||
|
bail!(InvalidRegister, start, program, n + 1)
|
||||||
|
}
|
||||||
|
rest
|
||||||
|
}
|
||||||
|
// RI
|
||||||
|
[LI, reg, _, _, _, _, _, _, _, _, rest @ ..] => {
|
||||||
|
if *reg > 59 {
|
||||||
|
bail!(InvalidRegister, start, program, 1)
|
||||||
|
}
|
||||||
|
rest
|
||||||
|
}
|
||||||
|
[LD | ST, ..] => bail!(Unimplemented, start, program),
|
||||||
|
_ => bail!(InvalidInstruction, start, program),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue