assembler: great leap forwards (more like the Cultural Revolution)

This commit is contained in:
2025-06-25 03:26:50 +01:00
parent ce76820b6d
commit 9232f2ccab
10 changed files with 172 additions and 1 deletions
+48
View File
@@ -0,0 +1,48 @@
//! This module contains code for various types of errors that may occur when assembling a
//! set of source DSA files.
use std::fmt::{Debug, Display};
use crate::source::source_info::SourceInfo;
/// An error that may occur during the assembly of a set of source files.
#[derive(Debug)]
pub struct AssembleError {
/// Display implementation can handle when the source code information is shown or
/// not.
source_info: Option<SourceInfo>,
/// The type of assembly error that occurred.
kind: AssembleErrorKind,
/// The formatter to handle printing the error.
formatter: Box<dyn ErrorFormatter>,
}
impl AssembleError {
pub fn new_source_error(source_info: SourceInfo, kind: AssembleErrorKind) -> Self {
Self {
source_info: Some(source_info),
kind,
formatter,
}
}
pub fn new_other_error(kind: AssembleErrorKind) {}
}
impl Display for AssembleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.formatter
.write(f, self.source_info.as_ref(), &self.kind)
}
}
/// Marker trait.
impl std::error::Error for AssembleError {}
/// Different types of errors that may occur when assembling a set of input source files.
#[non_exhaustive]
#[derive(Debug)]
pub enum AssembleErrorKind {}
pub mod conversions;
pub mod formatters;
+7
View File
@@ -0,0 +1,7 @@
use crate::error::AssembleError;
impl From<std::io::Error> for AssembleError {
fn from(err: std::io::Error) -> Self {
}
}
+5
View File
@@ -15,6 +15,11 @@
pub mod args;
pub mod image_builder;
// pub mod tooling;
pub mod error;
pub mod model;
pub mod source;
pub mod symtab;
mod util;
pub mod prelude {
+3
View File
@@ -0,0 +1,3 @@
//! This module contains the underlying data models and enums used by the Assembler.
pub mod symbol;
+69
View File
@@ -0,0 +1,69 @@
//! This module contains the definitions for a Symbol.
use uuid::Uuid;
/// A symbol is a named reference that may be resolved later to an address by a linker.
pub struct Symbol {
/// Stored cheaply instead of the name. Shall be stored in the symbol table under
/// this key.
pub id: Uuid,
pub visibility: Visibility,
pub symbol_type: SymbolType,
/// The id of the module the symbol is defined in.
module_id: Uuid,
/// Whether or not the symbol requires relocating.
pub needs_relocation: bool,
/// A list of the symbol's dependencies.
///
/// e.g.
///
/// ```dsa
/// main:
/// call another_func
///
/// another_func:
/// // Code goes here
/// ret
/// ```
///
/// Where `main` depends on `another_func`.
pub dependencies: Vec<Uuid>,
}
impl Symbol {
pub fn new(
id: Uuid,
visibility: Visibility,
symbol_type: SymbolType,
module_id: Uuid,
) -> Self {
Self {
id,
visibility,
symbol_type,
module_id,
}
}
}
#[derive(Debug, Copy, Clone)]
/// The visibility of the symbol in different object files.
pub enum Visibility {
/// STB_PUBLIC under the ELF spec. Visible in all other object files. Shall be used
/// for labels. Remember labels are namespaced in different files so they won't clash
/// with one another.
Public,
/// Only visible within this object file. STB_LOCAL under ELF spec. Shall be used for
/// data definitions unless they are marked public.
Local,
/// STB_WEAK under the ELF spec. Potentially unused.
Weak,
}
pub enum SymbolType {
Function,
Label,
}
+20
View File
@@ -0,0 +1,20 @@
//! This module contains anything within the first stage of assembly, i.e. the
//! tokenisation stage, or utility functions for reading input files.
use std::path::Path;
use crate::error::AssembleError;
pub mod source_info;
pub mod token;
pub mod tokeniser;
/// Attempts to load and open a source file, returning a [`Vec<u8>`] or an
/// [`AssembleError`].
pub fn load_source_bytes<P: AsRef<Path>>(p: P) -> Result<Vec<u8>, AssembleError> {
let path = p.as_ref();
let bytes = std::fs::read(path)?;
Ok(vec![])
}
@@ -2,11 +2,15 @@
//! code for more informative errors. This will likely be attached to a [`Token`] which
//! will in turn be attached to an AST [`Node`].
use uuid::Uuid;
/// Information on where the token is within the source.
#[derive(Debug)]
pub struct SourceInfo {
/// The line number within the source file underpinned by `module_id`.
pub line_no: usize,
/// The ID of the module containing this token.
/// The ID of the module containing this token. This will be looked up in the global
/// hashmap of [`Module`]'s.
pub module_id: Uuid,
/// The indexes where this token may be found (line-local).
pub span: std::ops::Range<usize>,
+5
View File
@@ -0,0 +1,5 @@
//! This file contains the [`Tokeniser`], which consumes a [`Vec`] of input bytes and
//! outputs a [`Vec<Token>`].
/// Consumes a [`Vec<u8>`] and outputs a [`Vec`] of [Token]'s.
pub struct Tokeniser {}
+10
View File
@@ -0,0 +1,10 @@
//! This module contains the code for the Symbol Table, which can be written into object
//! files to support deferred relocations when using ELF files.
//!
//! It is also required for detection of duplicate symbols, and resolution in the flat
//! binary output type.
/// Stored for each compilation unit (called a [`Module`]).
///
/// One hashmap maps [`Symbol`] ID's to their corresponding structs, and
pub struct SymbolTable