docs: Improve and update documentation

This commit is contained in:
John 2023-10-23 21:01:32 -05:00
parent c43ecf00d1
commit 8b1a1534f3
4 changed files with 64 additions and 14 deletions

View File

@ -285,7 +285,7 @@ pub struct Start(pub expression::Expr);
/// An Identifier stores the name of an item /// An Identifier stores the name of an item
/// # Syntax /// # Syntax
/// [`Identifier`] := [`IDENTIFIER`](crate::token::Type::Identifier) /// [`Identifier`] := [`IDENTIFIER`](crate::token::token_type::Type::Identifier)
#[derive(Clone, Debug, Hash)] #[derive(Clone, Debug, Hash)]
pub struct Identifier(pub String); pub struct Identifier(pub String);
@ -354,31 +354,31 @@ pub mod literal {
pub enum Literal { pub enum Literal {
/// Represents a literal string value /// Represents a literal string value
/// # Syntax /// # Syntax
/// [`Literal::String`] := [`STRING`](crate::token::Type::String) /// [`Literal::String`] := [`STRING`](crate::token::token_type::Type::String)
String(String), String(String),
/// Represents a literal [char] value /// Represents a literal [char] value
/// # Syntax /// # Syntax
/// [`Literal::Char`] := [`CHARACTER`](crate::token::Type::Character) /// [`Literal::Char`] := [`CHARACTER`](crate::token::token_type::Type::Character)
Char(char), Char(char),
/// Represents a literal [bool] value /// Represents a literal [bool] value
/// # Syntax /// # Syntax
/// [`Literal::Bool`] := /// [`Literal::Bool`] :=
/// [`TRUE`](crate::token::Keyword::True) /// [`TRUE`](crate::token::token_type::Keyword::True)
/// | [`FALSE`](crate::token::Keyword::False) /// | [`FALSE`](crate::token::token_type::Keyword::False)
Bool(bool), Bool(bool),
/// Represents a literal float value /// Represents a literal float value
/// # Syntax /// # Syntax
/// [`Float`] := [`FLOAT`](crate::token::Type::Float) /// [`Float`] := [`FLOAT`](crate::token::token_type::Type::Float)
Float(Float), Float(Float),
/// Represents a literal integer value /// Represents a literal integer value
/// # Syntax /// # Syntax
/// [`u128`] := [`INTEGER`](crate::token::Type::Integer) /// [`u128`] := [`INTEGER`](crate::token::token_type::Type::Integer)
Int(u128), Int(u128),
} }
/// Represents a literal float value /// Represents a literal float value
/// # Syntax /// # Syntax
/// [`Float`] := [`FLOAT`](crate::token::Type::Float) /// [`Float`] := [`FLOAT`](crate::token::token_type::Type::Float)
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Float { pub struct Float {
pub sign: bool, pub sign: bool,

View File

@ -1,5 +1,5 @@
//! Converts a text file into tokens //! Converts a text file into tokens
use crate::token::{Keyword, Token, TokenData, Type}; use crate::token::preamble::*;
use std::{ use std::{
iter::Peekable, iter::Peekable,
str::{Chars, FromStr}, str::{Chars, FromStr},
@ -7,12 +7,13 @@ use std::{
use unicode_xid::UnicodeXID; use unicode_xid::UnicodeXID;
pub mod lexer_iter { pub mod lexer_iter {
//! Iterator over a [`Lexer`], returning [`LResult<Token>`]s
use super::{ use super::{
error::{LResult, Reason}, error::{LResult, Reason},
Lexer, Token, Lexer, Token,
}; };
/// Fallible iterator over a [Lexer], returning optional [LResult<Token>]s /// Iterator over a [`Lexer`], returning [`LResult<Token>`]s
pub struct LexerIter<'t> { pub struct LexerIter<'t> {
lexer: Lexer<'t>, lexer: Lexer<'t>,
} }
@ -40,6 +41,31 @@ pub mod lexer_iter {
} }
} }
/// The Lexer iterates over the characters in a body of text, searching for [Tokens](Token).
///
/// # Examples
/// ```rust
///# use conlang::lexer::Lexer;
/// // Read in your code from somewhere
/// let some_code = "
/// fn main () {
/// // TODO: code goes here!
/// }
/// ";
/// // Create a lexer over your code
/// let mut lexer = Lexer::new(some_code);
/// // Scan for a single token
/// let first_token = lexer.scan().unwrap();
/// println!("{first_token:?}");
/// // Loop over all the rest of the tokens
/// for token in lexer {
///# let token: Result<_,()> = Ok(token.unwrap());
/// match token {
/// Ok(token) => println!("{token:?}"),
/// Err(e) => eprintln!("{e:?}"),
/// }
/// }
/// ```
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Lexer<'t> { pub struct Lexer<'t> {
iter: Peekable<Chars<'t>>, iter: Peekable<Chars<'t>>,
@ -50,6 +76,7 @@ pub struct Lexer<'t> {
} }
impl<'t> Lexer<'t> { impl<'t> Lexer<'t> {
/// Creates a new [Lexer] over a [str]
pub fn new(text: &'t str) -> Self { pub fn new(text: &'t str) -> Self {
Self { Self {
iter: text.chars().peekable(), iter: text.chars().peekable(),
@ -59,6 +86,7 @@ impl<'t> Lexer<'t> {
current_loc: (1, 1), current_loc: (1, 1),
} }
} }
/// Scans through the text, searching for the next [Token]
pub fn scan(&mut self) -> LResult<Token> { pub fn scan(&mut self) -> LResult<Token> {
match self.skip_whitespace().peek()? { match self.skip_whitespace().peek()? {
'{' => self.consume()?.produce(Type::LCurly, ()), '{' => self.consume()?.produce(Type::LCurly, ()),
@ -98,11 +126,11 @@ impl<'t> Lexer<'t> {
e => Err(Error::unexpected_char(e, self.line(), self.col())), e => Err(Error::unexpected_char(e, self.line(), self.col())),
} }
} }
/// Gets the line of the next token /// Returns the current line
pub fn line(&self) -> u32 { pub fn line(&self) -> u32 {
self.start_loc.0 self.start_loc.0
} }
/// Gets the column of the next token /// Returns the current column
pub fn col(&self) -> u32 { pub fn col(&self) -> u32 {
self.start_loc.1 self.start_loc.1
} }
@ -403,8 +431,10 @@ impl<'t> Lexer<'t> {
use error::{Error, LResult, Reason}; use error::{Error, LResult, Reason};
pub mod error { pub mod error {
//! [Error] type for the [Lexer](super::Lexer)
use std::fmt::Display; use std::fmt::Display;
/// Result type with [Err] = [Error]
pub type LResult<T> = Result<T, Error>; pub type LResult<T> = Result<T, Error>;
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Error { pub struct Error {
@ -415,14 +445,25 @@ pub mod error {
/// The reason for the [Error] /// The reason for the [Error]
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Reason { pub enum Reason {
/// Found an opening delimiter of type [char], but not the expected closing delimiter
UnmatchedDelimiters(char), UnmatchedDelimiters(char),
/// Found a character that doesn't belong to any [Type](crate::token::token_type::Type)
UnexpectedChar(char), UnexpectedChar(char),
/// Found a character that's not valid in identifiers while looking for an identifier
NotIdentifier(char), NotIdentifier(char),
/// Found a character that's not valid in an escape sequence while looking for an escape
/// sequence
UnknownEscape(char), UnknownEscape(char),
/// Escape sequence contains invalid hexadecimal digit or unmatched braces
InvalidEscape(char), InvalidEscape(char),
/// Character is not a valid digit in the requested base
InvalidDigit(char), InvalidDigit(char),
/// Base conversion requested, but the base character was not in the set of known
/// characters
UnknownBase(char), UnknownBase(char),
/// Unicode escape does not map to a valid unicode code-point
BadUnicode(u32), BadUnicode(u32),
/// Reached end of input
EndOfFile, EndOfFile,
} }
error_impl! { error_impl! {
@ -441,7 +482,11 @@ pub mod error {
pub(super) fn mask_reason(self, reason: Reason) -> Self { pub(super) fn mask_reason(self, reason: Reason) -> Self {
Self { reason, ..self } Self { reason, ..self }
} }
/// Gets the (line, col) where the error happened /// Returns the [Reason] for this error
pub fn reason(&self) -> &Reason {
&self.reason
}
/// Returns the (line, col) where the error happened
pub fn location(&self) -> (u32, u32) { pub fn location(&self) -> (u32, u32) {
(self.line, self.col) (self.line, self.col)
} }

View File

@ -1,10 +1,14 @@
//! A [Printer] pretty-prints a Conlang [syntax tree](crate::ast)
use super::ast::preamble::*; use super::ast::preamble::*;
use std::{ use std::{
fmt::Display, fmt::Display,
io::{stdout, Result as IOResult, StdoutLock, Write}, io::{stdout, Result as IOResult, StdoutLock, Write},
}; };
/// Prettily prints this node
pub trait PrettyPrintable { pub trait PrettyPrintable {
/// Prettily prints this node
fn print(&self); fn print(&self);
/// Prettily writes this node into the given [Writer](Write)
fn write(&self, into: impl Write) -> IOResult<()>; fn write(&self, into: impl Write) -> IOResult<()>;
} }
impl PrettyPrintable for Start { impl PrettyPrintable for Start {
@ -16,6 +20,7 @@ impl PrettyPrintable for Start {
} }
} }
/// Prints a Conlang [syntax tree](crate::ast) into a [Writer](Write)
#[derive(Debug)] #[derive(Debug)]
pub struct Printer<W: Write> { pub struct Printer<W: Write> {
level: u32, level: u32,

View File

@ -17,7 +17,7 @@ use token_data::Data;
use token_type::Type; use token_type::Type;
/// Contains a single unit of lexical information, /// Contains a single unit of lexical information,
/// and an optional bit of [data](TokenData) /// and an optional bit of [Data]
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Token { pub struct Token {
ty: Type, ty: Type,