From 6ea3a76d74bb6448c7ac31eec868bfbda1307a1a Mon Sep 17 00:00:00 2001 From: zxq5 Date: Sun, 22 Jun 2025 05:19:55 +0100 Subject: [PATCH] fixed some bugs with file picker & loading different file types - will start working on brainf##k interpreter tomorrow because a compiler isn't enough. --- emulator/src/emulator/ui/editor.rs | 144 +++++++++++++++++++++++------ resources/dsa/test.dsa | 8 +- 2 files changed, 119 insertions(+), 33 deletions(-) diff --git a/emulator/src/emulator/ui/editor.rs b/emulator/src/emulator/ui/editor.rs index 3a15aca..1a1f0a1 100644 --- a/emulator/src/emulator/ui/editor.rs +++ b/emulator/src/emulator/ui/editor.rs @@ -1,5 +1,6 @@ use std::{ ffi::OsStr, + fs, path::{Path, PathBuf}, sync::mpsc::Sender, }; @@ -147,7 +148,29 @@ impl Editor { if let Some(path) = &self.path { // Save to existing path - if let Err(why) = std::fs::write(path, &self.text) { + self.buffer = self.text.clone(); + + let text = if path.extension().is_some_and(|ext| ext == "dsb") { + let mut res = Vec::new(); + for line in self.text.lines() { + for line in line.split_whitespace() { + match u32::from_str_radix(line, 16) { + Ok(num) => res.push(num), + Err(e) => { + self.error = Some(format!("Failed to parse file: {e}")); + return; + } + } + } + } + res.into_iter() + .flat_map(u32::to_be_bytes) + .collect::>() + } else { + self.text.as_bytes().to_vec() + }; + + if let Err(why) = std::fs::write(path, text) { self.error = Some(format!("Failed to save file: {why}")); } else { self.unsaved = false; @@ -231,15 +254,39 @@ impl Editor { if let Some(dialog) = &mut self.open_file_dialog { if dialog.show(ctx).selected() { if let Some(file) = dialog.path() { - match std::fs::read_to_string(file) { - Ok(content) => { - self.text = content; - self.path = Some(file.to_path_buf()); - self.unsaved = false; - self.error = None; + // check if the file is a binary file + if file.extension().is_some_and(|ext| ext == "dsb") { + match std::fs::read(file) { + Ok(content) => { + let mut res = String::new(); + for (i, b) in content.iter().enumerate() { + res.push_str(&format!("{b:02x}")); + if i % 4 == 3 { + res.push('\n'); + } + } + self.text = res.clone(); + self.buffer = res; + self.path = Some(file.to_path_buf()); + self.unsaved = false; + self.error = None; + } + Err(e) => { + self.error = Some(format!("Failed to read file: {e}")); + } } - Err(e) => { - self.error = Some(format!("Failed to read file: {e}")); + } else { + match std::fs::read_to_string(file) { + Ok(content) => { + self.text = content.clone(); + self.buffer = content; + self.path = Some(file.to_path_buf()); + self.unsaved = false; + self.error = None; + } + Err(e) => { + self.error = Some(format!("Failed to read file: {e}")); + } } } } @@ -251,7 +298,30 @@ impl Editor { if let Some(dialog) = &mut self.save_file_dialog { if dialog.show(ctx).selected() { if let Some(file) = dialog.path() { - match std::fs::write(file, &self.text) { + self.buffer = self.text.clone(); + + let content = if file.extension().is_some_and(|ext| ext == "dsb") { + let mut res = Vec::new(); + for line in self.text.lines() { + for line in line.split_whitespace() { + match u32::from_str_radix(line, 16) { + Ok(num) => res.push(num), + Err(e) => { + self.error = + Some(format!("Failed to parse file: {e}")); + return; + } + } + } + } + res.into_iter() + .flat_map(u32::to_be_bytes) + .collect::>() + } else { + self.text.clone().as_bytes().to_vec() + }; + + match std::fs::write(file, content) { Ok(()) => { self.path = Some(file.to_path_buf()); self.unsaved = false; @@ -420,6 +490,41 @@ impl Editor { }); } + fn build(&mut self) { + if let Some(path) = &self.path { + match path.extension().and_then(|ext| ext.to_str()) { + Some("dsa") => { + let mut compiler = CompilerEngine::new(); + compiler.start_compilation(path); + + // Or block until done + let instructions = match compiler.wait_for_result() { + Ok(instructions) => instructions, + Err(e) => { + self.error = Some(e.to_string()); + return; + } + }; + + self.output = instructions + .iter() + .flat_map(|i| i.encode().to_be_bytes().to_vec()) + .collect(); + } + Some("dsb") => { + if let Ok(bytes) = fs::read(path) { + self.output = bytes; + } else { + self.error = Some("Failed to read file".to_string()); + } + } + _ => { + self.error = Some(format!("Invalid file type: {}", self.filename())); + } + } + } + } + fn render_toolbar(&mut self, _state: &mut State, ui: &mut Ui, ctx: &Context) { self.handle_file_dialogs(ctx); @@ -451,24 +556,7 @@ impl Editor { // builds the current file if ui.button("Build").clicked() && !self.unsaved { - if let Some(path) = &self.path { - let mut compiler = CompilerEngine::new(); - compiler.start_compilation(path); - - // Or block until done - let instructions = match compiler.wait_for_result() { - Ok(instructions) => instructions, - Err(e) => { - self.error = Some(e.to_string()); - return; - } - }; - - self.output = instructions - .iter() - .flat_map(|i| i.encode().to_be_bytes().to_vec()) - .collect(); - } + self.build(); } // Loads the generated binary into the assembler at the provided offset diff --git a/resources/dsa/test.dsa b/resources/dsa/test.dsa index 06abc66..667229e 100644 --- a/resources/dsa/test.dsa +++ b/resources/dsa/test.dsa @@ -1,7 +1,7 @@ include print "./lib/print.dsa" dw stack: 0x10000 -db string: "Hello world frfrfr" +db string: "Hello world" init: // set up a stack. @@ -9,12 +9,10 @@ init: mov bpr, spr start: - // string, rg1 - lli 87, rg1 + lwi string, rg1 push rg1 - - call print::print_byte + call print::print pop rg1 hlt \ No newline at end of file