diff options
| Commit | 8b65d8b6cf8ad44e7cae58bfda883567b8cc32fc (patch) | |
|---|---|---|
| Author | 2025-02-15 11:01:08 +0200 | |
| Committer | 2025-02-15 11:01:08 +0200 | |
| Files | 9c0ef14584e7493712d0f04fb955d813f7d56eae /assembler/src | |
| tonkobali-8b65d8b6cf8ad44e7cae58bfda883567b8cc32fc.tar tonkobali-8b65d8b6cf8ad44e7cae58bfda883567b8cc32fc.tar.gz tonkobali-8b65d8b6cf8ad44e7cae58bfda883567b8cc32fc.zip | ||
| Parent | a6a5cf874fc03296c01bb72abdcb564e5d65ddcd (diff) | |
test(assembler): Add tests
3 files changed, 207 insertions, 0 deletions
| -rw-r--r-- | assembler/src/lexer/mod.rs | 144 | ||||
| -rw-r--r-- | assembler/src/parser/code_gen.rs | 29 | ||||
| -rw-r--r-- | assembler/src/parser/semantic.rs | 34 |
diff --git a/assembler/src/lexer/mod.rs b/assembler/src/lexer/mod.rs index c8c8c83..45de90f 100644 --- a/assembler/src/lexer/mod.rs +++ b/assembler/src/lexer/mod.rs @@ -104,3 +104,147 @@ pub fn split(mut line: String) -> Vec<Token> { } res } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn splits_label() { + let res = split("label1:".to_string()); + assert_eq!(res.len(), 1); + assert!(matches!(res[0], Token::Label(_))); + if let Token::Label(name) = &res[0] { + assert_eq!(name, "label1"); + } + } + + #[test] + fn splits_lowercase_instruction_no_args() { + let res = split("instr".to_string()); + assert_eq!(res.len(), 1); + assert!(matches!(res[0], Token::Operator(_))); + if let Token::Operator(name) = &res[0] { + assert_eq!(name, "instr"); + } + } + + #[test] + fn splits_pascal_instruction_no_args() { + let res = split("Instr".to_string()); + assert_eq!(res.len(), 1); + assert!(matches!(res[0], Token::Operator(_))); + if let Token::Operator(name) = &res[0] { + assert_eq!(name, "Instr"); + } + } + + #[test] + fn splits_uppercase_instruction_no_args() { + let res = split("INSTR".to_string()); + assert_eq!(res.len(), 1); + assert!(matches!(res[0], Token::Operator(_))); + if let Token::Operator(name) = &res[0] { + assert_eq!(name, "INSTR"); + } + } + + #[test] + fn splits_instruction_symbol_arg() { + let res = split("instr x".to_string()); + assert_eq!(res.len(), 2); + + assert!(matches!(res[0], Token::Operator(_))); + if let Token::Operator(name) = &res[0] { + assert_eq!(name, "instr"); + } + + assert!(matches!(res[1], Token::Symbol(_))); + if let Token::Symbol(name) = &res[1] { + assert_eq!(name, "x"); + } + } + + #[test] + fn splits_instruction_two_symbol_arg() { + let res = split("instr x, y".to_string()); + assert_eq!(res.len(), 3); + + assert!(matches!(res[0], Token::Operator(_))); + if let Token::Operator(name) = &res[0] { + assert_eq!(name, "instr"); + } + + assert!(matches!(res[1], Token::Symbol(_))); + if let Token::Symbol(name) = &res[1] { + assert_eq!(name, "x"); + } + + assert!(matches!(res[2], Token::Symbol(_))); + if let Token::Symbol(name) = &res[2] { + assert_eq!(name, "y"); + } + } + + #[test] + fn splits_instruction_two_num_arg() { + let res = split("instr 819, 1".to_string()); + assert_eq!(res.len(), 3); + + assert!(matches!(res[0], Token::Operator(_))); + if let Token::Operator(name) = &res[0] { + assert_eq!(name, "instr"); + } + + assert!(matches!(res[1], Token::Number(_))); + if let Token::Number(value) = &res[1] { + assert_eq!(value, &819); + } + + assert!(matches!(res[2], Token::Number(_))); + if let Token::Number(value) = &res[2] { + assert_eq!(value, &1); + } + } + + #[test] + fn splits_definition() { + let res = split("somevar = 61".to_string()); + assert_eq!(res.len(), 2); + + assert!(matches!(res[0], Token::SymbolDef(_))); + if let Token::SymbolDef(name) = &res[0] { + assert_eq!(name, "somevar"); + } + } + + #[test] + fn splits_number() { + let res = split("561".to_string()); + assert_eq!(res.len(), 1); + assert!(matches!(res[0], Token::Number(_))); + if let Token::Number(value) = &res[0] { + assert_eq!(value, &561); + } + } + + #[test] + fn splits_address() { + let res = split("%561".to_string()); + assert_eq!(res.len(), 1); + assert!(matches!(res[0], Token::Address(_))); + if let Token::Address(value) = &res[0] { + assert_eq!(value, &561); + } + } + + #[test] + fn splits_string() { + let res = split("\"Hello World!\"".to_string()); + assert_eq!(res.len(), 1); + assert!(matches!(res[0], Token::String(_))); + if let Token::String(value) = &res[0] { + assert_eq!(value, "Hello World!"); + } + } +} diff --git a/assembler/src/parser/code_gen.rs b/assembler/src/parser/code_gen.rs index 2eaa34c..d183145 100644 --- a/assembler/src/parser/code_gen.rs +++ b/assembler/src/parser/code_gen.rs @@ -88,3 +88,32 @@ impl Program { .collect() } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::lexer::Token; + + #[test] + fn after_two_collapses_only_subleq_remains() { + let mut prog = Program::new(vec![ + Token::Operator("rts".to_string()), + Token::Operator("jsr".to_string()), + Token::Address(1000), + Token::Operator("mov".to_string()), + Token::Address(1001), + Token::Address(1002), + Token::Operator("subleq".to_string()), + Token::Address(1001), + Token::Address(1002), + Token::Address(1001), + + ], 10); + prog.collapse_instructions(); + prog.collapse_instructions(); + + for i in prog.instructions { + assert_eq!(i.name, "subleq"); + } + } +} diff --git a/assembler/src/parser/semantic.rs b/assembler/src/parser/semantic.rs index 47ba201..438b2f1 100644 --- a/assembler/src/parser/semantic.rs +++ b/assembler/src/parser/semantic.rs @@ -21,3 +21,37 @@ impl Program { } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::lexer::Token; + + #[test] + fn remove_definition_addresses_removes_symbols() { + let mut prog = Program::new(vec![ + Token::SymbolDef("hello".to_string()), + Token::Number(1000), + Token::SymbolDef("world".to_string()), + Token::Number(64), + Token::Operator("jsr".to_string()), + Token::Symbol("hello".to_string()), + Token::Operator("mov".to_string()), + Token::Address(1001), + Token::Symbol("world".to_string()), + Token::Operator("subleq".to_string()), + Token::Symbol("hello".to_string()), + Token::Address(1002), + Token::Symbol("world".to_string()), + + ], 10); + prog.remove_definition_addresses(); + + assert_eq!(prog.definitions.len(), 0); + for i in prog.instructions { + for arg in i.args { + assert!(! matches!(arg, Address::Definitions(_))); + } + } + } +} |
