assembler: refactor error handling and use ModuleId::new constructor
This commit is contained in:
@@ -6,6 +6,7 @@ use std::path::Path;
|
||||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
|
||||
use crate::error::{AssembleErrorKind, IoErrorKind};
|
||||
use crate::{
|
||||
context::AssemblerContext,
|
||||
error::AssembleError,
|
||||
@@ -176,8 +177,8 @@ impl CompilerEngine {
|
||||
// Verify file exists
|
||||
if !path.exists() {
|
||||
return Err(EngineError::Assembly(AssembleError::new_other_error(
|
||||
crate::error::AssembleErrorKind::Io(crate::error::IoError::new(
|
||||
crate::error::IoErrorKind::NotFound,
|
||||
AssembleErrorKind::Io(crate::error::IoError::new(
|
||||
IoErrorKind::NotFound,
|
||||
Some(format!("Source file not found: {}", path.display())),
|
||||
)),
|
||||
)));
|
||||
@@ -218,12 +219,12 @@ impl Default for CompilerEngine {
|
||||
fn assemble(src: &Path) -> Result<Vec<Instruction>, AssembleError> {
|
||||
// Verify the file exists
|
||||
if !src.exists() {
|
||||
return Err(AssembleError::new_other_error(
|
||||
crate::error::AssembleErrorKind::Io(crate::error::IoError::new(
|
||||
crate::error::IoErrorKind::NotFound,
|
||||
return Err(AssembleError::new_other_error(AssembleErrorKind::Io(
|
||||
crate::error::IoError::new(
|
||||
IoErrorKind::NotFound,
|
||||
Some(format!("Source file not found: {}", src.display())),
|
||||
)),
|
||||
));
|
||||
),
|
||||
)));
|
||||
}
|
||||
|
||||
let mut modules = HashSet::new();
|
||||
@@ -267,12 +268,10 @@ fn prepare_dependency(
|
||||
context: &AssemblerContext,
|
||||
) -> Result<(), AssembleError> {
|
||||
let filename = path.file_name().and_then(|n| n.to_str()).ok_or_else(|| {
|
||||
AssembleError::new_other_error(crate::error::AssembleErrorKind::Io(
|
||||
crate::error::IoError::new(
|
||||
crate::error::IoErrorKind::InvalidData,
|
||||
AssembleError::new_other_error(AssembleErrorKind::Io(crate::error::IoError::new(
|
||||
IoErrorKind::InvalidData,
|
||||
Some("Failed to get file name from path".to_string()),
|
||||
),
|
||||
))
|
||||
)))
|
||||
})?;
|
||||
|
||||
// Calculate a simple hash for the file (similar to quick_hash)
|
||||
@@ -290,8 +289,8 @@ fn prepare_dependency(
|
||||
|
||||
// Phase 1: Tokenize the file
|
||||
println!("Tokenising {filename}");
|
||||
let tokeniser = Tokeniser::new(path)?;
|
||||
let tokens = tokeniser.tokenise(context)?;
|
||||
let tokeniser = Tokeniser::new(path, context)?;
|
||||
let tokens = tokeniser.tokenise()?;
|
||||
|
||||
// Get the module ID that was registered during tokenization
|
||||
let module_id = get_module_id_for_file(path, context)?;
|
||||
@@ -328,7 +327,7 @@ fn get_module_id_for_file(
|
||||
{
|
||||
let registry = context.module_registry.read()?;
|
||||
|
||||
// Find module by path
|
||||
// Find module by path.
|
||||
for module in registry.modules() {
|
||||
if module.path == file_path {
|
||||
return Ok(module.id);
|
||||
@@ -336,15 +335,15 @@ fn get_module_id_for_file(
|
||||
}
|
||||
}
|
||||
|
||||
Err(AssembleError::new_other_error(
|
||||
crate::error::AssembleErrorKind::Io(crate::error::IoError::new(
|
||||
crate::error::IoErrorKind::NotFound,
|
||||
Err(AssembleError::new_other_error(AssembleErrorKind::Io(
|
||||
crate::error::IoError::new(
|
||||
IoErrorKind::NotFound,
|
||||
Some(format!(
|
||||
"Module not found for file: {}",
|
||||
file_path.display()
|
||||
)),
|
||||
)),
|
||||
))
|
||||
),
|
||||
)))
|
||||
}
|
||||
|
||||
/// Result of compilation. This is useless at present but compiles.
|
||||
|
||||
@@ -9,15 +9,24 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use regex::Regex;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::model::module_registry::ModuleRegistry;
|
||||
use crate::{
|
||||
error::{AssembleError, AssembleErrorKind, IoError, IoErrorKind},
|
||||
model::module_registry::ModuleRegistry,
|
||||
};
|
||||
|
||||
/// The ID for a module. A tuple struct for type safety.
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct ModuleId(Uuid);
|
||||
|
||||
impl ModuleId {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self(Uuid::new_v4())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn from_module(module: &Module) -> Self {
|
||||
module.id
|
||||
@@ -36,6 +45,12 @@ impl ModuleId {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ModuleId {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ModuleId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
@@ -61,11 +76,35 @@ impl std::hash::Hash for Module {
|
||||
}
|
||||
|
||||
impl Module {
|
||||
pub fn new<P: AsRef<Path>>(name: String, path: P) -> Self {
|
||||
Self {
|
||||
name,
|
||||
path: path.as_ref().to_path_buf(),
|
||||
id: ModuleId(Uuid::new_v4()),
|
||||
pub fn new<P: AsRef<Path>>(p: P) -> Result<Self, AssembleError> {
|
||||
let path = p.as_ref().to_path_buf();
|
||||
let name = Self::extract_module_name(&path)?;
|
||||
let id = ModuleId::new();
|
||||
|
||||
Ok(Self { name, path, id })
|
||||
}
|
||||
|
||||
/// Gets the name for a module from the path.
|
||||
fn extract_module_name<P: AsRef<Path>>(path: P) -> Result<String, AssembleError> {
|
||||
let extensions_regex = Regex::new(".(dsa|S|asm)$")
|
||||
.expect("For some reason the regular expression failed to compile!");
|
||||
let module_name = path
|
||||
.as_ref()
|
||||
.file_name()
|
||||
.map(|f| f.to_string_lossy())
|
||||
.ok_or_else(|| {
|
||||
AssembleError::new_other_error(AssembleErrorKind::Io(IoError::new(
|
||||
IoErrorKind::InvalidData,
|
||||
Some(
|
||||
"the filename couldn't be extracted, is it valid UTF-8?"
|
||||
.to_string(),
|
||||
),
|
||||
)))
|
||||
})?;
|
||||
|
||||
// Strip any file extensions given. We don't care for now.
|
||||
let out = extensions_regex.replace(&module_name, "");
|
||||
|
||||
Ok(out.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user