diff --git a/Cargo.lock b/Cargo.lock index 700d79f..3d4ee0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -659,12 +659,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "colorful" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb474a9c3219a8254ead020421ecf1b90427f29b55f6aae9a2471fa62c126ef" - [[package]] name = "combine" version = "4.6.7" @@ -909,16 +903,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" -[[package]] -name = "dsa_editor" -version = "0.1.0" -dependencies = [ - "colorful", - "eframe", - "egui", - "serde", -] - [[package]] name = "ecolor" version = "0.31.1" @@ -1021,6 +1005,14 @@ dependencies = [ "winit", ] +[[package]] +name = "egui_code_editor" +version = "0.2.13" +source = "git+https://github.com/zxq5-dev/egui_code_editor?rev=5eb313e#5eb313e38504410ce0a6b27231cda28842f542fe" +dependencies = [ + "egui", +] + [[package]] name = "egui_glow" version = "0.31.1" @@ -1058,6 +1050,7 @@ dependencies = [ "discord-presence", "eframe", "egui", + "egui_code_editor", "rfd", "toml", ] diff --git a/assembler/src/lib.rs b/assembler/src/lib.rs index d7fdb55..a3fa315 100644 --- a/assembler/src/lib.rs +++ b/assembler/src/lib.rs @@ -3,7 +3,7 @@ use std::{ collections::HashSet, fs, hash::{DefaultHasher, Hash, Hasher}, - path::PathBuf, + path::{Path, PathBuf}, }; use common::prelude::Instruction; @@ -17,27 +17,27 @@ pub mod lexer; pub mod model; pub mod parser; -pub fn assemble(src: &PathBuf) -> Vec { +pub fn assemble(src: &Path) -> Vec { let mut modules = HashSet::::new(); let mut program = Program::new(); let hash = quick_hash(src); modules.insert(hash); - match prepare_dependency(src.clone(), &mut modules, &mut program) { + match prepare_dependency(src, &mut modules, &mut program) { Ok(_) => {} - Err(err) => println!("BIG ERROR {:?}", err), + Err(err) => println!("BIG ERROR {err:?}"), } for node in program.nodes { - println!("{:?}", node); + println!("{node:?}"); } vec![] } fn prepare_dependency( - path: PathBuf, + path: &Path, modules: &mut HashSet, program: &mut Program, ) -> Result<(), AssembleError> { @@ -51,9 +51,9 @@ fn prepare_dependency( )); } - let src = fs::read_to_string(&path) - .map_err(|_| AssembleError::InvalidFile(path.clone()))?; - let file_hash = quick_hash(&path); + let src = fs::read_to_string(path) + .map_err(|_| AssembleError::InvalidFile(path.to_path_buf()))?; + let file_hash = quick_hash(path); log(&format!("{:20} {:20}", "Tokenising", filename)); let tokens = lexer::lexer(src, file_hash)?; @@ -77,14 +77,14 @@ fn prepare_dependency( if !modules.contains(&quick_hash(&dep)) { modules.insert(quick_hash(&dep)); - prepare_dependency(dep, modules, program)? + prepare_dependency(dep.as_path(), modules, program)? } } Ok(()) } -fn build(src: Vec) -> Result, AssembleError> { +fn _build(_src: Vec) -> Result, AssembleError> { Ok(vec![]) } @@ -116,12 +116,13 @@ impl fmt::Display for AssembleError { } } -fn quick_hash(value: &PathBuf) -> u64 { +fn quick_hash(value: &Path) -> u64 { let mut hasher = DefaultHasher::new(); value.canonicalize().unwrap().to_str().hash(&mut hasher); hasher.finish() } +// TODO: Use an actual logging or tracing library for pretty (scoped) output. fn log(message: &str) { - println!("\x1b[32mINFO:\x1b[0m {}", message); + println!("\x1b[32mINFO:\x1b[0m {message}"); } diff --git a/assembler/src/main.rs b/assembler/src/main.rs index 7645a1a..b01f13a 100644 --- a/assembler/src/main.rs +++ b/assembler/src/main.rs @@ -1,8 +1,5 @@ use std::{fs, io::Write, path::PathBuf}; -use assembler::{lexer, parser::Parser}; -use common::prelude::{ITypeArgs, Instruction, RTypeArgs, Register}; - fn main() { // parse args: let args: Vec = std::env::args().collect(); @@ -16,7 +13,7 @@ fn main() { let src = PathBuf::from(input_path); let mut output_file = fs::File::create(output_path).unwrap(); - let res = assembler::assemble(&src) + assembler::assemble(&src) .iter() .map(|i| i.encode()) .for_each(|i| { diff --git a/assembler/src/model.rs b/assembler/src/model.rs index dd5aeae..dc8a9cd 100644 --- a/assembler/src/model.rs +++ b/assembler/src/model.rs @@ -3,13 +3,12 @@ use std::{fmt, str::FromStr}; use common::prelude::Register; #[derive(Debug, Clone)] -#[expect(dead_code)] pub struct Node(pub Option, pub Opcode, pub Vec); impl fmt::Display for Node { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let symbol = match &self.0 { - Some(symbol) => format!("{}", symbol), + Some(symbol) => format!("{symbol}"), None => "".to_string(), }; @@ -26,15 +25,65 @@ impl fmt::Display for Symbol { impl fmt::Display for Module { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Module::Unresolved(name) => write!(f, "{}", name), - Module::Resolved(name) => write!(f, "{}", name), + Module::Unresolved(name) => write!(f, "{name}"), + Module::Resolved(name) => write!(f, "{name}"), } } } impl fmt::Display for Opcode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self) + match self { + Opcode::Nop => write!(f, "nop"), + Opcode::Mov => write!(f, "mov"), + Opcode::Movs => write!(f, "movs"), + Opcode::Ldb => write!(f, "ldb"), + Opcode::Ldbs => write!(f, "ldbs"), + Opcode::Ldh => write!(f, "ldh"), + Opcode::Ldhs => write!(f, "ldhs"), + Opcode::Ldw => write!(f, "ldw"), + Opcode::Stb => write!(f, "stb"), + Opcode::Sth => write!(f, "sth"), + Opcode::Stw => write!(f, "stw"), + Opcode::Lli => write!(f, "lli"), + Opcode::Lui => write!(f, "lui"), + Opcode::Jmp => write!(f, "jmp"), + Opcode::Jeq => write!(f, "jeq"), + Opcode::Jne => write!(f, "jne"), + Opcode::Jgt => write!(f, "jgt"), + Opcode::Jge => write!(f, "jge"), + Opcode::Jlt => write!(f, "jlt"), + Opcode::Jle => write!(f, "jle"), + Opcode::Cmp => write!(f, "cmp"), + Opcode::Inc => write!(f, "inc"), + Opcode::Dec => write!(f, "dec"), + Opcode::Shl => write!(f, "shl"), + Opcode::Shr => write!(f, "shr"), + Opcode::Add => write!(f, "add"), + Opcode::Sub => write!(f, "sub"), + Opcode::And => write!(f, "and"), + Opcode::Or => write!(f, "or"), + Opcode::Not => write!(f, "not"), + Opcode::Xor => write!(f, "xor"), + Opcode::Nand => write!(f, "nand"), + Opcode::Nor => write!(f, "nor"), + Opcode::Xnor => write!(f, "xnor"), + Opcode::Int => write!(f, "int"), + Opcode::Irt => write!(f, "irt"), + Opcode::Hlt => write!(f, "hlt"), + Opcode::Iadd => write!(f, "iadd"), + Opcode::Isub => write!(f, "isub"), + Opcode::Db => write!(f, "db"), + Opcode::Dh => write!(f, "dh"), + Opcode::Dw => write!(f, "dw"), + Opcode::Resb => write!(f, "resb"), + Opcode::Resh => write!(f, "resh"), + Opcode::Resw => write!(f, "resw"), + Opcode::Push => write!(f, "push"), + Opcode::Pop => write!(f, "pop"), + Opcode::Lwi => write!(f, "lwi"), + Opcode::Include => write!(f, "include"), + } } } diff --git a/assembler/src/parser.rs b/assembler/src/parser.rs index eb1457e..53ff115 100644 --- a/assembler/src/parser.rs +++ b/assembler/src/parser.rs @@ -1,6 +1,4 @@ -use core::fmt; use std::path::PathBuf; -use std::str::FromStr; use common::prelude::{Instruction, Register}; @@ -33,6 +31,12 @@ impl Program { } } +impl Default for Program { + fn default() -> Self { + Self::new() + } +} + impl Parser { pub fn new(tokens: Vec) -> Parser { Parser { @@ -68,7 +72,7 @@ impl Parser { for node in &self.nodes { if let Opcode::Include = node.1 { // we want the path, and the name - let name = if let Token::Symbol(name) = node.2.get(0).unwrap() { + let name = if let Token::Symbol(name) = node.2.first().unwrap() { name.name.clone() } else { unreachable!() @@ -129,7 +133,7 @@ impl Parser { // inc SPR // STW reg, SPR let label = node.0.clone(); - let reg = node.2.get(0).unwrap(); + let reg = node.2.first().unwrap(); vec![ Node( diff --git a/emulator/Cargo.toml b/emulator/Cargo.toml index b8bd3e0..4c1796a 100644 --- a/emulator/Cargo.toml +++ b/emulator/Cargo.toml @@ -10,7 +10,7 @@ path = "src/lib.rs" [dependencies] common = { path = "../common" } assembler = { path = "../assembler" } -dsa_editor = { path = "../dsa_editor" } +dsa_editor = { git = "https://github.com/zxq5-dev/egui_code_editor", package = "egui_code_editor", rev = "5eb313e" } eframe = "0.31.1" egui = "0.31.1" rfd = "0.15.3" diff --git a/emulator/src/emulator/ui/editor.rs b/emulator/src/emulator/ui/editor.rs index 70343c7..5fd7096 100644 --- a/emulator/src/emulator/ui/editor.rs +++ b/emulator/src/emulator/ui/editor.rs @@ -43,7 +43,7 @@ impl Component for Editor { if ui.input(|i| i.key_pressed(Key::S) && i.modifiers.ctrl) { self.save(); - }; + } self.render_toolbar(state, ui, ctx); @@ -87,17 +87,23 @@ impl Editor { fn filename(&self) -> &str { self.path .file_name() - .unwrap_or(OsStr::new("Unnamed!")) + .unwrap_or_else(|| OsStr::new("Unnamed!")) .to_str() - .unwrap() + .map_or_else( + || unreachable!("File name should be valid UTF-8."), + |ext| ext, + ) } fn extension(&self) -> &str { self.path .extension() - .unwrap_or(OsStr::new("Unknown!")) + .unwrap_or_else(|| OsStr::new("Unknown!")) .to_str() - .unwrap() + .map_or_else( + || unreachable!("File name should be valid UTF-8."), + |ext| ext, + ) } fn save(&mut self) { @@ -210,10 +216,10 @@ impl Editor { ); // Instruction column - let instruction = match Instruction::decode(value) { - Ok(instruction) => instruction.to_string(), - Err(_) => format!("{value:10}"), - }; + let instruction = Instruction::decode(value).map_or_else( + |_| format!("{value:10}"), + |instruction| instruction.to_string(), + ); ui.label( egui::RichText::new(instruction) @@ -230,19 +236,25 @@ impl Editor { fn render_editor(&mut self, _state: &mut State, ui: &mut Ui, _ctx: &Context) { let available_width = ui.available_width(); let syntax = match self.extension() { - "dsa" => Syntax::dsa(), - _ => Syntax::dsa(), + "dsa" => Some(Syntax::new("dsa")), + _ => None, }; - CodeEditor::default() + let ed = CodeEditor::default() .id_source("editor") .with_fontsize(12.0) .with_rows(0) .with_theme(ColorTheme::default()) - .with_syntax(syntax) .with_numlines(true) - .desired_width(available_width - 450.0) - .show(ui, &mut self.text); + .desired_width(available_width - 450.0); + + let mut editor = ed.clone(); + + if let Some(syntax) = syntax { + editor = ed.with_syntax(syntax); + } + + editor.show(ui, &mut self.text); } fn render_toolbar(&mut self, _state: &mut State, ui: &mut Ui, _ctx: &Context) {