docs: Improve documentation comments somewhat
This commit is contained in:
parent
82420f0665
commit
f79d7716c5
@ -15,6 +15,7 @@ use super::{
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Produced by [Parser](crate::parser::Parser::parse<T>())
|
/// Produced by [Parser](crate::parser::Parser::parse<T>())
|
||||||
ParseError(parser::root::Root, Box<dyn std::error::Error + 'static>),
|
ParseError(parser::root::Root, Box<dyn std::error::Error + 'static>),
|
||||||
|
/// Any other error, tagged with [Context]. Created by [`Error::context()`]
|
||||||
Contextual(Context, Box<Self>),
|
Contextual(Context, Box<Self>),
|
||||||
/// Produced by [Token] when the input is entirely unexpected.
|
/// Produced by [Token] when the input is entirely unexpected.
|
||||||
UnexpectedSymbol(String),
|
UnexpectedSymbol(String),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! Convenience trait for dealing with hashable data
|
//! Convenience functions and traits for dealing with hashable data
|
||||||
pub type Hash = u64;
|
pub type Hash = u64;
|
||||||
pub trait FromHash: From<Hash> {
|
pub trait FromHash: From<Hash> {
|
||||||
/// Hashes anything that implements [type@Hash] using the [DefaultHasher](std::collections::hash_map::DefaultHasher)
|
/// Hashes anything that implements [type@Hash] using the [DefaultHasher](std::collections::hash_map::DefaultHasher)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! Iterates over &[str], producing [Token]s
|
//! Iterates over [`&str`](str), producing [`Token`s](Token)
|
||||||
|
|
||||||
// Things we need:
|
// Things we need:
|
||||||
// ✔ 1. Lexer/Tokenizer
|
// ✔ 1. Lexer/Tokenizer
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
//! Stores contextual information about the current tokenizer state, useful for printing errors
|
// © 2023 John Breaux
|
||||||
|
//! A [Context] stores contextual information about the current tokenizer state
|
||||||
|
//!
|
||||||
|
//! This data is trivially copyable and can be provided in error messages using the
|
||||||
|
//! [Error::Contextual] specialization)
|
||||||
use super::*;
|
use super::*;
|
||||||
/// Stores contextual information about the current tokenizer state, useful for printing errors
|
/// Stores contextual information about the current tokenizer state, useful for printing errors
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// © 2023 John Breaux
|
||||||
|
//! Removes a single [kind](Type) of [`Token`] from a [`TokenStream`]
|
||||||
use super::*;
|
use super::*;
|
||||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
@ -11,8 +13,9 @@ where T: TokenStream<'t>
|
|||||||
impl<'t, T> Ignore<'t, T>
|
impl<'t, T> Ignore<'t, T>
|
||||||
where T: TokenStream<'t>
|
where T: TokenStream<'t>
|
||||||
{
|
{
|
||||||
/// Creates a new
|
/// Creates a new [Ignore], which ignores the [ignore Type](Type)
|
||||||
pub fn new(ignore: Type, t: &'t mut T) -> Self { Ignore { ignore, inner: t } }
|
pub fn new(ignore: Type, t: &'t mut T) -> Self { Ignore { ignore, inner: t } }
|
||||||
|
|
||||||
/// Gets a mutable reference to the inner [Iterator]
|
/// Gets a mutable reference to the inner [Iterator]
|
||||||
pub fn inner_mut(&mut self) -> &mut T { self.inner }
|
pub fn inner_mut(&mut self) -> &mut T { self.inner }
|
||||||
}
|
}
|
||||||
@ -21,7 +24,6 @@ impl<'t, T> Iterator for Ignore<'t, T>
|
|||||||
where T: TokenStream<'t>
|
where T: TokenStream<'t>
|
||||||
{
|
{
|
||||||
type Item = Token<'t>;
|
type Item = Token<'t>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let next = self.inner.next()?;
|
let next = self.inner.next()?;
|
||||||
// Space tokens are greedy, so the next token shouldn't be a Space
|
// Space tokens are greedy, so the next token shouldn't be a Space
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// © 2023 John Breaux
|
||||||
|
//! A TokenStream is a specialized [Iterator] which produces [Tokens](Token)
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use super::ignore::Ignore;
|
use super::ignore::Ignore;
|
||||||
|
56
src/lib.rs
56
src/lib.rs
@ -1,23 +1,73 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! A bare-bones toy assembler for the TI MSP430, for use in MicroCorruption
|
//! A bare-bones toy assembler for the TI MSP430, for use in MicroCorruption
|
||||||
|
//!
|
||||||
|
//! This project aims to assemble any valid msp430 instructions, while being lenient about the
|
||||||
|
//! syntax. After all, a real-world parser is going to face all kinds of malformed input, and it
|
||||||
|
//! would be nice to support that kind of input (or, if it's completely unsalvageable, provide a
|
||||||
|
//! useful message to the author.)
|
||||||
|
//!
|
||||||
|
//! The [`Parser`](preamble::Parser) will ignore whitespace, excluding newlines,
|
||||||
|
//! unless syntactically relevant. It will also discard comma-separators between operands of a
|
||||||
|
//! two-operand instruction.
|
||||||
|
//!
|
||||||
|
//! It returns an AST structured as follows
|
||||||
|
//! ```text
|
||||||
|
//! Root
|
||||||
|
//! ├─ Line
|
||||||
|
//! │ └─ Empty
|
||||||
|
//! ├─ Line
|
||||||
|
//! │ └─ Comment
|
||||||
|
//! ├─ Line
|
||||||
|
//! │ └─ Directive // Pre- or Post-processor directive
|
||||||
|
//! ├─ Linel
|
||||||
|
//! │ └─ Label // Label definition
|
||||||
|
//! ├─ Line
|
||||||
|
//! │ └─ Instruction
|
||||||
|
//! │ ├─ Opcode
|
||||||
|
//! │ └─ Encoding::Single
|
||||||
|
//! │ ├─ Width
|
||||||
|
//! │ └─ PrimaryOperand
|
||||||
|
//! │ ├─ Register // Direct, indexed, indirect or indirect-post-increment register.
|
||||||
|
//! │ └─ Number // Index, absolute address or immediate value.
|
||||||
|
//! ├─ Line
|
||||||
|
//! │ └─ Instruction
|
||||||
|
//! │ ├─ Opcode
|
||||||
|
//! │ └─ Encoding::Double
|
||||||
|
//! │ ├─ Width
|
||||||
|
//! │ ├─ PrimaryOperand
|
||||||
|
//! │ │ ├─ Register // Direct, indexed, indirect or indirect-post-increment register.
|
||||||
|
//! │ │ └─ Number // Index, absolute address or immediate value.
|
||||||
|
//! │ └─ SecondaryOperand
|
||||||
|
//! │ ├─ Register // Direct or indexed register
|
||||||
|
//! │ └─ Number // Index or absolute address
|
||||||
|
//! ├─ Line
|
||||||
|
//! │ └─ Instruction
|
||||||
|
//! │ ├─ Opcode
|
||||||
|
//! │ └─ Encoding::Jump
|
||||||
|
//! │ └─ JumpTarget
|
||||||
|
//! │ └─ Number // Even, PC-relative offset in range (-1024..=1022)
|
||||||
|
//! └─ Line
|
||||||
|
//! └─ EndOfFile
|
||||||
|
//! ```
|
||||||
|
|
||||||
pub mod preamble {
|
pub mod preamble {
|
||||||
//! Common imports for msp430-asm
|
//! Common imports for msp430-asm
|
||||||
use super::*;
|
use super::*;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use hash::{FromHash, Hash};
|
pub use hash::{FromHash, Hash};
|
||||||
pub use linker::{Linker, Visitor};
|
|
||||||
pub use parser::Parser;
|
|
||||||
pub use lexer::{
|
pub use lexer::{
|
||||||
context::Context,
|
context::Context,
|
||||||
token::{Token, Type},
|
token::{Token, Type},
|
||||||
token_stream::TokenStream,
|
token_stream::TokenStream,
|
||||||
Tokenizer,
|
Tokenizer,
|
||||||
};
|
};
|
||||||
|
pub use linker::{Linker, Visitor};
|
||||||
|
pub use parser::Parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
use preamble::*;
|
use preamble::*;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod hash;
|
pub mod hash;
|
||||||
|
pub mod lexer;
|
||||||
pub mod linker;
|
pub mod linker;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod lexer;
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! Parses [Tokens](crate::Token) into an [abstract syntax tree](Root)
|
//! Parses [`Tokens`](crate::Token) into an [abstract syntax tree](Root)
|
||||||
|
|
||||||
use crate::{Error, Hash, TokenStream, Type};
|
use crate::{Error, Hash, TokenStream, Type};
|
||||||
use std::fmt::{Debug, Display, LowerHex};
|
use std::fmt::{Debug, Display, LowerHex};
|
||||||
@ -37,13 +37,22 @@ pub mod label;
|
|||||||
|
|
||||||
pub mod line {
|
pub mod line {
|
||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
|
//! [`Line`] contains a single subcomponent of the document. Multiple instructions on the same document line will be treated as if they took up multiple [`Line`s](Line).
|
||||||
|
//!
|
||||||
|
//! A line contains one of:
|
||||||
|
//! - [`Label`]
|
||||||
|
//! - [`Instruction`]
|
||||||
|
//! - [`Directive`]
|
||||||
|
//! - [`Comment`]
|
||||||
|
//! - [Nothing](Line::Empty)
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// A line is one of:
|
/// A line contains any one of:
|
||||||
/// - [`Label`] (definition)
|
/// - [`Label`] (definition)
|
||||||
/// - [`Instruction`]
|
/// - [`Instruction`]
|
||||||
/// - [`Directive`]
|
/// - [`Directive`]
|
||||||
/// - [`Comment`]
|
/// - [`Comment`]
|
||||||
|
/// - Nothing at all
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub enum Line {
|
pub enum Line {
|
||||||
Empty,
|
Empty,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! A [Comment] stores the contents of a line comment, including the preceding `;` or `//`
|
//! A [`Comment`] stores the contents of a line comment, including the preceding `;` or `//`
|
||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Comment(pub String);
|
pub struct Comment(pub String);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! A [Directive] issues commands directly to the [Tokenizer](crate::Tokenizer) and
|
//! A [`Directive`] issues commands directly to the [`Tokenizer`](crate::Tokenizer) and
|
||||||
//! [Linker](crate::Linker)
|
//! [Linker](crate::Linker)
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::hash::FromHash;
|
use crate::hash::FromHash;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! An [Identifier] stores the hash of a named identifier
|
//! An [Identifier] stores the name of an identifier
|
||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub enum Identifier {
|
pub enum Identifier {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! An [Instruction] contains the [Opcode] and [Encoding] information for a single msp430
|
//! An [`Instruction`] contains the [`Opcode`] and [`Encoding`] information for a single msp430
|
||||||
//! instruction
|
//! instruction
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! Note: [Opcode] and [Encoding] are very tightly coupled, because they represent interdependent
|
//! Note: [`Opcode`] and [`Encoding`] are very tightly coupled, because they represent
|
||||||
//! parts of the same instruction. This is why [Opcode]::resolve() returns an [EncodingParser] --
|
//! interdependent parts of the same instruction. This is why [`Opcode`]::resolve() returns an
|
||||||
//! otherwise, there's an explosion of states that I can't really cope with on my own. Really,
|
//! [`EncodingParser`] -- otherwise, there's an explosion of states that I can't really cope with on
|
||||||
//! there's about 9 valid classes of instruction, some of which are only used for one or two of the
|
//! my own. Really, there's about 9 valid classes of instruction, some of which are only used for
|
||||||
//! MSP430's instructions.
|
//! one or two of the MSP430's instructions.
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! An [Encoding] represents the set of arguments for the [msp430's instructions](Opcode)
|
//! An [`Encoding`] represents the set of arguments for a given [msp430 opcode](Opcode)
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub mod number;
|
pub mod number;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! Builder API for [EncodingParser]
|
//! Builder API for [`EncodingParser`]
|
||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct SingleBuilder {
|
pub struct SingleBuilder {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! An [EncodingParser] builds an [Encoding] from a [TokenStream]
|
//! An [`EncodingParser`] builds an [`Encoding`] from a [`TokenStream`]
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! A [JumpTarget] contains the [pc-relative offset](Number) or [label](Identifier)
|
//! A [`JumpTarget`] contains the [pc-relative offset](Number) or [label](Identifier)
|
||||||
//! for a [Jump](Encoding::Jump) [instruction]
|
//! for a [Jump](Encoding::Jump) [instruction]
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! A [Number] represents a 16-bit signed or unsigned word
|
//! A [`Number`] represents a 16-bit signed or unsigned word
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// TODO: Allow identifiers/expressions in place of numbers
|
// TODO: Allow identifiers/expressions in place of numbers
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! A [PrimaryOperand] contains the first [Register], addressing mode, and Extension
|
//! A [`PrimaryOperand`] contains the first [`Register`], addressing mode, and Extension
|
||||||
//! Word for a [one-operand](Encoding::Single) or [two-operand](Encoding::Double) [Instruction]
|
//! Word for a [one-operand](Encoding::Single) or [two-operand](Encoding::Double) [`Instruction`]
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Contains the first [Register], addressing mode, and Extension Word for a
|
/// Contains the first [Register], addressing mode, and Extension Word for a
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! A [Register] epresents [one of the MSP430 processor's registers](https://mspgcc.sourceforge.net/manual/x82.html)
|
//! A [`Register`] represents [one of the MSP430 processor's registers](https://mspgcc.sourceforge.net/manual/x82.html)
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! A [SecondaryOperand] contains the second [Register], addressing mode, and Extension
|
//! A [`SecondaryOperand`] contains the second [`Register`], addressing mode, and Extension
|
||||||
//! Word for a [two-operand](Encoding::Double) [instruction]
|
//! Word for a [two-operand](Encoding::Double) [instruction]
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! A [Width] represents whether an instruction operates on whole words or bytes
|
//! A [`Width`] represents whether an instruction operates on whole words or bytes
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Represents an instruction's operand width.
|
/// Represents an instruction's operand width.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
//! An [Opcode] encodes an msp430 operation
|
//! An [`Opcode`] encodes an msp430 operation
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
|
//! The definition of a label
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
/// The definition of a label
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Label(pub Identifier);
|
pub struct Label(pub Identifier);
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// © 2023 John Breaux
|
// © 2023 John Breaux
|
||||||
|
//! A [`Parsable`] struct (an AST node) can parse tokens from a [stream](TokenStream) into it[`self`](https://doc.rust-lang.org/stable/std/keyword.SelfTy.html)
|
||||||
use super::*;
|
use super::*;
|
||||||
/// Parses tokens from [stream](TokenStream) into Self node
|
/// Parses tokens from [stream](TokenStream) into Self node
|
||||||
pub trait Parsable {
|
pub trait Parsable {
|
||||||
|
Loading…
Reference in New Issue
Block a user