Skip to content

Commit

Permalink
asm: Improve the assembler errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Granddave committed Jan 1, 2024
1 parent fbfd1db commit 4b58283
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 12 deletions.
18 changes: 13 additions & 5 deletions src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,23 @@ pub mod parser;
/// Generates machine code from an AST.
pub mod compiler;

/// Utility functions for generating machine code.
///
/// TODO: Pass in a target address.
#[derive(Debug, thiserror::Error)]
pub enum AssemblerError {
#[error("Parser error: {0}")]
Parse(#[from] parser::ParseError),
#[error("Compiler error: {0}")]
Compile(#[from] compiler::CompilerError),
}

/// Utility function for generating machine code from an assembly program.
#[tracing::instrument]
pub fn compile_code(input: &str, program_start: u16) -> anyhow::Result<Vec<u8>> {
pub fn compile_code(input: &str, program_start: u16) -> Result<Vec<u8>, AssemblerError> {
let mut lexer = lexer::Lexer::new(input);
let mut parser = parser::Parser::new(&mut lexer)?;
let ast = parser.parse_program()?;

let mut compiler = compiler::Compiler::new(program_start);
let program = compiler.compile(ast)?;

Ok(compiler.compile(ast)?)
Ok(program)
}
6 changes: 3 additions & 3 deletions src/assembler/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use self::token::{Token, TokenType};
pub mod token;

#[derive(Error, Debug)]
pub enum LexingError {
pub enum LexerError {
#[error("Unexpected character on line {0}: '{1}'")]
UnexpectedCharacter(usize, char),
}
Expand Down Expand Up @@ -116,7 +116,7 @@ impl<'a> Lexer<'a> {
}

#[tracing::instrument]
pub fn next_token(&mut self) -> Result<Option<Token>, LexingError> {
pub fn next_token(&mut self) -> Result<Option<Token>, LexerError> {
self.skip_whitespace();
let token = match self.ch {
Some(ch) => match ch {
Expand Down Expand Up @@ -167,7 +167,7 @@ impl<'a> Lexer<'a> {
}
}
_ => {
return Err(LexingError::UnexpectedCharacter(self.line_number, ch));
return Err(LexerError::UnexpectedCharacter(self.line_number, ch));
}
},
None => Some(self.create_token(TokenType::Eof, "")),
Expand Down
15 changes: 11 additions & 4 deletions src/assembler/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::VecDeque, str::FromStr};
use thiserror::Error;

use crate::{
assembler::lexer::{token::Token, token::TokenType, Lexer, LexingError},
assembler::lexer::{token::Token, token::TokenType, Lexer, LexerError},
ast::{
ASTAddressingMode, ASTConstantNode, ASTInstructionNode, ASTMnemonic, ASTNode, ASTOperand,
AST,
Expand All @@ -15,15 +15,17 @@ pub enum ParseError {
#[error("Invalid token - {0}:\n{1:#?}")]
InvalidToken(String, Token),
#[error(transparent)]
LexingError(#[from] LexingError),
LexingError(#[from] LexerError),
}

// ParseError helpers.
// Takes a reference to a `Parser` and a format string with optional arguments.
macro_rules! invalid_token {
// No format arguments
($parser:ident, $fmt:expr) => {
ParseError::InvalidToken(format!($fmt), $parser.current_token.clone())
};
// With format arguments
($parser:ident, $fmt:expr, $($arg:tt)+) => {
ParseError::InvalidToken(format!($fmt, $($arg)+), $parser.current_token.clone())
};
Expand Down Expand Up @@ -113,8 +115,13 @@ impl<'a> Parser<'a> {

#[tracing::instrument]
fn parse_mnemonic(&mut self) -> Result<ASTMnemonic, ParseError> {
ASTMnemonic::from_str(self.current_token.literal.to_uppercase().as_str())
.map_err(|err| invalid_token!(self, "invalid mnemonic: {}", err))
ASTMnemonic::from_str(self.current_token.literal.to_uppercase().as_str()).map_err(|_| {
invalid_token!(
self,
"Invalid instruction mnemonic '{}'",
self.current_token.literal
)
})
}

#[tracing::instrument]
Expand Down

0 comments on commit 4b58283

Please sign in to comment.