From 88912bfa39ce1b42a6161cc5a9d2a6de60496ee3 Mon Sep 17 00:00:00 2001 From: Jesse Braham Date: Tue, 24 Dec 2024 09:02:18 +0100 Subject: [PATCH] Rewrote the parser --- onihime/src/lexer/mod.rs | 6 + onihime/src/parser/{node.rs => ast.rs} | 234 ++++++++++------- onihime/src/parser/error.rs | 49 ++-- onihime/src/parser/mod.rs | 335 ++++++++++++------------- 4 files changed, 335 insertions(+), 289 deletions(-) rename onihime/src/parser/{node.rs => ast.rs} (66%) diff --git a/onihime/src/lexer/mod.rs b/onihime/src/lexer/mod.rs index b0e808c..fccfd94 100644 --- a/onihime/src/lexer/mod.rs +++ b/onihime/src/lexer/mod.rs @@ -59,6 +59,12 @@ impl<'lexer> Lexer<'lexer> { Span::new(self.byte..self.byte, self.source.clone()) } + /// Returns `true` when at the end of the input. + #[must_use] + pub(crate) fn eof(&self) -> bool { + self.peek(0).is_none() + } + /// Get the current character. #[must_use] fn current(&self) -> Option { diff --git a/onihime/src/parser/node.rs b/onihime/src/parser/ast.rs similarity index 66% rename from onihime/src/parser/node.rs rename to onihime/src/parser/ast.rs index 62272b1..a1ff399 100644 --- a/onihime/src/parser/node.rs +++ b/onihime/src/parser/ast.rs @@ -4,9 +4,123 @@ use crate::{ span::Span, }; +/// Abstract Syntax Tree (AST). +#[derive(Debug, Default, Clone, PartialEq)] +pub(crate) struct Ast { + root: Vec, +} + +impl Ast { + /// Construct a new instance of `Ast`. + #[must_use] + pub(crate) fn new(root: Vec) -> Self { + Self { root } + } +} + +impl From> for Ast { + fn from(root: Vec) -> Self { + Self { root } + } +} + +#[cfg(not(tarpaulin_include))] +impl std::fmt::Display for Ast { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for node in &self.root { + write!(f, "{node}\n")?; + } + + Ok(()) + } +} + +/// A node in the Abstract Syntax Tree (AST). +/// +/// `Nodes`s contain the kind of node which was found, as well as a [Span] +/// specifying the [Source] and [Location] of the node. +/// +/// [Source]: crate::span::Source +/// [Location]: crate::span::Location +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct Node { + /// The kind of node. + pub kind: Expr, + /// The span in which the node occurs. + pub span: Span, +} + +impl Node { + /// Construct a new instance of `Node`. + #[must_use] + pub(crate) fn new(kind: Expr, span: Span) -> Self { + Self { kind, span } + } + + /// Push a child node onto a list node. + pub(crate) fn push_node(&mut self, child: Self) -> Result<(), ParserError> { + match &mut self.kind { + Expr::List(vec) | Expr::Map(vec) | Expr::Set(vec) | Expr::Vector(vec) => { + vec.push(child); + } + _ => { + // FIXME + // return Err(ParserError::new( + // ParserErrorKind::UnexpectedState, + // child.span, + // )) + todo!() + } + } + + Ok(()) + } + + #[cfg(not(tarpaulin_include))] + #[must_use] + fn display(&self, indent: usize) -> String { + let mut text = format!( + "{}{}@{}..{}\n", + " ".repeat(indent), + self.kind, + self.span.bytes().start, + self.span.bytes().end + ); + + match &self.kind { + Expr::Atom(_) => {} + Expr::List(vec) | Expr::Map(vec) | Expr::Set(vec) | Expr::Vector(vec) => { + for node in vec { + text.push_str(&format!("{}\n", node.display(indent + 1))); + } + } + } + + text.trim_end().to_string() + } +} + +impl TryFrom for Node { + type Error = ParserError; + + fn try_from(token: Token) -> Result { + let span = token.span.clone(); + let kind = Expr::try_from(token)?; + + Ok(Self::new(kind, span)) + } +} + +#[cfg(not(tarpaulin_include))] +impl std::fmt::Display for Node { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.display(0)) + } +} + /// An atomic value. #[derive(Debug, Clone, PartialEq)] -pub enum Atom { +pub(crate) enum Atom { /// Boolean, e.g. `true`, `false` Bool(bool), /// Character, e.g. `'c'`, `'\n'` @@ -45,7 +159,7 @@ impl std::fmt::Display for Atom { /// An expression. #[derive(Debug, Clone, PartialEq)] -pub enum NodeKind { +pub(crate) enum Expr { /// An atomic value. Atom(Atom), /// A list of nodes. @@ -58,13 +172,25 @@ pub enum NodeKind { Vector(Vec), } -impl From for NodeKind { +impl Expr { + /// Which closing delimiter is associated with the expression kind? + pub(crate) fn closing_delimiter(&self) -> Option { + match self { + Expr::List(_) => Some(TokenKind::CloseParen), + Expr::Map(_) | Expr::Set(_) => Some(TokenKind::CloseBrace), + Expr::Vector(_) => Some(TokenKind::CloseBracket), + _ => None, + } + } +} + +impl From for Expr { fn from(atom: Atom) -> Self { Self::Atom(atom) } } -impl TryFrom for NodeKind { +impl TryFrom for Expr { type Error = ParserError; fn try_from(token: Token) -> Result { @@ -78,10 +204,12 @@ impl TryFrom for NodeKind { TokenKind::Symbol(s) => Atom::Symbol(s), TokenKind::Nil => Atom::Nil, _ => { - return Err(ParserError::new( - ParserErrorKind::UnexpectedState, - token.span, - )) + // FIXME + // return Err(ParserError::new( + // ParserErrorKind::UnexpectedState, + // token.span, + // )) + todo!() } }; @@ -90,9 +218,9 @@ impl TryFrom for NodeKind { } #[cfg(not(tarpaulin_include))] -impl std::fmt::Display for NodeKind { +impl std::fmt::Display for Expr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use NodeKind::*; + use Expr::*; match self { Atom(atom) => write!(f, "{atom}"), @@ -103,89 +231,3 @@ impl std::fmt::Display for NodeKind { } } } - -/// A node in the Abstract Syntax Tree (AST). -/// -/// `Nodes`s contain the kind of node which was found, as well as a [Span] -/// specifying the [Source] and [Location] of the node. -/// -/// [Source]: crate::span::Source -/// [Location]: crate::span::Location -#[derive(Debug, Clone, PartialEq)] -pub struct Node { - /// The kind of node. - pub kind: NodeKind, - /// The span in which the node occurs. - pub span: Span, -} - -impl Node { - /// Construct a new instance of `Node`. - #[must_use] - pub const fn new(kind: NodeKind, span: Span) -> Self { - Self { kind, span } - } - - /// Push a child node onto a list node. - pub fn push_node(&mut self, child: Self) -> Result<(), ParserError> { - match &mut self.kind { - NodeKind::List(vec) - | NodeKind::Map(vec) - | NodeKind::Set(vec) - | NodeKind::Vector(vec) => { - vec.push(child); - } - _ => { - return Err(ParserError::new( - ParserErrorKind::UnexpectedState, - child.span, - )) - } - } - - Ok(()) - } - - #[cfg(not(tarpaulin_include))] - fn display(&self, indent: usize) -> String { - let mut text = format!( - "{}{}@{}..{}\n", - " ".repeat(indent), - self.kind, - self.span.bytes().start, - self.span.bytes().end - ); - - match &self.kind { - NodeKind::Atom(_) => {} - NodeKind::List(vec) - | NodeKind::Map(vec) - | NodeKind::Set(vec) - | NodeKind::Vector(vec) => { - for node in vec { - text.push_str(&format!("{}\n", node.display(indent + 1))); - } - } - } - - text.trim_end().to_string() - } -} - -impl TryFrom for Node { - type Error = ParserError; - - fn try_from(token: Token) -> Result { - let span = token.span.clone(); - let kind = NodeKind::try_from(token)?; - - Ok(Self::new(kind, span)) - } -} - -#[cfg(not(tarpaulin_include))] -impl std::fmt::Display for Node { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.display(0)) - } -} diff --git a/onihime/src/parser/error.rs b/onihime/src/parser/error.rs index 320f7f4..8c40333 100644 --- a/onihime/src/parser/error.rs +++ b/onihime/src/parser/error.rs @@ -5,19 +5,16 @@ use crate::{lexer::LexerError, span::Span}; pub enum ParserErrorKind { /// An error which ocurred during lexical analysis. Lexer(LexerError), - /// Expected a value for key in map, but no value was found. + /// Key in map is missing its corresponding value. MissingValueInMap, - /// An unexpecting closing parenthesis/brace/bracket was encountered. - UnexpectedCloseBracket, - /// Unexpectedly reached the end of the input. + /// Opening delimiter does not have a matching closing delimiter. + UnclosedSequence, + /// An unexpected closing delimiter was found. + UnexpectedClosingDelimiter, + /// Unexpectedly reached end of input. UnexpectedEof, - /// Unexpected parser state reached. - UnexpectedState, - /// Opening parenthesis/brace/bracket does not have a matching closing - /// parenthesis/brace/bracket. - UnclosedBracket, - /// An unmatched parenthesis/brace/bracket was encountered. - UnmatchedBracket, + /// An unmatched closing delimiter was found. + UnmatchedClosingDelimiter, } /// Parser error, with a start and end location. @@ -30,13 +27,20 @@ pub struct ParserError { } impl ParserError { - /// Construct a new instance of `ParserErorr`. + /// Construct a new instance of `ParserError`. #[must_use] pub const fn new(kind: ParserErrorKind, span: Span) -> Self { Self { kind, span } } } +impl From for ParserError { + fn from(err: LexerError) -> Self { + let span = err.span.clone(); + Self::new(ParserErrorKind::Lexer(err), span) + } +} + impl std::error::Error for ParserError {} #[cfg(not(tarpaulin_include))] @@ -46,19 +50,14 @@ impl std::fmt::Display for ParserError { match &self.kind { Lexer(err) => write!(f, "{err}"), - MissingValueInMap => write!(f, "Key in map is missing its value"), - UnexpectedCloseBracket => write!(f, "Unexpected closing bracket"), - UnexpectedEof => write!(f, "Unexpected reached end of input"), - UnexpectedState => write!(f, "Unexpected parsing state reached"), - UnclosedBracket => write!(f, "Unclosed bracket"), - UnmatchedBracket => write!(f, "Unmatched bracket"), + MissingValueInMap => write!(f, "Key in map is missing its corresponding value"), + UnclosedSequence => write!( + f, + "Opening delimiter does not have a matching closing delimiter" + ), + UnexpectedClosingDelimiter => write!(f, "An unexpected closing delimiter was found"), + UnexpectedEof => write!(f, "Unexpectedly reached end of input"), + UnmatchedClosingDelimiter => write!(f, "An unmatched closing delimiter was found"), } } } - -impl From for ParserError { - fn from(err: LexerError) -> Self { - let span = err.span.clone(); - Self::new(ParserErrorKind::Lexer(err), span) - } -} diff --git a/onihime/src/parser/mod.rs b/onihime/src/parser/mod.rs index c510c15..5defeb0 100644 --- a/onihime/src/parser/mod.rs +++ b/onihime/src/parser/mod.rs @@ -1,154 +1,154 @@ -pub use self::{ +use self::{ + ast::{Ast, Expr, Node}, error::{ParserError, ParserErrorKind}, - node::{Node, NodeKind}, }; -use crate::lexer::{Lexer, TokenKind}; +use crate::{ + lexer::{Lexer, TokenKind}, + span::Span, +}; +mod ast; mod error; -mod node; -/// Parser for converting Onihime source code into an Abstract Syntax Tree -/// (AST). -#[derive(Debug)] -pub struct Parser<'parser> { +pub(crate) struct Parser<'parser> { lexer: Lexer<'parser>, + parents: Vec, + current: Node, } impl<'parser> Parser<'parser> { /// Create a new parser instance from a string. #[must_use] - pub fn new(input: &'parser str) -> Self { + pub(crate) fn new(input: &'parser str) -> Self { + let lexer = Lexer::new(input); + let current = Node::new(Expr::List(Vec::new()), lexer.span()); + Self { - lexer: Lexer::new(input), + lexer, + parents: Vec::new(), + current, } } /// Set the name of the lexer's source. - pub fn set_name(&mut self, name: String) { + pub(crate) fn set_name(&mut self, name: String) { self.lexer.set_name(name); } - /// Parse the input string into an AST. - pub fn parse(&mut self) -> Result, ParserError> { - let mut parents = Vec::new(); - let mut cur_node = Node::new(NodeKind::List(Vec::new()), self.lexer.span()); - - while let Some(token) = self.lexer.read()? { - match token.kind { - TokenKind::BlockComment(_) | TokenKind::LineComment(_) => {} - - TokenKind::OpenParen => { - let child = Node::new(NodeKind::List(Vec::new()), token.span); - parents.push(cur_node); - cur_node = child; - } - TokenKind::CloseParen => { - let mut parent = parents.pop().ok_or_else(|| { - ParserError::new( - ParserErrorKind::UnexpectedCloseBracket, - token.span.clone(), - ) - })?; - - cur_node.span.extend(&token.span); - - if !matches!(cur_node.kind, NodeKind::List(_)) { - return Err(ParserError::new( - ParserErrorKind::UnmatchedBracket, - token.span, - )); - } - - parent.push_node(cur_node)?; - cur_node = parent; - } - - TokenKind::OpenBrace => { - let child = Node::new(NodeKind::Set(Vec::new()), token.span); - parents.push(cur_node); - cur_node = child; - } - TokenKind::OpenHashBrace => { - let child = Node::new(NodeKind::Map(Vec::new()), token.span); - parents.push(cur_node); - cur_node = child; - } - TokenKind::CloseBrace => { - let mut parent = parents.pop().ok_or_else(|| { - ParserError::new( - ParserErrorKind::UnexpectedCloseBracket, - token.span.clone(), - ) - })?; - - cur_node.span.extend(&token.span); - - if !matches!(cur_node.kind, NodeKind::Map(_) | NodeKind::Set(_)) { - return Err(ParserError::new( - ParserErrorKind::UnmatchedBracket, - token.span, - )); - } - - if let NodeKind::Map(ref vec) = cur_node.kind { - if vec.len() % 2 != 0 { - return Err(ParserError::new( - ParserErrorKind::MissingValueInMap, - token.span, - )); - } - } - - parent.push_node(cur_node)?; - cur_node = parent; - } - - TokenKind::OpenBracket => { - let child = Node::new(NodeKind::Vector(Vec::new()), token.span); - parents.push(cur_node); - cur_node = child; - } - TokenKind::CloseBracket => { - let mut parent = parents.pop().ok_or_else(|| { - ParserError::new( - ParserErrorKind::UnexpectedCloseBracket, - token.span.clone(), - ) - })?; - - cur_node.span.extend(&token.span); - - if !matches!(cur_node.kind, NodeKind::Vector(_)) { - return Err(ParserError::new( - ParserErrorKind::UnmatchedBracket, - token.span, - )); - } - - parent.push_node(cur_node)?; - cur_node = parent; - } - - _ => { - let node = Node::try_from(token)?; - cur_node.push_node(node)?; - } + /// Produce an Abstract Syntax Tree (AST) from the source input. + #[must_use] + pub(crate) fn parse(mut self) -> Result { + // This parser is actually quite simple!Recursively parse expressions until we + // run out of tokens, or an error occurs: + while !self.lexer.eof() { + if let Some(node) = self.expr()? { + self.current.push_node(node); } } - if !parents.is_empty() { + // When we reach the end of input, there should be no remaining parent nodes; if + // there are, that means that there is a missing closing delimiter somewhere: + if !self.parents.is_empty() { return Err(ParserError::new( - ParserErrorKind::UnclosedBracket, - cur_node.span, + ParserErrorKind::UnclosedSequence, + self.current.span, )); } - if let NodeKind::List(body) = cur_node.kind { - Ok(body) + // Since we created an initial `Expr::List` node to hold the parsed contents + // (i.e. so that we had something to push nodes to), we can now rip out its guts + // and return the newly constructed AST: + if let Expr::List(root) = self.current.kind { + Ok(Ast::new(root)) } else { - unreachable!() // In theory, at least... + unreachable!() // TODO: Is this really true? It should be... right? } } + + #[must_use] + fn expr(&mut self) -> Result, ParserError> { + if let Some(token) = self.lexer.read()? { + match token.kind { + // Comments are simply ignored by the parser: + TokenKind::BlockComment(_) | TokenKind::LineComment(_) => Ok(None), + + // Any valid opening delimiters begins a new sequence: + TokenKind::OpenParen => self.begin_sequence(Expr::List, token.span), + TokenKind::OpenHashBrace => self.begin_sequence(Expr::Map, token.span), + TokenKind::OpenBrace => self.begin_sequence(Expr::Set, token.span), + TokenKind::OpenBracket => self.begin_sequence(Expr::Vector, token.span), + + // Any valid closing delimiters end the current sequence: + kind + @ (TokenKind::CloseParen | TokenKind::CloseBrace | TokenKind::CloseBracket) => { + self.end_sequence(kind, token.span) + } + + // Atoms are pushed to the current sequence: + _ => { + let node = Node::try_from(token)?; + let span = node.span.clone(); + + self.current.push_node(node); + self.current.span.extend(&span); + + Ok(None) + } + } + } else { + Err(ParserError::new( + ParserErrorKind::UnexpectedEof, + self.lexer.span(), + )) + } + } + + #[must_use] + fn begin_sequence( + &mut self, + init: impl FnOnce(Vec) -> Expr, + span: Span, + ) -> Result, ParserError> { + self.current.span.extend(&span); + self.parents.push(self.current.clone()); + + self.current = Node::new(init(Vec::new()), span.clone()); + + Ok(None) + } + + #[must_use] + fn end_sequence(&mut self, kind: TokenKind, span: Span) -> Result, ParserError> { + // We will ultimately return the current expression, so clone it and update its + // span first: + let mut current = self.current.clone(); + current.span.extend(&span); + + // Update the parser's current node to the previous parent, or return an error + // if no parents exist: + self.current = self.parents.pop().ok_or_else(|| { + ParserError::new(ParserErrorKind::UnexpectedClosingDelimiter, span.clone()) + })?; + + // Ensure that the appropriate closing delimiter was found for our current node: + if current.kind.closing_delimiter() != Some(kind) { + return Err(ParserError::new( + ParserErrorKind::UnmatchedClosingDelimiter, + span, + )); + } + + // For maps, ensure that each key has a corresponding value: + match current.kind { + Expr::Map(ref vec) if vec.len() % 2 != 0 => { + return Err(ParserError::new(ParserErrorKind::MissingValueInMap, span)); + } + _ => {} + } + + // Finally, return the current node so it can be added to the AST: + Ok(Some(current)) + } } #[cfg(test)] @@ -156,8 +156,7 @@ mod tests { use super::*; use crate::{ lexer::{LexerError, LexerErrorKind, Symbol}, - parser::node::Atom, - span::Span, + parser::ast::Atom, }; macro_rules! test { @@ -171,7 +170,7 @@ mod tests { }; } - test!(empty: "", _src => Ok(vec![])); + test!(empty: "", _src => Ok(Ast::default())); test!(error_invalid_number: "(+ 1.2.3)", src => Err(ParserError::new( ParserErrorKind::Lexer(LexerError::new( @@ -181,35 +180,35 @@ mod tests { Span::new(3..8, src) ))); - test!(list: "(+ 1 2) ; sneaky comment :)", src => Ok(vec![ + test!(list: "(+ 1 2) ; sneaky comment :)", src => Ok(Ast::from(vec![ Node::new( - NodeKind::List(vec![ + Expr::List(vec![ Node::new(Atom::Symbol(Symbol::from("+")).into(), Span::new(1..2, src.clone())), Node::new(Atom::Integer(1).into(), Span::new(3..4, src.clone())), Node::new(Atom::Integer(2).into(), Span::new(5..6, src.clone())), ]), Span::new(0..7, src) ) - ])); + ]))); test!(error_list_unmatched_bracket: "(]", src => Err(ParserError::new( - ParserErrorKind::UnmatchedBracket, + ParserErrorKind::UnmatchedClosingDelimiter, Span::new(1..2, src), ))); test!(error_list_missing_close_paren: "(true", src => Err(ParserError::new( - ParserErrorKind::UnclosedBracket, - Span::new(0..1, src), + ParserErrorKind::UnclosedSequence, + Span::new(0..5, src), ))); test!(error_list_unexpected_close_paren: ")", src => Err(ParserError::new( - ParserErrorKind::UnexpectedCloseBracket, + ParserErrorKind::UnexpectedClosingDelimiter, Span::new(0..1, src) ))); - test!(map: "#{:a 0.0 :b 1.0}", src => Ok(vec![ + test!(map: "#{:a 0.0 :b 1.0}", src => Ok(Ast::from(vec![ Node::new( - NodeKind::Map(vec![ + Expr::Map(vec![ Node::new(Atom::Keyword(Symbol::from("a")).into(), Span::new(2..4, src.clone())), Node::new(Atom::Float(0.0).into(), Span::new(5..8, src.clone())), Node::new(Atom::Keyword(Symbol::from("b")).into(), Span::new(9..11, src.clone())), @@ -217,7 +216,7 @@ mod tests { ]), Span::new(0..16, src) ) - ])); + ]))); test!(error_map_missing_value: "#{:x}", src => Err(ParserError::new( ParserErrorKind::MissingValueInMap, @@ -225,74 +224,74 @@ mod tests { ))); test!(error_map_unmatched_bracket: "#{)", src => Err(ParserError::new( - ParserErrorKind::UnmatchedBracket, + ParserErrorKind::UnmatchedClosingDelimiter, Span::new(2..3, src), ))); test!(error_map_missing_close_brace: "#{", src => Err(ParserError::new( - ParserErrorKind::UnclosedBracket, + ParserErrorKind::UnclosedSequence, Span::new(0..2, src), ))); - test!(set: "{{} nil}", src => Ok(vec![ + test!(error_map_set_unexpected_close_brace: "}", src => Err(ParserError::new( + ParserErrorKind::UnexpectedClosingDelimiter, + Span::new(0..1, src) + ))); + + test!(set: "{{} nil}", src => Ok(Ast::from(vec![ Node::new( - NodeKind::Set(vec![ - Node::new(NodeKind::Set(vec![]), Span::new(1..3, src.clone())), - Node::new(NodeKind::Atom(Atom::Nil), Span::new(4..7, src.clone())), + Expr::Set(vec![ + Node::new(Expr::Set(vec![]), Span::new(1..3, src.clone())), + Node::new(Expr::Atom(Atom::Nil), Span::new(4..7, src.clone())), ]), Span::new(0..8, src), ) - ])); + ]))); test!(error_set_unmatched_bracket: "{]", src => Err(ParserError::new( - ParserErrorKind::UnmatchedBracket, + ParserErrorKind::UnmatchedClosingDelimiter, Span::new(1..2, src), ))); test!(error_set_missing_close_brace: "{", src => Err(ParserError::new( - ParserErrorKind::UnclosedBracket, + ParserErrorKind::UnclosedSequence, Span::new(0..1, src), ))); - test!(error_map_set_unexpected_close_brace: "}", src => Err(ParserError::new( - ParserErrorKind::UnexpectedCloseBracket, - Span::new(0..1, src) - ))); - - test!(vector: "['a' 'b' 'c']", src => Ok(vec![ + test!(vector: "['a' 'b' 'c']", src => Ok(Ast::from(vec![ Node::new( - NodeKind::Vector(vec![ - Node::new(NodeKind::Atom(Atom::Char('a')), Span::new(1..4, src.clone())), - Node::new(NodeKind::Atom(Atom::Char('b')), Span::new(5..8, src.clone())), - Node::new(NodeKind::Atom(Atom::Char('c')), Span::new(9..12, src.clone())), + Expr::Vector(vec![ + Node::new(Expr::Atom(Atom::Char('a')), Span::new(1..4, src.clone())), + Node::new(Expr::Atom(Atom::Char('b')), Span::new(5..8, src.clone())), + Node::new(Expr::Atom(Atom::Char('c')), Span::new(9..12, src.clone())), ]), Span::new(0..13, src), ) - ])); + ]))); test!(error_vector_unmatched_bracket: "[}", src => Err(ParserError::new( - ParserErrorKind::UnmatchedBracket, + ParserErrorKind::UnmatchedClosingDelimiter, Span::new(1..2, src), ))); - test!(error_vector_missing_close_bracket: "{", src => Err(ParserError::new( - ParserErrorKind::UnclosedBracket, + test!(error_vector_missing_close_bracket: "[", src => Err(ParserError::new( + ParserErrorKind::UnclosedSequence, Span::new(0..1, src), ))); test!(error_vector_unexpected_close_bracket: "]", src => Err(ParserError::new( - ParserErrorKind::UnexpectedCloseBracket, + ParserErrorKind::UnexpectedClosingDelimiter, Span::new(0..1, src) ))); - test!(multiple_expressions: "(/ 6 3 (+ 1 2)) (* 2 5)\n(- 10 5)", src => Ok(vec![ + test!(multiple_expressions: "(/ 6 3 (+ 1 2)) (* 2 5)\n(- 10 5)", src => Ok(Ast::from(vec![ Node::new( - NodeKind::List(vec![ + Expr::List(vec![ Node::new(Atom::Symbol(Symbol::from("/")).into(), Span::new(1..2, src.clone())), Node::new(Atom::Integer(6).into(), Span::new(3..4, src.clone())), Node::new(Atom::Integer(3).into(), Span::new(5..6, src.clone())), Node::new( - NodeKind::List(vec![ + Expr::List(vec![ Node::new(Atom::Symbol(Symbol::from("+")).into(), Span::new(8..9, src.clone())), Node::new(Atom::Integer(1).into(), Span::new(10..11, src.clone())), Node::new(Atom::Integer(2).into(), Span::new(12..13, src.clone())), @@ -303,7 +302,7 @@ mod tests { Span::new(0..15, src.clone()) ), Node::new( - NodeKind::List(vec![ + Expr::List(vec![ Node::new(Atom::Symbol(Symbol::from("*")).into(), Span::new(17..18, src.clone())), Node::new(Atom::Integer(2).into(), Span::new(19..20, src.clone())), Node::new(Atom::Integer(5).into(), Span::new(21..22, src.clone())), @@ -311,21 +310,21 @@ mod tests { Span::new(16..23, src.clone()) ), Node::new( - NodeKind::List(vec![ + Expr::List(vec![ Node::new(Atom::Symbol(Symbol::from("-")).into(), Span::new(25..26, src.clone())), Node::new(Atom::Integer(10).into(), Span::new(27..29, src.clone())), Node::new(Atom::Integer(5).into(), Span::new(30..31, src.clone())), ]), Span::new(24..32, src) ), - ])); + ]))); - test!(function_application: "(join \"foo\" \"bar\")", src => Ok(vec![Node::new( - NodeKind::List(vec![ + test!(function_application: "(join \"foo\" \"bar\")", src => Ok(Ast::from(vec![Node::new( + Expr::List(vec![ Node::new(Atom::Symbol(Symbol::from("join")).into(), Span::new(1..5, src.clone())), Node::new(Atom::String("foo".into()).into(), Span::new(6..11, src.clone())), Node::new(Atom::String("bar".into()).into(), Span::new(12..17, src.clone())), ]), Span::new(0..18, src) - )])); + )]))); }