Skip to content

Instantly share code, notes, and snippets.

@flaviusb
Last active September 18, 2024 13:42
Show Gist options
  • Save flaviusb/445eb4c946a72058d0bb60e2958bc5d0 to your computer and use it in GitHub Desktop.
Save flaviusb/445eb4c946a72058d0bb60e2958bc5d0 to your computer and use it in GitHub Desktop.
An example of the thing I'm trying to be able to do with Instruction matcher code
type ip = u16;
#[derive(Copy,Clone,Eq,PartialEq,Debug)]
pub enum Instruction {
Nop,
Jmp { loc: ip },
Not { length: u8, start: ip, out: ip },
Copy { length: u8, start: ip, out: ip },
}
trait Decode<const N: usize, const M: usize, T> {
type DECODE;
const REAL: usize = M;
fn decode(it: [T; N]) -> Self;
}
impl Decode<0, 0, u8> for Instruction {
type DECODE = fn([u8; 0]) -> Instruction;
fn decode(it: [u8; 0]) -> Self {
Instruction::Nop
}
}
impl Decode<2, 3, u8> for Instruction { // This is 3 4-bit words
type DECODE = fn([u8; 2]) -> Instruction;
fn decode(it: [u8; 2]) -> Self {
match it[0] & 0b00001111 {
0 => Instruction::Jmp { loc: 0 },
_ => panic!(),
}
}
}
impl Decode<4, 7, u8> for Instruction { // This is 7 4-bit words
type DECODE = fn([u8; 4]) -> Instruction;
fn decode(it: [u8; 4]) -> Self {
match it[0] & 0b00001111 {
0 => Instruction::Not { length: 1, start: 0, out: 1 },
1 => Instruction::Copy { length: 1, start: 0, out: 1 },
_ => panic!(),
}
}
}
impl Decode<4, 8, u8> for Instruction { // This is 8 4-bit words
type DECODE = fn([u8; 4]) -> Instruction;
fn decode(it: [u8; 4]) -> Self {
match it[0] & 0b00001111 {
0 => Instruction::Not { length: 2 + (it[0] >> 4), start: 0, out: 1 },
1 => Instruction::Copy { length: 2 + (it[0] >> 4), start: 0, out: 1 },
_ => panic!(),
}
}
}
struct Words<const WORDS: usize>;
impl<const M: usize, const N: usize, T> Decode<M, N, T, Instruction> for Words<N> where Instruction : Decode::<M, N, T, Instruction> {
type DECODE = <Instruction as Decode::<M, N, T, Instruction>>::DECODE;
fn decode(it: [T; M]) -> Instruction {
<Instruction as Decode::<M, N, T, Instruction>>::decode(it)
}
}
fn main() {
println!("[] -> {:?}", Words::<0>::decode([]));
println!("[0000, and then 3 more 4 bit chunks] -> {:?}", Words::<3>::decode([0u8; 2]));
println!("[0000, and then 6 more 4 bit chunks] -> {:?}", Words::<7>::decode([0u8; 4]));
println!("[0001, and then 6 more 4 bit chunks] -> {:?}", Words::<7>::decode([1u8; 4]));
println!("[0000, and then 6 more 4 bit chunks] -> {:?}", Words::<8>::decode([0u8; 4]));
println!("[0001, and then 6 more 4 bit chunks] -> {:?}", Words::<8>::decode([1u8; 4]));
println!("[0000, and then 7 more 4 bit chunks] -> {:?}", Words::<8>::decode([0b0001_0000u8; 4]));
println!("[0001, and then 7 more 4 bit chunks] -> {:?}", Words::<8>::decode([0b0011_0001u8; 4]));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment