diff --git a/wright/src/bin/wright.rs b/wright/src/bin/wright.rs index 1d97f6a3..7fc4f2f8 100644 --- a/wright/src/bin/wright.rs +++ b/wright/src/bin/wright.rs @@ -24,7 +24,7 @@ enum Commands { command: DebugCommands, }, - /// Subcommand to start an interactive repl. + /// Subcommand to start an interactive repl. Repl, } @@ -65,7 +65,7 @@ fn main() -> Result<()> { Ok(()) } - // Start an interactive repl. + // Start an interactive repl. Some(Commands::Repl) => repl::start(), _ => unimplemented!(), diff --git a/wright/src/filemap.rs b/wright/src/filemap.rs index f03c73ae..7f167a4e 100644 --- a/wright/src/filemap.rs +++ b/wright/src/filemap.rs @@ -12,7 +12,7 @@ pub enum FileName { Real(PathBuf), /// A named test-case in this crate's source code. Test(&'static str), - /// The interactive Wright repl. + /// The interactive Wright repl. #[display(fmt = "REPL:{}", line_number)] Repl { line_number: usize }, /// An un-named test case in this crate's source code. diff --git a/wright/src/lib.rs b/wright/src/lib.rs index b117765e..aa362ede 100644 --- a/wright/src/lib.rs +++ b/wright/src/lib.rs @@ -2,10 +2,10 @@ //! The wright programming language crate. This is being re-written from the ground up as of September 2022. -/// The version of this copy of Wright. +/// The version of this copy of Wright. pub const WRIGHT_VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub mod filemap; pub mod parser; -pub mod solver; pub mod repl; +pub mod solver; diff --git a/wright/src/parser.rs b/wright/src/parser.rs index e02ce2b4..3779b817 100644 --- a/wright/src/parser.rs +++ b/wright/src/parser.rs @@ -1,8 +1,7 @@ //! Parsers module, for all the parsers implemented by wright and necessary to parse wright source code. pub mod ast; +pub mod error; pub mod lexer; -pub mod util; pub mod state; -pub mod error; - +pub mod util; diff --git a/wright/src/parser/ast.rs b/wright/src/parser/ast.rs index 4a46943b..eb1c5906 100644 --- a/wright/src/parser/ast.rs +++ b/wright/src/parser/ast.rs @@ -7,10 +7,8 @@ pub mod expression; pub mod identifier; pub mod metadata; pub mod path; -pub mod types; pub mod statement; +pub mod types; /// Trait implementd -pub trait AstNode<'src> { - -} +pub trait AstNode<'src> {} diff --git a/wright/src/parser/ast/expression.rs b/wright/src/parser/ast/expression.rs index 032240ba..ac6120a4 100644 --- a/wright/src/parser/ast/expression.rs +++ b/wright/src/parser/ast/expression.rs @@ -10,7 +10,7 @@ pub mod primary; /// Enumeration of all the different kinds of expression in wright. #[derive(Debug)] pub enum Expression<'src> { - /// A literal in source code. + /// A literal in source code. Primary(Primary<'src>), // Block(block::Block<'src>), } diff --git a/wright/src/parser/ast/expression/literal.rs b/wright/src/parser/ast/expression/literal.rs index 43edeb30..43ceeac2 100644 --- a/wright/src/parser/ast/expression/literal.rs +++ b/wright/src/parser/ast/expression/literal.rs @@ -1,9 +1,14 @@ //! Representation for literal expressions in wright source code. -use crate::parser::{state::ParserState, util::{NodeParserResult, map::map_node_type, NodeParserOption, BoxedParserFn}}; - -use self::{boolean::{BooleanLiteral, parse_boolean_literal}, integer::{IntegerLiteral, parse_integer_literal}}; +use crate::parser::{ + state::ParserState, + util::{map::map_node_type, BoxedParserFn, NodeParserOption, NodeParserResult}, +}; +use self::{ + boolean::{parse_boolean_literal, BooleanLiteral}, + integer::{parse_integer_literal, IntegerLiteral}, +}; pub mod boolean; pub mod integer; @@ -14,27 +19,29 @@ pub mod integer; pub enum Literal<'src> { /// An integer literal in source code. Integer(IntegerLiteral<'src>), - /// A boolean literal in source code. + /// A boolean literal in source code. Boolean(BooleanLiteral<'src>), } -/// Parse a literal from source code. -pub fn parse_literal<'src>(parser_state: ParserState<'src>) -> NodeParserOption<'src, Literal<'src>> { - // Make a list of the parsers to attempt in order on fresh clones of the parser state. - // Map each parser to the enum constructor to normalize types. +/// Parse a literal from source code. +pub fn parse_literal<'src>( + parser_state: ParserState<'src>, +) -> NodeParserOption<'src, Literal<'src>> { + // Make a list of the parsers to attempt in order on fresh clones of the parser state. + // Map each parser to the enum constructor to normalize types. let literal_parsers: [BoxedParserFn<'src, NodeParserResult<'src, Literal<'src>>>; 2] = [ map_node_type(parse_integer_literal, Literal::Integer), map_node_type(parse_boolean_literal, Literal::Boolean), ]; for parser_function in literal_parsers.into_iter() { - // Make a clean state to pass to the child parser. + // Make a clean state to pass to the child parser. let clean_state = parser_state.clone(); - // Call the parser and handle the result. + // Call the parser and handle the result. match (parser_function)(clean_state) { - // Ignore/handle the output. - // Go to the next parser on errors. + // Ignore/handle the output. + // Go to the next parser on errors. Err(_) => continue, ok @ Ok(_) => return ok.ok(), } diff --git a/wright/src/parser/ast/expression/literal/boolean.rs b/wright/src/parser/ast/expression/literal/boolean.rs index a068a13b..3bf3ad31 100644 --- a/wright/src/parser/ast/expression/literal/boolean.rs +++ b/wright/src/parser/ast/expression/literal/boolean.rs @@ -1,6 +1,15 @@ //! Boolean literal representation and parsing in Wright source. -use crate::parser::{ast::metadata::AstNodeMeta, util::{NodeParserResult, ParserSuccess}, state::ParserState, lexer::{IndexedToken, tokens::{Token, TokenTy}}, error::{ParserError, ParserErrorVariant}}; +use crate::parser::{ + ast::metadata::AstNodeMeta, + error::{ParserError, ParserErrorVariant}, + lexer::{ + tokens::{Token, TokenTy}, + IndexedToken, + }, + state::ParserState, + util::{NodeParserResult, ParserSuccess}, +}; /// A boolean literal (true or false) in Wright source code. #[derive(Debug)] @@ -11,42 +20,54 @@ pub struct BooleanLiteral<'src> { pub value: bool, } -/// Attempt to parse a boolean literal from the lexer held by the parser state. -pub fn parse_boolean_literal<'src>(mut parser_state: ParserState<'src>) -> NodeParserResult<'src, BooleanLiteral<'src>> { - // Get the initial lexer index for later error reporting. +/// Attempt to parse a boolean literal from the lexer held by the parser state. +pub fn parse_boolean_literal<'src>( + mut parser_state: ParserState<'src>, +) -> NodeParserResult<'src, BooleanLiteral<'src>> { + // Get the initial lexer index for later error reporting. let initial_index = parser_state.lexer.index; - // Match on the next token + // Match on the next token match parser_state.lexer.next() { Some(IndexedToken { index, - token: Token { - variant: TokenTy::True, - length - } + token: + Token { + variant: TokenTy::True, + length, + }, }) => { - // Generate the AST node metadata for the parsed node. + // Generate the AST node metadata for the parsed node. let ast_node_meta = parser_state.make_ast_node_meta(index, length); Ok(ParserSuccess { updated_parser_state: parser_state, - ast_node: BooleanLiteral { meta: ast_node_meta, value: true }, + ast_node: BooleanLiteral { + meta: ast_node_meta, + value: true, + }, }) - }, + } Some(IndexedToken { token: Token { variant: TokenTy::False, - length + length, }, - index + index, }) => { // Make the AST node meta for the parsed node. let ast_node_meta = parser_state.make_ast_node_meta(index, length); - Ok(ParserSuccess { updated_parser_state: parser_state, ast_node: BooleanLiteral { meta: ast_node_meta, value: false } }) - }, + Ok(ParserSuccess { + updated_parser_state: parser_state, + ast_node: BooleanLiteral { + meta: ast_node_meta, + value: false, + }, + }) + } _ => Err(ParserError { byte_range: initial_index..parser_state.lexer.index, @@ -55,20 +76,18 @@ pub fn parse_boolean_literal<'src>(mut parser_state: ParserState<'src>) -> NodeP } } - - // impl<'a> Parse for ParseBooleanLiteral<'a> { // type Success = BooleanLiteral<'a>; // type Error = ParserError; // /// Attempt to parse a boolean literal from the given parser. This will mutate the parser, and return either [`Ok`] -// /// with a [`BooleanLiteral`] or an [`Err`] containing a [`ParserError`]. The parser will have the front-most -// /// [`Token`] consumed from its lexer regardless. +// /// with a [`BooleanLiteral`] or an [`Err`] containing a [`ParserError`]. The parser will have the front-most +// /// [`Token`] consumed from its lexer regardless. // fn parse<'src>(&self, parser: &mut Parser<'src>) -> Result { -// // Get the initial lexer index for use in calculating the span of errors reported. +// // Get the initial lexer index for use in calculating the span of errors reported. // let initial_index = parser.lexer.index; -// +// // } // } diff --git a/wright/src/parser/ast/expression/literal/integer.rs b/wright/src/parser/ast/expression/literal/integer.rs index ef2e478d..4caa369e 100644 --- a/wright/src/parser/ast/expression/literal/integer.rs +++ b/wright/src/parser/ast/expression/literal/integer.rs @@ -1,9 +1,17 @@ //! Integer literal representation and parsing in wright source. +use crate::parser::{ + ast::metadata::AstNodeMeta, + error::{ParserError, ParserErrorVariant}, + lexer::{ + tokens::{Token, TokenTy}, + IndexedToken, + }, + state::ParserState, + util::{NodeParserResult, ParserSuccess}, +}; use num::{BigUint, Num}; use std::cmp; -use crate::parser::{state::ParserState, ast::metadata::AstNodeMeta, util::{NodeParserResult, ParserSuccess}, lexer::{IndexedToken, tokens::{Token, TokenTy}}, error::{ParserError, ParserErrorVariant}}; - /// An integer in Wright source code. #[derive(Debug)] @@ -14,12 +22,14 @@ pub struct IntegerLiteral<'src> { pub value: BigUint, } -/// Parse an [`IntegerLiteral`] from source code. -pub fn parse_integer_literal<'src>(mut parser_state: ParserState<'src>) -> NodeParserResult<'src, IntegerLiteral<'src>> { - // Get the initial index of the lexer for later error reporting. +/// Parse an [`IntegerLiteral`] from source code. +pub fn parse_integer_literal<'src>( + mut parser_state: ParserState<'src>, +) -> NodeParserResult<'src, IntegerLiteral<'src>> { + // Get the initial index of the lexer for later error reporting. let initial_index = parser_state.lexer.index; - // Match on the next token from the lexer, erroring if it's anything but an integer literal. + // Match on the next token from the lexer, erroring if it's anything but an integer literal. match parser_state.lexer.next() { Some(IndexedToken { index, @@ -58,12 +68,12 @@ pub fn parse_integer_literal<'src>(mut parser_state: ParserState<'src>) -> NodeP // Make the AST node metadata for the parsed value let ast_node_meta = parser_state.make_ast_node_meta(index, length); - Ok(ParserSuccess { - updated_parser_state: parser_state, + Ok(ParserSuccess { + updated_parser_state: parser_state, ast_node: IntegerLiteral { meta: ast_node_meta, value, - } + }, }) } diff --git a/wright/src/parser/ast/expression/parentheses.rs b/wright/src/parser/ast/expression/parentheses.rs index 1f97aa6e..c30c8ac5 100644 --- a/wright/src/parser/ast/expression/parentheses.rs +++ b/wright/src/parser/ast/expression/parentheses.rs @@ -1,4 +1,4 @@ -//! An expression in parentheses in Wright source code. +//! An expression in parentheses in Wright source code. use crate::parser::ast::metadata::AstNodeMeta; diff --git a/wright/src/parser/ast/expression/primary.rs b/wright/src/parser/ast/expression/primary.rs index dba31c16..916ed19a 100644 --- a/wright/src/parser/ast/expression/primary.rs +++ b/wright/src/parser/ast/expression/primary.rs @@ -1,19 +1,18 @@ -//! Primary expressions in Qright source code. +//! Primary expressions in Qright source code. -use crate::parser::ast::path::Path; use super::{literal::Literal, parentheses::ParenthesesExpression}; +use crate::parser::ast::path::Path; -/// A primary expression is a special type of low-level expression that can appear in places where other expressions -/// (such as blocks or conditionals) are not allowed. +/// A primary expression is a special type of low-level expression that can appear in places where other expressions +/// (such as blocks or conditionals) are not allowed. #[derive(Debug)] pub enum Primary<'src> { /// A literal in source code. Literal(Literal<'src>), - /// A path to an item/symbol/constant value. - /// - /// This includes identifiers as single element paths. + /// A path to an item/symbol/constant value. + /// + /// This includes identifiers as single element paths. Path(Path<'src>), - /// An expression in parentheses. - Parentheses(ParenthesesExpression<'src>) + /// An expression in parentheses. + Parentheses(ParenthesesExpression<'src>), } - diff --git a/wright/src/parser/ast/identifier.rs b/wright/src/parser/ast/identifier.rs index a5e0ecbb..5b8205bb 100644 --- a/wright/src/parser/ast/identifier.rs +++ b/wright/src/parser/ast/identifier.rs @@ -12,8 +12,8 @@ pub struct Identifier<'src> { // impl<'src> Parser<'src> { // /// Parse an identifier in source code or error. -// /// -// /// If the parse is unsuccessful, return an error and do not update the parser state. +// /// +// /// If the parse is unsuccessful, return an error and do not update the parser state. // pub fn parse_identifier(&mut self) -> ParserResult> { // // Clone the lexer to try to parse an identifier. // let mut lexer = self.lexer.clone(); diff --git a/wright/src/parser/ast/path.rs b/wright/src/parser/ast/path.rs index c0f5383b..5cd12863 100644 --- a/wright/src/parser/ast/path.rs +++ b/wright/src/parser/ast/path.rs @@ -18,54 +18,54 @@ pub struct Path<'src> { } // impl<'src> Parser<'src> { -// /// Try to parse a path from the inner lexer iterator. -// /// The result may be a single length path holding one identifier. -// /// -// /// If a [`Path`] could not be parsed, return an error and leave the parser unmodified. +// /// Try to parse a path from the inner lexer iterator. +// /// The result may be a single length path holding one identifier. +// /// +// /// If a [`Path`] could not be parsed, return an error and leave the parser unmodified. // pub fn parse_path(&mut self) -> ParserResult> { -// // Clone the lexer -- leave this as the unmodified lexer to replace if the parse fails. +// // Clone the lexer -- leave this as the unmodified lexer to replace if the parse fails. // let initial_lexer = self.lexer.clone(); -// // Try parsing an identifier. +// // Try parsing an identifier. // let head = self.parse_identifier() // // If we parse no head, swap out the error type and return. // .map_err(|ParserError { byte_range, ..} | ParserError { // byte_range, // ty: ParserErrorVariant::Expected("fully-qualified symbol reference (path) or identifier") // })?; - -// // Try parsing the rest of the path. Pass into box/heap allocation on success. + +// // Try parsing the rest of the path. Pass into box/heap allocation on success. // let tail = self.parse_path_tail().map(Box::new); -// // Return the parsed path. -// Ok(Path { -// // Make the node metadata. -// meta: AstNodeMeta { -// file_map: self.file_map, -// file_id: self.file_id, -// index: initial_lexer.index, -// matching_source: &self.source[initial_lexer.index..self.lexer.index] -// }, +// // Return the parsed path. +// Ok(Path { +// // Make the node metadata. +// meta: AstNodeMeta { +// file_map: self.file_map, +// file_id: self.file_id, +// index: initial_lexer.index, +// matching_source: &self.source[initial_lexer.index..self.lexer.index] +// }, -// head, -// tail +// head, +// tail // }) // } // /// Try parsing the tail of a path. This gets called recursively in path parsing. // fn parse_path_tail(&mut self) -> Option> { -// // Clone the initial lexer. +// // Clone the initial lexer. // let initial_lexer = self.lexer.clone(); // // Allow (ignore) whitespace between initial head and first double colon. // self.ignore_whitespace(); // // First parse through a single double colon. // if let Some(IndexedToken { token: Token { variant: TokenTy::ColonColon, .. }, .. }) = self.lexer.next() { -// // Allow a whitespace between the double colon and head identifier. +// // Allow a whitespace between the double colon and head identifier. // self.ignore_whitespace(); -// // Try to parse the head identifier. +// // Try to parse the head identifier. // let head = match self.parse_identifier().ok() { -// // On success, keep the head, continue to parse the tail. +// // On success, keep the head, continue to parse the tail. // Some(head) => head, // // No head -- role back to the initial parser (pre-double colon and whitespaces) and return none. @@ -75,20 +75,20 @@ pub struct Path<'src> { // } // }; -// // Then try to parse the tail. Pass into box on success. +// // Then try to parse the tail. Pass into box on success. // let tail = self.parse_path_tail().map(Box::new); // // Return the parsed path. -// Some(Path { -// meta: AstNodeMeta { -// file_map: self.file_map, -// file_id: self.file_id, -// index: initial_lexer.index, +// Some(Path { +// meta: AstNodeMeta { +// file_map: self.file_map, +// file_id: self.file_id, +// index: initial_lexer.index, // matching_source: &self.source[initial_lexer.index..self.lexer.index] -// }, +// }, -// head, -// tail +// head, +// tail // }) // } else { diff --git a/wright/src/parser/ast/statement.rs b/wright/src/parser/ast/statement.rs index 360cdaa9..f3e484e4 100644 --- a/wright/src/parser/ast/statement.rs +++ b/wright/src/parser/ast/statement.rs @@ -1,10 +1,10 @@ -//! Statements in Wright source code. +//! Statements in Wright source code. use self::bind::Bind; pub mod bind; pub enum Statement<'src> { - /// A variable or constant binding. - Bind(Bind<'src>) + /// A variable or constant binding. + Bind(Bind<'src>), } diff --git a/wright/src/parser/ast/statement/bind.rs b/wright/src/parser/ast/statement/bind.rs index 6db98431..651f2ff8 100644 --- a/wright/src/parser/ast/statement/bind.rs +++ b/wright/src/parser/ast/statement/bind.rs @@ -1,10 +1,8 @@ -//! Statements that bind a value to a symbol, possibly with a type, in the context of a scope. +//! Statements that bind a value to a symbol, possibly with a type, in the context of a scope. use crate::parser::ast::metadata::AstNodeMeta; -/// Bind statement +/// Bind statement pub struct Bind<'src> { - pub meta: AstNodeMeta<'src> + pub meta: AstNodeMeta<'src>, } - - diff --git a/wright/src/parser/error.rs b/wright/src/parser/error.rs index 9b38eda5..bb611e69 100644 --- a/wright/src/parser/error.rs +++ b/wright/src/parser/error.rs @@ -1,4 +1,4 @@ -//! Parser error handling. +//! Parser error handling. use std::ops::Range; @@ -17,4 +17,3 @@ pub enum ParserErrorVariant { /// Something was expected and wasn't there. Expected(&'static str), } - diff --git a/wright/src/parser/state.rs b/wright/src/parser/state.rs index 661b5843..b7f12b84 100644 --- a/wright/src/parser/state.rs +++ b/wright/src/parser/state.rs @@ -1,10 +1,10 @@ -//! Parser state structure and implementation. +//! Parser state structure and implementation. -use crate::filemap::{FileMap, FileId}; -use super::{lexer::IndexedLexer, ast::metadata::AstNodeMeta}; +use super::{ast::metadata::AstNodeMeta, lexer::IndexedLexer}; +use crate::filemap::{FileId, FileMap}; use codespan_reporting::files::Files; -/// The state of the [`Parser`] used to transform wright source code into the +/// The state of the [`Parser`] used to transform wright source code into the /// appropriate series of [AST] (Abstract Syntax Tree) nodes. /// /// [AST]: https://en.wikipedia.org/wiki/Abstract_syntax_tree @@ -39,15 +39,15 @@ impl<'src> ParserState<'src> { } } - /// Make a new [`AstNodeMeta`] object using this [`Parser`]'s [`FileMap`] and [`FileId`]. + /// Make a new [`AstNodeMeta`] object using this [`Parser`]'s [`FileMap`] and [`FileId`]. /// The byte index and byte length in source code are supplied as arguments, usually from the - /// [`IndexedToken`] pulled from this [Parser]'s internal [`IndexedLexer`]. + /// [`IndexedToken`] pulled from this [Parser]'s internal [`IndexedLexer`]. pub fn make_ast_node_meta(&self, index: usize, length: usize) -> AstNodeMeta<'src> { - AstNodeMeta { + AstNodeMeta { file_map: self.file_map, file_id: self.file_id, index: index, - matching_source: &self.source[index..index+length] + matching_source: &self.source[index..index + length], } } } diff --git a/wright/src/parser/util.rs b/wright/src/parser/util.rs index 2b6a0716..c20d51ce 100644 --- a/wright/src/parser/util.rs +++ b/wright/src/parser/util.rs @@ -1,28 +1,28 @@ //! Parsing utility functions used throughout the parser to make the process of parsing easier. -use super::{state::ParserState, error::ParserError}; +use super::{error::ParserError, state::ParserState}; -pub mod map; -pub mod first_successful; pub mod discard_error; +pub mod first_successful; +pub mod map; - -/// The output of a successful parse always includes the updated [`ParserState`] after parsing and the -/// parsed AST node. +/// The output of a successful parse always includes the updated [`ParserState`] after parsing and the +/// parsed AST node. #[derive(Debug)] pub struct ParserSuccess<'src, Node> { /// The updated state of the parser. pub updated_parser_state: ParserState<'src>, - /// The produced AST node. - pub ast_node: Node + /// The produced AST node. + pub ast_node: Node, } /// A [`Result`] returned from an AST node parser. -pub type NodeParserResult<'src, Node, Error = ParserError> = Result, Error>; +pub type NodeParserResult<'src, Node, Error = ParserError> = + Result, Error>; -/// An [`Option`] returned from an AST node parser. +/// An [`Option`] returned from an AST node parser. pub type NodeParserOption<'src, Node> = Option>; -/// Type alias used to apease the borrow/lifetime checker complaining about HKTs and stuff. +/// Type alias used to apease the borrow/lifetime checker complaining about HKTs and stuff. pub type BoxedParserFn<'src, Output> = Box) -> Output>; diff --git a/wright/src/parser/util/discard_error.rs b/wright/src/parser/util/discard_error.rs index 452486b6..6c82d524 100644 --- a/wright/src/parser/util/discard_error.rs +++ b/wright/src/parser/util/discard_error.rs @@ -1,15 +1,16 @@ //! Parser function combinator useful for discarding errors. This can transform a parser from returning a [`Result`] -//! to returning an [`Option`]. +//! to returning an [`Option`]. use crate::parser::state::ParserState; -use super::{NodeParserOption, NodeParserResult, BoxedParserFn}; +use super::{BoxedParserFn, NodeParserOption, NodeParserResult}; -/// Return a [Box]xed parser function that returns an [`Option`] rather than a [`Result`]. -pub fn discard_errors<'src, PF, O>(parser_function: PF) -> BoxedParserFn<'src, NodeParserOption<'src, O>> -where PF: (Fn(ParserState<'src>) -> NodeParserResult) + 'static +/// Return a [Box]xed parser function that returns an [`Option`] rather than a [`Result`]. +pub fn discard_errors<'src, PF, O>( + parser_function: PF, +) -> BoxedParserFn<'src, NodeParserOption<'src, O>> +where + PF: (Fn(ParserState<'src>) -> NodeParserResult) + 'static, { - Box::new(move |parser_state: ParserState<'_>| { - ((parser_function)(parser_state)).ok() - }) + Box::new(move |parser_state: ParserState<'_>| ((parser_function)(parser_state)).ok()) } diff --git a/wright/src/parser/util/first_successful.rs b/wright/src/parser/util/first_successful.rs index 7b09ab4d..f950e5aa 100644 --- a/wright/src/parser/util/first_successful.rs +++ b/wright/src/parser/util/first_successful.rs @@ -1,30 +1,29 @@ -//! The [`FirstSuccessful`] parse combinator takes a series of parsers and applies them in order until one is -//! successful. +//! The [`FirstSuccessful`] parse combinator takes a series of parsers and applies them in order until one is +//! successful. // use crate::parser::state::ParserState; // use super::NodeParserOption; - // /// Object that holds the series of parsers to test in order. The first one that produces -// /// an [`Ok`] will return, all others will be discarded. -// /// +// /// an [`Ok`] will return, all others will be discarded. +// /// // /// - Each item must implement [`Parse`] and -// /// will be erased when added to this object. +// /// will be erased when added to this object. // /// - Each item will be run on a fresh clone of the original [`Parser`] -// /// so that the partial progress of one will not effect any others. -// /// - Errors from any of the contained/child parsers will be ignored. -// /// - If none of the parse functions are successful then an [`Err`] with no content will be returned. -// /// +// /// so that the partial progress of one will not effect any others. +// /// - Errors from any of the contained/child parsers will be ignored. +// /// - If none of the parse functions are successful then an [`Err`] with no content will be returned. +// /// // pub struct FirstSuccessful { -// /// All parse functions passed to this object should be erased. +// /// All parse functions passed to this object should be erased. // pub parse_fns: Vec Fn(ParserState<'pf_s>) -> NodeParserOption<'pf_s, T>>> // } // pub fn first_successful // impl FirstSuccessful { -// /// Create a new empty [`FirstSuccessful`] parse function. +// /// Create a new empty [`FirstSuccessful`] parse function. // pub fn new() -> Self { // Self { parse_fns: Vec::new() } // } @@ -36,7 +35,7 @@ // self // } -// /// Push an additional parse function to the end of this objects list of [`Parse`] functions to try. +// /// Push an additional parse function to the end of this objects list of [`Parse`] functions to try. // pub fn push(&mut self, p: impl Parse) { // self.parse_fns.push(p.discard_error()) // } @@ -50,11 +49,11 @@ // fn parse<'src>(&self, parser: &mut Parser<'src>) -> Result { // // Iterate in order over child parsers. // for parse_fn in self.parse_fns.iter() { -// // Clone the parser state so that we have a clean parser every time. +// // Clone the parser state so that we have a clean parser every time. // let mut clean_parser = parser.clone(); -// // Try the given parse function. +// // Try the given parse function. // let parse_result = parse_fn.parse(&mut clean_parser); -// // Check and return +// // Check and return // if parse_result.is_ok() { // // Update the lexer on the parent parser. // parser.lexer = clean_parser.lexer; diff --git a/wright/src/parser/util/map.rs b/wright/src/parser/util/map.rs index c4b03c0c..a5081519 100644 --- a/wright/src/parser/util/map.rs +++ b/wright/src/parser/util/map.rs @@ -1,33 +1,42 @@ -//! Parser mapping utilities. +//! Parser mapping utilities. use crate::parser::state::ParserState; -use super::{NodeParserResult, ParserSuccess, BoxedParserFn}; +use super::{BoxedParserFn, NodeParserResult, ParserSuccess}; -/// Create a [Box]xed function (dyn [`Fn`]) that maps the output of a parser function through another function. +/// Create a [Box]xed function (dyn [`Fn`]) that maps the output of a parser function through another function. pub fn map<'src, PF, MF, O1, O2>(parser_function: PF, map_function: MF) -> BoxedParserFn<'src, O2> -where +where PF: (Fn(ParserState<'src>) -> O1) + 'static, MF: (Fn(O1) -> O2) + 'static, { - Box::new(move |parser_state: ParserState| { - (map_function)((parser_function)(parser_state)) - }) + Box::new(move |parser_state: ParserState| (map_function)((parser_function)(parser_state))) } /// Map specifically the node -pub fn map_node_type<'src, PF, MF, N1, N2>(parser_function: PF, map_function: MF) -> BoxedParserFn<'src, NodeParserResult<'src, N2>> +pub fn map_node_type<'src, PF, MF, N1, N2>( + parser_function: PF, + map_function: MF, +) -> BoxedParserFn<'src, NodeParserResult<'src, N2>> where PF: (Fn(ParserState<'src>) -> NodeParserResult) + 'static, - MF: (Fn(N1) -> N2) + 'static + MF: (Fn(N1) -> N2) + 'static, { Box::new(move |parse_state: ParserState<'_>| { // Run the parser and get the result. let parse_result = (parser_function)(parse_state); // Map the node type - parse_result.map(|ParserSuccess { updated_parser_state, ast_node }| { - ParserSuccess { updated_parser_state, ast_node: ((map_function)(ast_node)) } - }) + parse_result.map( + |ParserSuccess { + updated_parser_state, + ast_node, + }| { + ParserSuccess { + updated_parser_state, + ast_node: ((map_function)(ast_node)), + } + }, + ) }) } diff --git a/wright/src/repl.rs b/wright/src/repl.rs index a0875790..0f9dfd15 100644 --- a/wright/src/repl.rs +++ b/wright/src/repl.rs @@ -1,8 +1,12 @@ -//! The Wright interactive REPL. +//! The Wright interactive REPL. -use std::io::{self, BufRead, Write}; -use crate::{WRIGHT_VERSION, filemap::{FileMap, FileName}, parser::lexer::Lexer}; +use crate::{ + filemap::{FileMap, FileName}, + parser::lexer::Lexer, + WRIGHT_VERSION, +}; use derive_more::Display; +use std::io::{self, BufRead, Write}; const HELP_MESSAGE: &'static str = " Wright REPL Help: @@ -25,21 +29,20 @@ Modes: #[derive(Clone, Copy, PartialEq, Debug, Default, Display)] enum ReplMode { - - /// Default REPL mode -- evaluates and prints results of input. + /// Default REPL mode -- evaluates and prints results of input. #[default] Eval, - /// Print the tokens passed to the repl. - Tokens, + /// Print the tokens passed to the repl. + Tokens, - /// Print the AST Tree passed to the repl. + /// Print the AST Tree passed to the repl. Ast, } -/// Start an interactive Wright repl. +/// Start an interactive Wright repl. pub fn start() -> anyhow::Result<()> { - // Print version info. + // Print version info. println!("Wright REPL interpreter (wright version {})", WRIGHT_VERSION); // Get a global lock on the standard input. @@ -54,23 +57,23 @@ pub fn start() -> anyhow::Result<()> { // Set the repl mode. let mut repl_mode = ReplMode::Tokens; - // Make a file map to track input. + // Make a file map to track input. let mut code_map = FileMap::new(); - // Loop until this returns/exits. + // Loop until this returns/exits. loop { // Increment input number. input_number += 1; - // Write prompt. + // Write prompt. write!(&mut output, "[{}]: >> ", input_number)?; output.flush()?; - // Read line of input. + // Read line of input. let mut line = String::new(); input.read_line(&mut line)?; - - // Handle certain builtin REPL commands. + + // Handle certain builtin REPL commands. match line.trim() { ":?" | ":h" | ":help" => { writeln!(&mut output, "{}", HELP_MESSAGE)?; @@ -109,7 +112,7 @@ pub fn start() -> anyhow::Result<()> { continue; } - // Any other input is a no-op here and will get handled later. + // Any other input is a no-op here and will get handled later. _ => {} } @@ -118,8 +121,13 @@ pub fn start() -> anyhow::Result<()> { output.flush()?; // Add line to the code map. - let file_handle = code_map.add(FileName::Repl { line_number: input_number }, line); - // Get a ref to the line we just added to the code map. + let file_handle = code_map.add( + FileName::Repl { + line_number: input_number, + }, + line, + ); + // Get a ref to the line we just added to the code map. let line_ref: &str = code_map.get(file_handle).unwrap().source().as_str(); match repl_mode { @@ -135,12 +143,11 @@ pub fn start() -> anyhow::Result<()> { write!(&mut output, "[{}]", token)?; } - // Write newline. + // Write newline. writeln!(&mut output, "")?; } ReplMode::Eval => unimplemented!("Eval mode is unimplemented."), } - } }