~jakintosh/co

ce12859541431d1843bd054797fe693ca00e0003 — Jak Tiano 7 months ago b4ec9ed
fixed some issues with parsing absolute padding, cleaned up some small compiler warnings
5 files changed, 40 insertions(+), 31 deletions(-)

M Cargo.lock
M Cargo.toml
M src/assembler/context.rs
M src/parsing/byteco.rs
M src/parsing/bytecostream.rs
M Cargo.lock => Cargo.lock +1 -1
@@ 57,7 57,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"

[[package]]
name = "co"
version = "0.2.1"
version = "0.2.2"
dependencies = [
 "base64",
 "blake3",

M Cargo.toml => Cargo.toml +1 -1
@@ 1,6 1,6 @@
[package]
name = "co"
version = "0.2.1"
version = "0.2.2"
edition = "2021"

[profile.release]

M src/assembler/context.rs => src/assembler/context.rs +15 -12
@@ 141,9 141,9 @@ impl Context {
    }

    pub fn render_assembly(&mut self) -> Result<ByteCo, String> {
        let mut assembly = self.assembly.clone();
        let assembly = self.assembly.clone();
        let mut render_stack = RenderStack::new();
        byteco::render_rom(self, &mut assembly, &mut render_stack)
        byteco::render_rom(self, &assembly, &mut render_stack)
    }

    pub fn write_exports(&mut self, library: &mut Library, path: &Path) -> Result<(), String> {


@@ 164,10 164,12 @@ impl Context {
        render_stack: &mut RenderStack,
    ) -> Result<Hash, String> {
        match self.hashes.get(&label) {
            Some(hash) => Ok(hash.clone()),
            Some(hash) => Ok(*hash),
            None => match self.sources.get(&label) {
                Some(source) => self.export_routine_symbol(label, source.clone(), render_stack),
                None => Err(format!("couldn't resolve '{}' to hash", label)),
                Some(source) => self
                    .export_routine_symbol(label.clone(), source.clone(), render_stack)
                    .map_err(|e| format!("couldn't export '{label}': {e}")),
                None => Err(format!("couldn't resolve '{label}' to hash")),
            },
        }
    }


@@ 177,7 179,7 @@ impl Context {
            Some(symbol) => Ok(symbol.clone()),
            None => Err(format!(
                "no routine symbol found for hash '{:?}'",
                hash_to_b64(&hash)
                hash_to_b64(hash)
            )),
        }
    }


@@ 188,14 190,15 @@ impl Context {
        render_stack: &mut RenderStack,
    ) -> Result<Hash, String> {
        match self.hashes.get(label) {
            Some(hash) => Ok(hash.clone()),
            Some(hash) => Ok(*hash),
            None => match self.sources.get(label) {
                Some(source) => {
                    let hash =
                        self.export_macro_symbol(label.clone(), source.clone(), render_stack)?;
                    let hash = self
                        .export_macro_symbol(label.clone(), source.clone(), render_stack)
                        .map_err(|e| format!("couldn't export macro '{label}: {e}"))?;
                    Ok(hash)
                }
                None => return Err(format!("couldn't resolve '{}' to hash", label)),
                None => Err(format!("couldn't resolve '{label}' to hash")),
            },
        }
    }


@@ 351,7 354,7 @@ impl Context {
        render_stack: &mut RenderStack,
    ) -> Result<Hash, String> {
        if let Some(hash) = self.hashes.get(&name) {
            return Ok(hash.clone());
            return Ok(*hash);
        }

        // wrap the conversion with render stack guards for infinite recursion


@@ 375,7 378,7 @@ impl Context {
        render_stack: &mut RenderStack,
    ) -> Result<Hash, String> {
        if let Some(hash) = self.hashes.get(&name) {
            return Ok(hash.clone());
            return Ok(*hash);
        }

        // wrap the conversion with render stack guards for infinite recursion

M src/parsing/byteco.rs => src/parsing/byteco.rs +20 -17
@@ 104,10 104,11 @@ fn parse_routine(
    tokens: &mut Peekable<IntoIter<TextToken>>,
    byteco: &mut ByteCo,
) -> Result<(), String> {
    match tokens.next() {
        Some(TextToken::StringLiteral(n)) => push_name(n, Instruction::RoutineDef, byteco)?,
    let name = match tokens.next() {
        Some(TextToken::StringLiteral(n)) => n,
        _ => return Err(format!("Routine must start with name")),
    }
    };
    push_name(&name, Instruction::RoutineDef, byteco)?;

    while let Some(token) = tokens.next() {
        match token {


@@ 127,10 128,11 @@ fn parse_routine(
                    Marker::DefineAnchor => Instruction::AnchorDef,
                    Marker::AnchorAddressRelative => Instruction::AnchorAddrRel,
                    Marker::Parameter => Instruction::ParameterPass,

                    Marker::PaddingAbsolute | Marker::AnchorAddressAbsolute => {
                        return Err(format!("Invalid routine command"));
                    }
                    Marker::PaddingAbsolute => Instruction::PaddingAbs,
                    Marker::AnchorAddressAbsolute => Instruction::AnchorAddrAbs,
                    // Marker::PaddingAbsolute | Marker::AnchorAddressAbsolute => {
                    //     return Err(format!("Invalid routine command"));
                    // }
                };
                push_command(instruction, label, byteco)?
            }


@@ 142,10 144,10 @@ fn parse_routine(
            TextToken::Tab(count) => push_indent(count, byteco),

            // invalid tokens
            TextToken::Rune(rune) => return Err(format!("Invalid '{}' in routine", rune)),
            TextToken::StringLiteral(s) => return Err(format!("Invalid string {} in routine", s)),
            TextToken::Path(p) => return Err(format!("Invalid path '{}' in routine", p)),
            TextToken::Import(i) => return Err(format!("Invalid import '{}' in routine", i)),
            TextToken::Rune(rune) => return Err(format!("Invalid '{rune}' in ': {name}'")),
            TextToken::StringLiteral(s) => return Err(format!("Invalid str '{s}' in ': {name}'")),
            TextToken::Path(p) => return Err(format!("Invalid path '{p}' in ': {name}'")),
            TextToken::Import(i) => return Err(format!("Invalid import '{i}' in ': {name}'")),
        }
    }



@@ 156,10 158,11 @@ fn parse_macro(
    tokens: &mut Peekable<IntoIter<TextToken>>,
    byteco: &mut ByteCo,
) -> Result<(), String> {
    match tokens.next() {
        Some(TextToken::StringLiteral(n)) => push_name(n, Instruction::MacroDef, byteco)?,
    let name = match tokens.next() {
        Some(TextToken::StringLiteral(n)) => n,
        _ => return Err(format!("Macro must start with name")),
    }
    };
    push_name(&name, Instruction::MacroDef, byteco)?;

    let mut params = Vec::new();
    if matches!(tokens.peek(), Some(TextToken::Rune(Rune::OpenParameters))) {


@@ 240,7 243,7 @@ fn push_label(label: Label, byteco: &mut ByteCo) -> Result<(), String> {
    Ok(())
}

fn push_name(name: String, instruction: Instruction, byteco: &mut ByteCo) -> Result<(), String> {
fn push_name(name: &String, instruction: Instruction, byteco: &mut ByteCo) -> Result<(), String> {
    byteco.push(instruction.into());
    push_string(&name, byteco)
}


@@ 810,7 813,7 @@ pub(crate) fn stream_to_rom(

                // anchors and padding
                Instruction::PaddingAbs => {
                    let position = stream.read_u16()?;
                    let position = slice_stream_from(slice).read_u16()?;
                    if position as usize >= output.len() {
                        let dist = position as usize - output.len();
                        let pad = vec![0; dist.into()];


@@ 822,7 825,7 @@ pub(crate) fn stream_to_rom(
                    Ok(Status::More)
                }
                Instruction::PaddingRel => {
                    let len = stream.read_u16()?;
                    let len = slice_stream_from(slice).read_u16()?;
                    let pad = vec![0; len.into()];
                    output.extend_from_slice(&pad);
                    Ok(Status::More)

M src/parsing/bytecostream.rs => src/parsing/bytecostream.rs +3 -0
@@ 195,6 195,9 @@ impl<'a> ByteCoStream<'a> {
            Instruction::IntLit => 5,
            Instruction::LongLit => 9,

            // ins + 2B num
            Instruction::PaddingAbs | Instruction::PaddingRel => 3,

            // invalid
            Instruction::UndefinedOperation => return None,