Skip to content

Commit

Permalink
Deduplicate instruction compilation code
Browse files Browse the repository at this point in the history
  • Loading branch information
Granddave committed Dec 21, 2023
1 parent ff96d7a commit f095e10
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 40 deletions.
19 changes: 12 additions & 7 deletions src/assembler/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use self::opcode::OPCODE_MAPPING;
use self::symbol_resolver::{SymbolTable, SymbolType};
use crate::ast::{ASTAddressingMode, ASTInstructionNode, ASTNode, ASTOperand, AST};

Expand Down Expand Up @@ -139,27 +138,33 @@ impl Compiler {

/// Compile a single instruction node from the AST to machine code.
#[tracing::instrument]
fn compile_instruction(&mut self, ins: &ASTInstructionNode) -> Vec<u8> {
let mut bytes: Vec<u8> = Vec::new();
pub fn instruction_to_bytes(ins: &ASTInstructionNode) -> Vec<u8> {
let mut bytes = vec![];

bytes.push(
OPCODE_MAPPING
crate::assembler::compiler::opcode::OPCODE_MAPPING
.find_opcode(ins.ins)
.unwrap_or_else(|| panic!("Invalid instruction for opcode: {:#?}", ins)),
.unwrap_or_else(|| panic!("Invalid opcode: '{:#04x}'", ins.ins.mnemonic as u8)),
);

bytes.extend(match ins.operand {
ASTOperand::Immediate(value) => vec![value],
ASTOperand::Absolute(address) => vec![address as u8, (address >> 8) as u8],
ASTOperand::ZeroPage(address) => vec![address],
ASTOperand::Relative(offset) => vec![offset as u8],
ASTOperand::Implied => vec![],
ASTOperand::Label(_) => panic!("Label should have been resolved to a relative offset"),
ASTOperand::Constant(_) => panic!("Constant should have been resolved to its value"),
ASTOperand::Implied => vec![],
});

self.current_address += ins.size() as u16;
bytes
}

/// Compile a instruction to machine code and increment address.
#[tracing::instrument]
fn compile_instruction(&mut self, ins: &ASTInstructionNode) -> Vec<u8> {
let bytes: Vec<u8> = Compiler::instruction_to_bytes(ins);
self.current_address += ins.size() as u16;
bytes
}

Expand Down
28 changes: 2 additions & 26 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ pub enum ASTAddressingMode {
AbsoluteX,
/// `a,y`
AbsoluteY,
/// `r` for branch instructions. [`ASTOperand::Label`][self::ASTOperand#variant.Label] is resolved to relative offsets
/// `r` for branch instructions.
/// [`ASTOperand::Label`][self::ASTOperand#variant.Label] is resolved to relative offsets
Relative,
/// `(a)`
Indirect,
Expand Down Expand Up @@ -238,31 +239,6 @@ impl ASTInstructionNode {
ASTOperand::Implied => 1,
}
}

// TODO: Merge with the implementation in the compiler module
pub fn bytes(&self) -> Vec<u8> {
let mut bytes = vec![];

bytes.push(
crate::assembler::compiler::opcode::OPCODE_MAPPING
.find_opcode(self.ins)
.unwrap_or_else(|| panic!("Invalid opcode: '{:#04x}'", self.ins.mnemonic as u8)),
);

match self.operand {
ASTOperand::Immediate(value) => bytes.push(value),
ASTOperand::Absolute(address) => {
bytes.push((address & 0xFF) as u8);
bytes.push((address >> 8) as u8);
}
ASTOperand::ZeroPage(address) => bytes.push(address),
ASTOperand::Relative(offset) => bytes.push(offset as u8),
ASTOperand::Implied => {}
_ => panic!("Cannot calculate bytes for: {:#?}", self),
}

bytes
}
}

impl fmt::Display for ASTInstructionNode {
Expand Down
14 changes: 7 additions & 7 deletions src/disassembler/listing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::ast::{ASTInstructionNode, ASTNode};
use crate::{
assembler::compiler::Compiler,
ast::{ASTInstructionNode, ASTNode},
};

#[derive(Debug)]
pub struct Listing {
Expand All @@ -23,17 +26,14 @@ impl Listing {
}

#[tracing::instrument]
fn generate_line(&self, node: &ASTInstructionNode) -> String {
let bytes = node.bytes();
fn generate_line(&self, ins: &ASTInstructionNode) -> String {
let bytes = Compiler::instruction_to_bytes(ins);
let bytes_str = bytes
.iter()
.map(|b| format!("{:02X}", b))
.collect::<Vec<String>>()
.join(" ");
format!(
"${:04X} {:08} {}\n",
self.current_address, bytes_str, node
)
format!("${:04X} {:08} {}\n", self.current_address, bytes_str, ins)
}

#[tracing::instrument]
Expand Down

0 comments on commit f095e10

Please sign in to comment.