assembler: great leap forwards (more like the Cultural Revolution)
This commit is contained in:
@@ -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;
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
use crate::error::AssembleError;
|
||||||
|
|
||||||
|
impl From<std::io::Error> for AssembleError {
|
||||||
|
fn from(err: std::io::Error) -> Self {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,11 @@
|
|||||||
pub mod args;
|
pub mod args;
|
||||||
pub mod image_builder;
|
pub mod image_builder;
|
||||||
// pub mod tooling;
|
// pub mod tooling;
|
||||||
|
pub mod error;
|
||||||
|
pub mod model;
|
||||||
|
pub mod source;
|
||||||
|
pub mod symtab;
|
||||||
|
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
//! This module contains the underlying data models and enums used by the Assembler.
|
||||||
|
|
||||||
|
pub mod symbol;
|
||||||
@@ -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,
|
||||||
|
}
|
||||||
@@ -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
|
//! code for more informative errors. This will likely be attached to a [`Token`] which
|
||||||
//! will in turn be attached to an AST [`Node`].
|
//! will in turn be attached to an AST [`Node`].
|
||||||
|
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
/// Information on where the token is within the source.
|
/// Information on where the token is within the source.
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct SourceInfo {
|
pub struct SourceInfo {
|
||||||
/// The line number within the source file underpinned by `module_id`.
|
/// The line number within the source file underpinned by `module_id`.
|
||||||
pub line_no: usize,
|
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,
|
pub module_id: Uuid,
|
||||||
/// The indexes where this token may be found (line-local).
|
/// The indexes where this token may be found (line-local).
|
||||||
pub span: std::ops::Range<usize>,
|
pub span: std::ops::Range<usize>,
|
||||||
@@ -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 {}
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user