~jpl8/lorthc3

afdf69f6afc6ba28cd19017371f3e56342619682 — jpl 1 year, 27 days ago 4acd311
Make latest point to compile time link
1 files changed, 47 insertions(+), 16 deletions(-)

M src/compiler.rs
M src/compiler.rs => src/compiler.rs +47 -16
@@ 55,7 55,7 @@ impl ForthCompiler {
        let cells = vec![
            ("tib", Self::TIB),
            ("toin", Self::TOIN),
            ("latest", Self::LATEST),
            ("latest", self.link),
            ("state", Self::STATE),
            ("here", Self::HERE),
            ("sp_addr", Self::SP_ADDR),


@@ 98,8 98,7 @@ impl ForthCompiler {
        self.asm
            .store(R0, R1, 0)
            .add(R1, R1, AddMode::Immediate(1 as Word))
            .not(R0, R0)
            .and(R0, R0, AndMode::Immediate('\n' as Word));
            .add(R0, R0, AddMode::Immediate(-('\n' as SignedWord) as Word));
        let readlp = self.asm.reference_label("readlp");
        self.asm
            .branch(


@@ 184,7 183,10 @@ impl ForthCompiler {
            .add(R0, R0, AddMode::Register(R1));

        let findws = self.asm.reference_label("findws");
        self.asm.branch(ConditionCode::ZER as Word, findws);
        self.asm.branch(
            ConditionCode::NEG as Word | ConditionCode::POS as Word,
            findws,
        );

        self.asm.label("tokend");
        let toin = self.asm.reference_label("toin");


@@ 198,8 200,9 @@ impl ForthCompiler {
    }

    fn word(&mut self, name: String, flags: Word) -> &mut Self {
        let pc = self.asm.pc();
        self.asm.fill(AsmAddr::Word(self.link));
        self.link = self.asm.pc();
        self.link = pc;
        self.asm.fill(AsmAddr::Word(name.len() as Word + flags));

        for byte in name.as_bytes() {


@@ 209,13 212,16 @@ impl ForthCompiler {
        self
    }

    fn var(&mut self, name: String, ptr: AsmAddr, next: AsmAddr) -> &mut Self {
        self.word(name, 0)
            .asm
            .load(R0, ptr)
    fn var(&mut self, name: String, label: &'static str) -> &mut Self {
        self.word(name, 0);
        let addr = self.asm.reference_label(label);
        self.asm
            .load(R0, addr)
            .add(Self::SP, Self::SP, AddMode::Immediate(1))
            .store(R0, Self::SP, 0)
            .branch_unconditionally(next);
            .store(R0, Self::SP, 0);

        let next = self.asm.reference_label("next");
        self.asm.branch_unconditionally(next);

        self
    }


@@ 237,13 243,34 @@ impl ForthCompiler {
            .load_register(R1, Self::SP, -1i16 as Word)
            .store(R1, R0, 0)
            .add(Self::SP, Self::SP, AddMode::Immediate(-2i16 as Word));
        let next = self.asm.reference_label("next");
        self.asm.branch_unconditionally(next);

        // Add
        self.word(String::from("+"), 0)
            .asm
            .load_register(R0, Self::SP, 0)
            .load_register(R1, Self::SP, -1i16 as Word)
            .add(Self::SP, Self::SP, AddMode::Immediate(-1i16 as Word))
            .store(R1, Self::SP, 0);
        let next = self.asm.reference_label("next");
        self.asm.branch_unconditionally(next);

        self.word(String::from("bye"), 0).asm.halt();
        let next = self.asm.reference_label("next");
        self.asm.branch_unconditionally(next);

        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
    }

    pub fn print_tib(&mut self) -> Result<&mut Self> {
        let tib_addr = self.asm.reference_label("tib");
        self.asm.instr(LD(R0, tib_addr));


@@ 272,7 299,8 @@ impl ForthCompiler {
            .store(R3, Self::SP, 3);

        let latest = self.asm.reference_label("latest");
        self.asm.load_indirect(R0, latest).label("is_match");
        self.asm.load(R0, latest);
        self.asm.label("is_match");

        let error = self.asm.reference_label("error");
        self.asm


@@ 282,7 310,8 @@ impl ForthCompiler {
            .load_register(R2, Self::SP, 3)
            .load_register(R3, R0, 1)
            .and(R3, R3, AndMode::Immediate(0xf)) // mask to get the word length and not the flags
            .sub(R3, R3, R3, R2);
            .neg(R3, R3)
            .add(R3, R3, AddMode::Register(R2));

        let no_match = self.asm.reference_label("no_match");
        self.asm.branch(


@@ 294,7 323,8 @@ impl ForthCompiler {
            .label("nextc")
            .load_register(Self::IP, R0, 2)
            .load_register(R3, R1, 0)
            .sub(R3, R3, Self::IP, R3);
            .neg(R3, R3)
            .add(R3, R3, AddMode::Register(Self::IP));

        let no_match = self.asm.reference_label("no_match");
        self.asm


@@ 390,14 420,15 @@ impl ForthCompiler {
    }

    pub fn compile(&mut self) -> Result<&mut Self> {
        self.load_intermediate_cells()
            .error()
        self.error()
            .start()
            .interpret_loop()
            .parse_words()
            .read_input()
            .define_next()
            .builtin_words()
            .builtin_vars()
            .load_intermediate_cells()
            // .print_tib()?
            .halt()
            .assemble()?;