~jpl8/lorthc3

1adb95ee960af7cd1ef504644b5fbeec3c93138e — jpl 1 year, 1 month ago a6782b5
Commit before implementing assembler
1 files changed, 43 insertions(+), 13 deletions(-)

M src/compiler.rs
M src/compiler.rs => src/compiler.rs +43 -13
@@ 7,6 7,7 @@ use toasty_lc3_primitives::registers::{Register, Register::*, Registers};

use anyhow::{bail, Result};

use std::collections::HashMap;
use std::iter;

use crate::lorth_instruction::LorthInstruction::{self, *};


@@ 16,8 17,7 @@ pub type SignedWord = i16;
pub struct ForthCompiler {
    instructions: Vec<LorthInstruction>,
    registers: Registers,
    tib: Option<Word>,
    toin: Option<Word>,
    labels: HashMap<String, Word>,
}

impl ForthCompiler {


@@ 29,8 29,7 @@ impl ForthCompiler {
        Self {
            instructions: vec![],
            registers: Registers::new(),
            tib: None,
            toin: None,
            labels: HashMap::new(),
        }
    }
    pub fn load(&mut self, r: Register, addr: Word) -> &mut Self {


@@ 139,20 138,25 @@ impl ForthCompiler {
    }

    fn load_intermediate_cells(&mut self) -> &mut Self {
        self.branch_unconditionally(2);
        self.tib = Some(self.pc());
        self.fill(Self::TIB);
        eprintln!("TIB: {:#02X}", self.tib.unwrap());
        self.toin = Some(self.pc());
        self.fill(Self::TOIN);
        let cells = vec![
            ("tib", Self::TIB),
            ("toin", Self::TOIN),
            ("space", ' ' as Word),
        ];

        self.branch_unconditionally(cells.len() as Word);

        for (label, val) in cells {
            self.label(label);
            self.fill(val);
        }
        self
    }

    fn get_tib(&self) -> Result<Word> {
        if let Some(tib) = self.tib {
            eprintln!("TIB: {:#02X}", self.tib.unwrap());
            Ok(tib)
        if let Some(tib) = self.labels.get("tib") {
            eprintln!("TIB: {:#02X}", tib);
            Ok(*tib)
        } else {
            bail!("TIB not allocated!")
        }


@@ 179,6 183,31 @@ impl ForthCompiler {
        Ok(self)
    }

    fn label(&mut self, s: &'static str) -> &mut Self {
        self.labels.insert(String::from(s), self.pc());
        self
    }

    fn label_addr(&self, s: &'static str) -> Result<Word> {
        if let Some(addr) = self.labels.get(s) {
            Ok(*addr)
        } else {
            bail!("Undefined label {}", s)
        }
    }

    fn load_indirect(&mut self, r: Register, addr: Word) -> &mut Self {
        self.instr(LC3(LDI(r, self.pc_offset(addr) as Word)))
    }

    fn parse_words(&mut self) -> Result<&mut Self> {
        let space = self.label_addr("space")?;
        let toin = self.label_addr("toin")?;
        self.label("token").load_indirect(R3, toin).load(R1, space);
        unimplemented!();
        Ok(self)
    }

    pub fn print_tib(&mut self) -> Result<&mut Self> {
        let tib = self.get_tib()?;
        self.instr(LC3(LD(R0, self.pc_offset(tib) as Word)));


@@ 189,6 218,7 @@ impl ForthCompiler {
    pub fn compile(&mut self) -> Result<&mut Self> {
        self.load_intermediate_cells()
            .read_input()?
            .parse_words()?
            .print_tib()?
            .halt();