diff --git a/Cargo.lock b/Cargo.lock index bca5893..4db5574 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,6 +104,15 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + [[package]] name = "heck" version = "0.5.0" @@ -146,12 +155,70 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "struct_iterable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "849a064c6470a650b72e41fa6c057879b68f804d113af92900f27574828e7712" +dependencies = [ + "struct_iterable_derive", + "struct_iterable_internal", +] + +[[package]] +name = "struct_iterable_derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb939ce88a43ea4e9d012f2f6b4cc789deb2db9d47bad697952a85d6978662c" +dependencies = [ + "erased-serde", + "proc-macro2", + "quote", + "struct_iterable_internal", + "syn", +] + +[[package]] +name = "struct_iterable_internal" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9426b2a0c03e6cc2ea8dbc0168dbbf943f88755e409fb91bcb8f6a268305f4a" + [[package]] name = "syn" version = "2.0.114" @@ -170,6 +237,7 @@ dependencies = [ "clap", "data-encoding", "progress_bar", + "struct_iterable", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 17da2c9..3ded67f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2024" clap = { version = "4.5.54", features = ["derive"] } progress_bar = "1.4.0" data-encoding = "2.10.0" +struct_iterable = "0.1.1" diff --git a/src/assemble.rs b/src/assemble.rs index 63527d2..c229a45 100644 --- a/src/assemble.rs +++ b/src/assemble.rs @@ -1,10 +1,21 @@ use crate::exit; use progress_bar::*; use std::io::Write; +use std::ops::Deref; use std::{fs::File, thread::sleep, time::Duration}; +use struct_iterable::Iterable; use crate::insturctions::get_hex; +#[derive(Debug, Default, Iterable)] +struct Instruction { + opt_code: u8, + arg1: u8, + arg2: u8, + arg3: u8, + arg4: u8, +} + pub fn assemble(code: Vec, output: String) { let mut output_file = File::options() .create(true) @@ -17,36 +28,55 @@ pub fn assemble(code: Vec, output: String) { for line in code.iter() { let line_split: Vec<&str> = line.split(' ').collect(); - let instruction = line_split[0]; - let instruction_hex = get_hex(&instruction); + let mut line_iter = line_split.iter(); + let opt_code = line_split[0]; + let opt_code_hex = get_hex(&opt_code); - if !(instruction_hex.1 == (line_split.len() as i32 - 1)) { + if !(opt_code_hex.1 == (line_split.len() as i32 - 1)) { set_progress_bar_action("Error", Color::Red, Style::Normal); finalize_progress_bar(); eprintln!( "Found {} arguments for {}, but expected {}", line_split.len() as i32 - 1, - instruction, - instruction_hex.1 + opt_code, + opt_code_hex.1 ); exit(1) } - append_hex( - &mut output_file, - u8::from_str_radix( - instruction_hex.0.to_string().strip_prefix("0x").unwrap(), - 16, - ) - .unwrap(), - ); + // append_hex( + // &mut output_file, + // u8::from_str_radix(opt_code_hex.0.to_string().strip_prefix("0x").unwrap(), 16).unwrap(), + // ); + + let mut instruction = Instruction::default(); + instruction.opt_code = + u8::from_str_radix(opt_code_hex.0.to_string().strip_prefix("0x").unwrap(), 16).unwrap(); + + let mut args: Vec = Vec::new(); for arg in &line_split[1..] { - let reg = u8::from_str_radix(arg.strip_prefix("0x").unwrap_or(arg), 16).unwrap(); + args.push(u8::from_str_radix(arg.strip_prefix("0x").unwrap_or(arg), 16).unwrap()); + } + println!("{:?}", args); - append_hex(&mut output_file, reg); + if args.len() >= 1 { + instruction.arg1 = args[0]; + } + if args.len() >= 2 { + instruction.arg2 = args[1]; + } + if args.len() >= 3 { + instruction.arg3 = args[2]; + } + if args.len() >= 4 { + instruction.arg4 = args[3]; } + println!("{:?}", instruction); + println!("{}", line_split.len() - 1); + + append_hex(&mut output_file, instruction); sleep(Duration::from_millis(1)); inc_progress_bar(); } @@ -56,6 +86,10 @@ pub fn assemble(code: Vec, output: String) { println!("Finshed assembling progamm, output found in: {}", output); } -fn append_hex(file: &mut File, hex: u8) { - file.write_all(&[hex]).unwrap(); +fn append_hex(file: &mut File, instruction: Instruction) { + for (field, val) in instruction.iter() { + file + .write_all(&[*val.downcast_ref::().unwrap()]) + .unwrap(); + } } diff --git a/test.s b/test.s index 8d608f5..ca9bb5a 100644 --- a/test.s +++ b/test.s @@ -1,8 +1,8 @@ -NOP 0xA1 -HALT 0xA1 -HALI 0xA1 -LOAD 0xA2 0xA2 -STOA 0xA2 0xA2 +NOP 0x01 +HALT 0x01 +HALI 0x01 +LOAD 0x02 0x02 +STOA 0x02 0x02 MOV 0x03 0x03 0x03 PUSH 0x02 0x02 POP 0x02 0x02