From bd319140bc318f96bd6afc08845eb7a1f4bfa699 Mon Sep 17 00:00:00 2001 From: jpl Date: Mon, 30 Jan 2023 20:44:17 +0000 Subject: [PATCH] Restructure compilation order so as to not have any label jumps larger than 256 words. Also fix add not adding --- src/assembler.rs | 7 ++++ src/compiler.rs | 97 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 78 insertions(+), 26 deletions(-) diff --git a/src/assembler.rs b/src/assembler.rs index f6dc5ea..ed9de36 100644 --- a/src/assembler.rs +++ b/src/assembler.rs @@ -242,6 +242,13 @@ impl LC3Assembler { self.not(dest, src).add(dest, dest, AddMode::Immediate(1)) } + pub fn inc(&mut self, r: Register) -> &mut Self { + self.add(r, r, AddMode::Immediate(1)) + } + pub fn dec(&mut self, r: Register) -> &mut Self { + self.add(r, r, AddMode::Immediate(-1i16 as Word)) + } + pub fn sub( &mut self, dest: Register, diff --git a/src/compiler.rs b/src/compiler.rs index 8aad4c4..09577f7 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -55,6 +55,7 @@ impl ForthCompiler { } fn load_intermediate_cells(&mut self) -> &mut Self { let pc = self.asm.pc() + 1; + let cells = vec![ ("latest", pc + 1), ("latest_val", self.link), @@ -204,7 +205,7 @@ impl ForthCompiler { self } - fn word(&mut self, name: String, flags: Word) -> &mut Self { + fn word(&mut self, name: &str, flags: Word) -> &mut Self { let pc = self.asm.pc(); eprintln!("WORD: {} has address: {:#X?}", name, pc); self.asm.fill(AsmAddr::Word(self.link)); @@ -218,7 +219,7 @@ impl ForthCompiler { self } - fn var(&mut self, name: String, label: &'static str) -> &mut Self { + fn var(&mut self, name: &str, label: &'static str) -> &mut Self { self.word(name, 0); let addr = self.asm.reference_label(label); self.asm @@ -233,7 +234,7 @@ impl ForthCompiler { } fn build_fetch(&mut self) -> &mut Self { - self.word(String::from("@"), 0) + self.word("@", 0) .asm .load_register(R0, Self::SP, 0) .load_register(R0, R0, 0) @@ -244,7 +245,7 @@ impl ForthCompiler { } fn build_store(&mut self) -> &mut Self { - self.word(String::from("!"), 0) + self.word("!", 0) .asm .load_register(R0, Self::SP, 0) .load_register(R1, Self::SP, -1i16 as Word) @@ -257,10 +258,11 @@ impl ForthCompiler { } fn build_add(&mut self) -> &mut Self { - self.word(String::from("+"), 0) + self.word("+", 0) .asm .load_register(R0, Self::SP, 0) .load_register(R1, Self::SP, -1i16 as Word) + .add(R1, R1, AddMode::Register(R0)) .add(Self::SP, Self::SP, AddMode::Immediate(-1i16 as Word)) .store(R1, Self::SP, 0); let next = self.asm.reference_label("next"); @@ -269,7 +271,7 @@ impl ForthCompiler { } fn build_key(&mut self) -> &mut Self { - self.word(String::from("key"), 0) + self.word("key", 0) .get_char() .asm .add(Self::SP, Self::SP, AddMode::Immediate(1)) @@ -280,10 +282,11 @@ impl ForthCompiler { self } fn build_emit(&mut self) -> &mut Self { - self.word(String::from("emit"), 0) - .asm - .load_register(R0, Self::SP, 0) - .add(Self::SP, Self::SP, AddMode::Immediate(-1i16 as Word)); + self.word("emit", 0).asm.load_register(R0, Self::SP, 0).add( + Self::SP, + Self::SP, + AddMode::Immediate(-1i16 as Word), + ); self.out_char(); let next = self.asm.reference_label("next"); self.asm.branch_unconditionally(next); @@ -291,14 +294,14 @@ impl ForthCompiler { self } fn build_bye(&mut self) -> &mut Self { - self.word(String::from("bye"), 0).asm.halt(); + self.word("bye", 0).asm.halt(); let next = self.asm.reference_label("next"); self.asm.branch_unconditionally(next); self } fn build_exit(&mut self) -> &mut Self { - self.word(String::from("exit"), 0) + self.word("exit", 0) .asm .label("exit") .load_register(Self::IP, Self::RP, 0) @@ -309,7 +312,7 @@ impl ForthCompiler { self } fn build_interpret(&mut self) -> &mut Self { - self.word(String::from(";"), Self::FLAG_IMMEDIATE) + self.word(";", Self::FLAG_IMMEDIATE) .asm .and(R1, R1, AndMode::Immediate(0)); let state = self.asm.reference_label("state"); // Set state to interpret @@ -325,7 +328,7 @@ impl ForthCompiler { } fn build_compile(&mut self) -> &mut Self { - self.word(String::from(":"), 0); + self.word(":", 0); let token = self.asm.reference_label("token"); self.asm.subroutine(AsmJsrMode::Addr(token)); @@ -391,6 +394,34 @@ impl ForthCompiler { self } + + fn build_zero(&mut self) -> &mut Self { + self.word("0", 0) + .asm + .zero(R0) + .inc(Self::SP) + .store(R0, Self::SP, 0); + + let next = self.asm.reference_label("next"); + self.asm.branch_unconditionally(next); + + self + } + + fn build_one(&mut self) -> &mut Self { + self.word("1", 0) + .asm + .zero(R0) + .inc(R0) + .inc(Self::SP) + .store(R0, Self::SP, 0); + + let next = self.asm.reference_label("next"); + self.asm.branch_unconditionally(next); + + self + } + fn builtin_words(&mut self) -> &mut Self { self.build_fetch() .build_store() @@ -401,14 +432,18 @@ impl ForthCompiler { .build_exit() .build_interpret() .build_compile() - .build_docol(); + .build_docol() + .build_zero() + .build_one(); + + eprintln!("WTF: {:#X?}", self.asm.pc); self } fn builtin_vars(&mut self) -> &mut Self { - self.var(String::from("latest"), "latest") - .var(String::from("state"), "state") - .var(String::from("here"), "here"); + self.var("latest", "latest") + .var("state", "state") + .var("here", "here"); self } @@ -542,16 +577,15 @@ impl ForthCompiler { self.out_char(); // Restart - let start = self.asm.reference_label("start"); - self.asm.branch_unconditionally(start); - self + self.jump_to_start() } fn start(&mut self) -> &mut Self { self.asm.label("start"); let toin = self.asm.reference_label("toin"); + eprintln!("=== TOIN LABEL {:?}", toin); self.asm.load(R0, toin); let tib = self.asm.reference_label("tib"); @@ -567,25 +601,36 @@ impl ForthCompiler { let rp_addr = self.asm.reference_label("rp_addr"); self.asm.load(Self::RP, rp_addr); + let intrp = self.asm.reference_label("intrp"); + self.asm.branch_unconditionally(intrp); + + self + } + + fn jump_to_start(&mut self) -> &mut Self { + let start = self.asm.reference_label("start"); + self.asm.branch_unconditionally(start); self } pub fn compile(&mut self) -> Result<&mut Self> { self.start() - .interpret_loop() - .parse_words() - .read_input() - .define_next() .builtin_words() .builtin_vars() .load_intermediate_cells() - // .print_tib()? + .interpret_loop() + .read_input() + .define_next() + .parse_words() .halt() .error() .assemble()?; // eprintln!("{:?}", self.asm.instructions); // eprintln!("{:?}", self.assembled_instructions); + for (label, addr) in &self.asm.labels { + eprintln!("== LABEL: {} {:#X?}", label, addr); + } Ok(self) } -- 2.45.2