ast: Improve documentation linking

This commit is contained in:
John 2023-10-26 17:56:02 -05:00
parent ed6917070c
commit 55070bcc41

View File

@ -5,8 +5,8 @@
//! //!
//! ## Syntax //! ## Syntax
//! [`Start`]` := `[`Program`] \ //! [`Start`]` := `[`Program`] \
//! [`Program`] := [`statement::Stmt`]* EOI \ //! [`Program`]` := `[`statement::Stmt`]`* EOI` \
//! [`Identifier`] := [`IDENTIFIER`](crate::token::token_type::Type::Identifier) //! [`Identifier`]` := `[`IDENTIFIER`](crate::token::token_type::Type::Identifier)
//! //!
//! See [statement], [literal], and [expression] for more information. //! See [statement], [literal], and [expression] for more information.
@ -17,28 +17,28 @@ pub mod preamble {
self, control, self, control,
math::{self, operator}, math::{self, operator},
}, },
literal, statement::Stmt, literal,
statement::Stmt,
visitor::{Visitor, Walk}, visitor::{Visitor, Walk},
Identifier, Program, Start, Identifier, Program, Start,
}; };
} }
/// Marks the root of a tree /// Marks the root of a tree
/// # Syntax /// # Syntax
/// [`Start`] := [`Program`] /// [`Start`]` := `[`Program`]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Start(pub Program); pub struct Start(pub Program);
/// Contains an entire Conlang program /// Contains an entire Conlang program
/// # Syntax /// # Syntax
/// [`Program`] := [`statement::Stmt`]* /// [`Program`]` := `[`statement::Stmt`]`* EOI`
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Program(pub Vec<statement::Stmt>); pub struct Program(pub Vec<statement::Stmt>);
/// An Identifier stores the name of an item /// An Identifier stores the name of an item
/// # Syntax /// # Syntax
/// [`Identifier`] := [`IDENTIFIER`](crate::token::token_type::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);
@ -102,16 +102,16 @@ pub mod literal {
/// Represents a literal value /// Represents a literal value
/// # Syntax /// # Syntax
/// [`Literal`] := [`String`] | [`char`] | [`bool`] | [`Float`] | [`u128`] /// [`Literal`]` := `[`String`]` | `[`char`]` | `[`bool`]` | `[`Float`]` | `[`u128`]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Literal { pub enum Literal {
/// Represents a literal string value /// Represents a literal string value
/// # Syntax /// # Syntax
/// [`Literal::String`] := [`STRING`](crate::token::token_type::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::token_type::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
@ -121,17 +121,17 @@ pub mod literal {
Bool(bool), Bool(bool),
/// Represents a literal float value /// Represents a literal float value
/// # Syntax /// # Syntax
/// [`Float`] := [`FLOAT`](crate::token::token_type::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::token_type::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::token_type::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,
@ -145,14 +145,14 @@ pub mod statement {
//! A statement is an expression which evaluates to Empty //! A statement is an expression which evaluates to Empty
//! //!
//! # Syntax //! # Syntax
//! [`Stmt`] := [`Let`](Stmt::Let) | [`Expr`](Stmt::Expr) //! [`Stmt`]` := `[`Let`](Stmt::Let)` | `[`Expr`](Stmt::Expr)
//! [`Let`](Stmt::Let) := `"let"` [`Identifier`] (`:` `Type`)? (`=` [`Expr`])? `;` //! [`Let`](Stmt::Let)` := "let"` [`Identifier`] (`:` `Type`)? (`=` [`Expr`])? `;`
//! [`Expr`](Stmt::Expr) := [`Expr`] `;` //! [`Expr`](Stmt::Expr)` := `[`Expr`] `;`
use super::{expression::Expr, Identifier}; use super::{expression::Expr, Identifier};
/// Contains a statement /// Contains a statement
/// # Syntax /// # Syntax
/// [`Stmt`] := [`Let`](Stmt::Let) | [`Expr`](Stmt::Expr) /// [`Stmt`]` := `[`Let`](Stmt::Let)` | `[`Expr`](Stmt::Expr)
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Stmt { pub enum Stmt {
/// Contains a variable declaration /// Contains a variable declaration
@ -174,42 +174,41 @@ pub mod statement {
pub mod expression { pub mod expression {
//! # Expressions //! # Expressions
//! //!
//! The [expression] is the backbone of Conlang: everything is an expression. //! The [expression] is the backbone of Conlang: almost everything is an expression.
//! //!
//! ## Grammar //! ## Grammar
//! Higher number = higher precedence. //! Higher number = higher precedence.
//! //!
//! | # | Node | Function //! | # | Node | Function
//! |----|------------------:|:---------------------------------------------- //! |---|------------------:|:----------------------------------------------
//! | 0 | [`Expr`] | Contains an expression //! | 0 | [`Expr`] | Contains an expression
//! | 1 | [`Ignore`](math) | Ignores the preceding sub-expression's result //! | 1 | [`Assign`](math) | Assignment
//! | 2 | [`Assign`](math) | Assignment //! | 2 | [`Compare`](math) | Value Comparison
//! | 3 | [`Compare`](math) | Value Comparison //! | 3 | [`Logic`](math) | Boolean And, Or, Xor
//! | 4 | [`Logic`](math) | Boolean And, Or, Xor //! | 4 | [`Bitwise`](math) | Bitwise And, Or, Xor
//! | 5 | [`Bitwise`](math) | Bitwise And, Or, Xor //! | 5 | [`Shift`](math) | Shift Left/Right
//! | 6 | [`Shift`](math) | Shift Left/Right //! | 6 | [`Term`](math) | Add, Subtract
//! | 7 | [`Term`](math) | Add, Subtract //! | 7 | [`Factor`](math) | Multiply, Divide, Remainder
//! | 8 | [`Factor`](math) | Multiply, Divide, Remainder //! | 8 | [`Unary`](math) | Unary Dereference, Reference, Negate, Not
//! | 9 | [`Unary`](math) | Unary Dereference, Reference, Negate, Not //! | 9 | [`control::Flow`] | Branch expressions (`if`, `while`, `for`, `return`, `break`, `continue`)
//! | 10 | [`control::Flow`] | Branch expressions (`if`, `while`, `for`, `return`, `break`, `continue`), `else` //! | 9 | [`Group`] | Group expressions `(` [Expr]? `)` /* Can evaluate to Empty! */
//! | 10 | [`Group`] | Group expressions `(` [Expr]? `)` /* Can evaluate to Empty! */ //! | 9 | [`Block`] | Block expressions `{` [Expr] `}`
//! | 10 | [`Block`] | Block expressions `{` [Expr] `}` //! | 9 | [`Primary`] | Contains an [Identifier], [Literal](literal::Literal), [Block], [Group], or [Flow](control::Flow)
//! | 10 | [`Primary`] | Contains an [Identifier], [Literal](literal::Literal), [Block], [Group], or [Flow](control::Flow)
//! //!
//! ## Syntax //! ## Syntax
//! ```ignore //! [`Expr`]` := `[`math::Operation`] \
//! Expr := control::Flow | math::Ignore //! [`Block`]` := '{' `[`Expr`]` '}'` \
//! Block := '{' Expr '}' //! [`Group`]` := '(' `[`Expr`]`? ')'` \
//! Group := '(' Expr? ')' //! [`Primary`]` := `[`Identifier`]` | `[`Literal`](literal::Literal)` | `[`Block`]` |
//! Primary := Identifier | Literal | Block | control::Branch //! `[`Group`]` | `[`control::Flow`]
//! ``` //!
//! See [control] and [math] for their respective production rules. //! See [control] and [math] for their respective production rules.
use super::*; use super::*;
/// Contains an expression /// Contains an expression
/// ///
/// # Syntax /// # Syntax
/// [`Expr`] := [`math::Operation`] /// [`Expr`]` := `[`math::Operation`]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Expr { pub struct Expr {
pub ignore: math::Operation, pub ignore: math::Operation,
@ -218,12 +217,11 @@ pub mod expression {
/// A [Primary] Expression is the expression with the highest precedence (i.e. the deepest /// A [Primary] Expression is the expression with the highest precedence (i.e. the deepest
/// derivation) /// derivation)
/// # Syntax /// # Syntax
/// [`Primary`] := /// [`Primary`]` := `[`IDENTIFIER`](Identifier)`
/// [`IDENTIFIER`](Identifier) /// | `[`Literal`](literal::Literal)`
/// | [`Literal`](literal::Literal) /// | `[`Block`]`
/// | [`Block`] /// | `[`Group`]`
/// | [`Group`] /// | `[`Branch`](control::Flow)
/// | [`Branch`](control::Flow)
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Primary { pub enum Primary {
Identifier(Identifier), Identifier(Identifier),
@ -256,35 +254,39 @@ pub mod expression {
//! ## Precedence Order //! ## Precedence Order
//! Operator associativity is always left-to-right among members of the same group //! Operator associativity is always left-to-right among members of the same group
//! //!
//! | # | Name | Operators | Associativity //! | # | Name | Operators | Associativity
//! |---|----------:|:--------------------------------------|--------------- //! |---|----------:|:----------------------------------------|---------------
// | | TODO: Try | `?` | // | | TODO: Try | `?` |
//! | 1 | Unary | `*` `&` `-` `!` | Right //! | 1 | Unary | [`*` `&` `-` `!`][3] | Right
//! | 2 | Factor | `*` `/` `%` | Left to Right //! | 2 | Factor | [`*` `/` `%`][4] | Left to Right
//! | 3 | Term | `+` `-` | Left to Right //! | 3 | Term | [`+` `-`][4] | Left to Right
//! | 4 | Shift | `<<` `>>` | Left to Right //! | 4 | Shift | [`<<` `>>`][4] | Left to Right
//! | 5 | Bitwise | `&` <code>&#124;</code> | Left to Right //! | 5 | Bitwise | [`&` <code>&#124;</code>][4] | Left to Right
//! | 6 | Logic | `&&` <code>&#124;&#124;</code> `^^` | Left to Right //! | 6 | Logic | [`&&` <code>&#124;&#124;</code> `^^`][4]| Left to Right
//! | 7 | Compare | `<` `<=` `==` `!=` `>=` `>` | Left to Right //! | 7 | Compare | [`<` `<=` `==` `!=` `>=` `>`][4] | Left to Right
#![doc = concat!( //| | #![doc = concat!( //| |
r" | 8 | Assign |", r"`*=`, `/=`, `%=`, `+=`, `-=`, ",//| r" | 8 | Assign | [`*=`, `/=`, `%=`, `+=`, `-=`, ", //|
/* | | |*/ r"`&=`, <code>&#124;=</code>, ", //| /* | | |*/ r"`&=`, <code>&#124;=</code>, ", //|
/* | | |*/ r"`^=`, `<<=`, `>>=`", r"| Right to Left")] /* | | |*/ r"`^=`, `<<=`, `>>=`][4]", r"| Left to Right")]
//! //!
//! <!-- Note: '&#124;' == '|' /--> //! <!-- Note: '&#124;' == '|' /-->
//! //!
//! ## Syntax //! ## Syntax
//! ```ignore //! All precedence levels other than [Unary][1] fold into [Binary][2]
//! /* All precedence levels other than Unary fold into Binary */ //!
//! Assign := Compare (AssignOp Compare)* //! [`Assign`][2]` := `[`Compare`][2]` (`[`AssignOp`][4]` `[`Compare`][2]`)*` \
//! Compare := Logic (CompareOp Logic )* //! [`Compare`][2]` := `[`Logic`][2]` (`[`CompareOp`][4]` `[`Logic`][2]` )*` \
//! Logic := Bitwise (LogicOp Bitwise)* //! [`Logic`][2]` := `[`Bitwise`][2]` (`[`LogicOp`][4]` `[`Bitwise`][2]`)*` \
//! Bitwise := Shift (BitwiseOp Shift )* //! [`Bitwise`][2]` := `[`Shift`][2]` (`[`BitwiseOp`][4]` `[`Shift`][2]` )*` \
//! Shift := Term (ShiftOp Term )* //! [`Shift`][2]` := `[`Term`][2]` (`[`ShiftOp`][4]` `[`Term`][2]` )*` \
//! Term := Factor (TermOp Factor )* //! [`Term`][2]` := `[`Factor`][2]` (`[`TermOp`][4]` `[`Factor`][2]` )*` \
//! Factor := Unary (FactorOp Unary )* //! [`Factor`][2]` := `[`Unary`][1]` (`[`FactorOp`][4]` `[`Unary`][1]` )*` \
//! Unary := (UnaryOp)* Primary //! [`Unary`][1]` := (`[`UnaryOp`][3]`)* `[`Primary`]
//! ``` //!
//! [1]: Operation::Unary
//! [2]: Operation::Binary
//! [3]: operator::Unary
//! [4]: operator::Binary
use super::*; use super::*;
/// An Operation is a tree of [operands](Primary) and [operators](operator). /// An Operation is a tree of [operands](Primary) and [operators](operator).
@ -309,22 +311,11 @@ pub mod expression {
} }
pub mod operator { pub mod operator {
//! | # | [Operators](self) | Associativity //! # [Unary] and [Binary] operators
//! |---|---------------------------------------|-------------- //!
//! | 0 |[`*`, `&`, `-`, `!`](Unary) | Left to Right //! An Operator represents the action taken during an [operation](super::Operation)
//! | 1 | `*`, `/`, `%` | Left to Right
//! | 2 | `+`, `-` | Left to Right
//! | 3 | `<<`, `>>` | Left to Right
//! | 4 | `&`, <code>&#124;</code>, `^` | Left to Right
//! | 5 | `&&`, <code>&#124;&#124;</code>, `^^` | Left to Right
//! | 6 | `>`. `>=`. `==`. `!=`. `<=`. `<` | Left to Right
#![doc = concat!(
r"| 7 |", r"`*=`, `/=`, `%=`, `+=`, `-=`, ",//|
/* | |*/ r"`&=`, <code>&#124;=</code>, ", //|
/* | |*/ r"`^=`, `<<=`, `>>=`, `=`", r"| Left to Right")]
//! | 8 | `,` |
/// Operators which take a single argument /// # Operators which take a single argument
/// ///
/// (`*`, `&`, `-`, `!`, `@`, `#`, `~`) /// (`*`, `&`, `-`, `!`, `@`, `#`, `~`)
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
@ -346,52 +337,61 @@ pub mod expression {
/// `~`: Undefined /// `~`: Undefined
Tilde, Tilde,
} }
/// Operators which take two arguments /// # Operators which take two arguments
/// ## Term operators:
/// [`*`](Binary::Mul), [`/`](Binary::Div), [`%`](Binary::Rem)
/// ## Factor operators
/// [`+`](Binary::Add), [`-`](Binary::Sub)
/// ## Shift operators
/// [`<<`](Binary::Lsh), [`>>`](Binary::Rsh)
/// ## Bitwise operators
/// [`&`](Binary::BitAnd), [`|`](Binary::BitOr), [`^`](Binary::BitXor)
/// ## Logic operators
/// [`&&`](Binary::LogAnd), [`||`](Binary::LogOr), [`^^`](Binary::LogXor)
/// ## Range operators
/// [`..`](Binary::RangeExc), [`..=`](Binary::RangeInc)
/// ## Comparison operators
/// [`<`](Binary::Less), [`<=`](Binary::LessEq), [`==`](Binary::Equal),
/// [`!=`](Binary::NotEq), [`>=`](Binary::GreaterEq), [`>`](Binary::Greater),
/// ## Assignment operators
/// [`=`](Binary::Assign), [`+=`](Binary::AddAssign), [`-=`](Binary::SubAssign),
/// [`*=`](Binary::MulAssign), [`/=`](Binary::DivAssign), [`%=`](Binary::RemAssign),
/// [`&=`](Binary::BitAndAssign), [`|=`](Binary::BitOrAssign),
/// [`^=`](Binary::BitXorAssign) [`<<=`](Binary::ShlAssign),
/// [`>>=`](Binary::ShrAssign)
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Binary { pub enum Binary {
// Term operators
/// `*`: Multiplication /// `*`: Multiplication
Mul, Mul,
/// `/`: Division /// `/`: Division
Div, Div,
/// `%`: Remainder /// `%`: Remainder
Rem, Rem,
// Factor operators
/// `+`: Addition /// `+`: Addition
Add, Add,
/// `-`: Subtraction /// `-`: Subtraction
Sub, Sub,
// Shift operators
/// `<<`: Left Shift /// `<<`: Left Shift
Lsh, Lsh,
/// `>>`: Right Shift /// `>>`: Right Shift
Rsh, Rsh,
// Bitwise operators
/// `&`: Bitwise AND /// `&`: Bitwise AND
BitAnd, BitAnd,
/// `|`: Bitwise OR /// `|`: Bitwise OR
BitOr, BitOr,
/// `^`: Bitwise XOR /// `^`: Bitwise XOR
BitXor, BitXor,
// Logic operators
/// `&&`: Short-circuiting logical AND /// `&&`: Short-circuiting logical AND
LogAnd, LogAnd,
/// `||`: Short-circuiting logical OR /// `||`: Short-circuiting logical OR
LogOr, LogOr,
/// `^^`: **Non-short-circuiting** logical XOR /// `^^`: **Non-short-circuiting** logical XOR
LogXor, LogXor,
// Range operators
/// `..`: Exclusive range /// `..`: Exclusive range
RangeExc, RangeExc,
/// `..=`: Inclusive range /// `..=`: Inclusive range
RangeInc, RangeInc,
// Comparison operators
/// `<`: Less-than Comparison /// `<`: Less-than Comparison
Less, Less,
/// `<=`: Less-than or Equal Comparison /// `<=`: Less-than or Equal Comparison
@ -404,8 +404,6 @@ pub mod expression {
GreaterEq, GreaterEq,
/// `>`: Greater-than Comparison /// `>`: Greater-than Comparison
Greater, Greater,
// Assignment operators
/// `=`: Assignment /// `=`: Assignment
Assign, Assign,
/// `+=`: Additive In-place Assignment /// `+=`: Additive In-place Assignment
@ -458,15 +456,17 @@ pub mod expression {
//! //!
//! [`continue` expressions][7] skip to the next iteration of a loop //! [`continue` expressions][7] skip to the next iteration of a loop
//! # Syntax //! # Syntax
//! ```rust,ignore //! [`Flow`]`  := `[`While`]` | `[`If`]` | `[`For`]` |
//! Branch := While | If | For //! `[`Break`]` | `[`Return`]` | `[`Continue`] \
//! If := "if" Expr Block Else?
//! While := "while" Expr Block Else?
//! For := "for" Identifier "in" Expr Block Else?
//! Else := "else" Block
//! //!
//! Break := "break" Expr //! [`While`]` := "while" `[`Expr`]` `[`Block`]` `[`Else`]`?` \
//! ``` //! [`If`]` := "if" `[`Expr`]` `[`Block`]` `[`Else`]`?` \
//! [`For`]` := "for" `[`Identifier`]` "in" `[`Expr`]` `[`Block`]` `[`Else`]`?` \
//! [`Else`]` := "else" `[`Block`] \
//!
//! [`Break`]`  := "break" `[`Expr`] \
//! [`Return`]`  := "return" `[`Expr`] \
//! [`Continue`]` := "continue"`
//! //!
//! [1]: If //! [1]: If
//! [2]: While //! [2]: While
@ -830,7 +830,7 @@ pub mod visitor {
/// Visit a [Primary] expression /// Visit a [Primary] expression
/// ///
/// [Primary] := [Identifier] | [Literal] | [Block] | [Flow] /// [`Primary`]` := `[`Identifier`]` | `[`Literal`]` | `[`Block`]` | `[`Flow`]
fn visit_primary(&mut self, expr: &Primary) -> R { fn visit_primary(&mut self, expr: &Primary) -> R {
match expr { match expr {
Primary::Identifier(v) => self.visit_identifier(v), Primary::Identifier(v) => self.visit_identifier(v),
@ -843,7 +843,8 @@ pub mod visitor {
/// Visit a [Flow] expression. /// Visit a [Flow] expression.
/// ///
/// [Flow] := [While] | [If] | [For] /// [`Flow`]` := `[`While`]` | `[`If`]` | `[`For`]`
/// | `[`Continue`]` | `[`Return`]` | `[`Break`]
fn visit_branch_expr(&mut self, expr: &Flow) -> R { fn visit_branch_expr(&mut self, expr: &Flow) -> R {
match expr { match expr {
Flow::While(e) => self.visit_while(e), Flow::While(e) => self.visit_while(e),
@ -874,7 +875,7 @@ pub mod visitor {
fn visit_identifier(&mut self, ident: &Identifier) -> R; fn visit_identifier(&mut self, ident: &Identifier) -> R;
/// Visit a [Literal] /// Visit a [Literal]
/// ///
/// [Literal] := [String] | [char] | [bool] | [Float] | [u128] /// [`Literal`]` := `[`String`]` | `[`char`]` | `[`bool`]` | `[`Float`]` | `[`u128`]
fn visit_literal(&mut self, literal: &Literal) -> R { fn visit_literal(&mut self, literal: &Literal) -> R {
match literal { match literal {
Literal::String(l) => self.visit_string_literal(l), Literal::String(l) => self.visit_string_literal(l),