From 76a67c5117a84fcec85752b06015f83ca0df5133 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 7 Aug 2024 12:32:18 -0400 Subject: [PATCH] Add parse examples --- dust-lang/src/lex.rs | 2 +- dust-lang/src/parse.rs | 78 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/dust-lang/src/lex.rs b/dust-lang/src/lex.rs index 4ed88fc..aa88607 100644 --- a/dust-lang/src/lex.rs +++ b/dust-lang/src/lex.rs @@ -7,7 +7,7 @@ use std::num::{ParseFloatError, ParseIntError}; use crate::{Identifier, ReservedIdentifier, Span, Token}; -/// Lex the input and return a vector of tokens and their positions. +/// Lexes the input and return a vector of tokens and their positions. /// /// # Examples /// ``` diff --git a/dust-lang/src/parse.rs b/dust-lang/src/parse.rs index bfe33a2..17c6ed5 100644 --- a/dust-lang/src/parse.rs +++ b/dust-lang/src/parse.rs @@ -1,7 +1,41 @@ +/// Parsing tools. +/// +/// This module provides two parsing options: +/// - `parse` convenience function +/// - `Parser` struct, which parses the input a statement at a time use std::collections::VecDeque; use crate::{AbstractSyntaxTree, LexError, Lexer, Node, Span, Statement, Token, Value}; +/// Parses the input into an abstract syntax tree. +/// +/// # Examples +/// ``` +/// # use dust_lang::*; +/// let input = "x = 42"; +/// let result = parse(input); +/// +/// assert_eq!( +/// result, +/// Ok(AbstractSyntaxTree { +/// nodes: [ +/// Node { +/// statement: Statement::Assign( +/// Box::new(Node { +/// statement: Statement::Identifier("x".into()), +/// span: (0, 1), +/// }), +/// Box::new(Node { +/// statement: Statement::Constant(Value::integer(42)), +/// span: (4, 6), +/// }) +/// ), +/// span: (0, 6), +/// } +/// ].into(), +/// }), +/// ); +/// ``` pub fn parse(input: &str) -> Result { let lexer = Lexer::new(input); let mut parser = Parser::new(lexer); @@ -20,6 +54,46 @@ pub fn parse(input: &str) -> Result { Ok(AbstractSyntaxTree { nodes }) } +/// Low-level tool for parsing the input a statement at a time. +/// +/// # Examples +/// ``` +/// # use std::collections::VecDeque; +/// # use dust_lang::*; +/// let input = "x = 42"; +/// let lexer = Lexer::new(input); +/// let mut parser = Parser::new(lexer); +/// let mut nodes = VecDeque::new(); +/// +/// loop { +/// let node = parser.parse().unwrap(); +/// +/// nodes.push_back(node); +/// +/// if let Token::Eof = parser.current().0 { +/// break; +/// } +/// } +/// +/// assert_eq!( +/// nodes, +/// Into::>::into([ +/// Node { +/// statement: Statement::Assign( +/// Box::new(Node { +/// statement: Statement::Identifier("x".into()), +/// span: (0, 1), +/// }), +/// Box::new(Node { +/// statement: Statement::Constant(Value::integer(42)), +/// span: (4, 6), +/// }) +/// ), +/// span: (0, 6), +/// } +/// ]), +/// ); +/// ``` pub struct Parser<'src> { lexer: Lexer<'src>, current: (Token, Span), @@ -37,6 +111,10 @@ impl<'src> Parser<'src> { self.parse_node(0) } + pub fn current(&self) -> &(Token, Span) { + &self.current + } + fn next_token(&mut self) -> Result<(), ParseError> { self.current = self.lexer.next_token()?;