~jpl8/lorthc3

bd319140bc318f96bd6afc08845eb7a1f4bfa699 — jpl 1 year, 30 days ago bc50c03 main
Restructure compilation order so as to not have any
label jumps larger than 256 words.

Also fix add not adding
2 files changed, 78 insertions(+), 26 deletions(-)

M src/assembler.rs
M src/compiler.rs
M src/assembler.rs => src/assembler.rs +7 -0
@@ 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,

M src/compiler.rs => src/compiler.rs +71 -26
@@ 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)
    }