diff --git a/dust-lang/src/lex.rs b/dust-lang/src/lex.rs index e1dd97f..e2664c5 100644 --- a/dust-lang/src/lex.rs +++ b/dust-lang/src/lex.rs @@ -1,16 +1,5 @@ use crate::{Identifier, Span, Token}; -#[derive(Debug, PartialEq, Clone)] -pub enum LexError { - IntegerParseError(std::num::ParseIntError), -} - -impl From for LexError { - fn from(v: std::num::ParseIntError) -> Self { - Self::IntegerParseError(v) - } -} - pub fn lex(input: &str) -> Result, LexError> { let mut lexer = Lexer::new(input); let mut tokens = Vec::new(); @@ -130,3 +119,85 @@ impl<'a> Lexer<'a> { Ok((token, (start_pos, self.position))) } } + +#[derive(Debug, PartialEq, Clone)] +pub enum LexError { + IntegerParseError(std::num::ParseIntError), +} + +impl From for LexError { + fn from(v: std::num::ParseIntError) -> Self { + Self::IntegerParseError(v) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn add() { + let input = "1 + 2"; + + assert_eq!( + lex(input), + Ok(vec![ + (Token::Integer(1), (0, 1)), + (Token::Plus, (2, 3)), + (Token::Integer(2), (4, 5)), + (Token::Eof, (5, 5)), + ]) + ) + } + + #[test] + fn multiply() { + let input = "1 * 2"; + + assert_eq!( + lex(input), + Ok(vec![ + (Token::Integer(1), (0, 1)), + (Token::Star, (2, 3)), + (Token::Integer(2), (4, 5)), + (Token::Eof, (5, 5)), + ]) + ) + } + + #[test] + fn add_and_multiply() { + let input = "1 + 2 * 3"; + + assert_eq!( + lex(input), + Ok(vec![ + (Token::Integer(1), (0, 1)), + (Token::Plus, (2, 3)), + (Token::Integer(2), (4, 5)), + (Token::Star, (6, 7)), + (Token::Integer(3), (8, 9)), + (Token::Eof, (9, 9)), + ]) + ); + } + + #[test] + fn assignment() { + let input = "a = 1 + 2 * 3"; + + assert_eq!( + lex(input,), + Ok(vec![ + (Token::Identifier(Identifier::new("a")), (0, 1)), + (Token::Equal, (2, 3)), + (Token::Integer(1), (4, 5)), + (Token::Plus, (6, 7)), + (Token::Integer(2), (8, 9)), + (Token::Star, (10, 11)), + (Token::Integer(3), (12, 13)), + (Token::Eof, (13, 13)), + ]) + ); + } +} diff --git a/dust-lang/src/parse.rs b/dust-lang/src/parse.rs index cddd35e..0f91674 100644 --- a/dust-lang/src/parse.rs +++ b/dust-lang/src/parse.rs @@ -4,6 +4,13 @@ use crate::{ Span, Token, Value, }; +pub fn parse(input: &str) -> Result<(Instruction, Span), ParseError> { + let lexer = Lexer::new(input); + let mut parser = Parser::new(lexer); + + parser.parse() +} + #[derive(Debug, PartialEq, Clone)] pub enum Instruction { Add(Box<(Instruction, Instruction)>), @@ -13,19 +20,6 @@ pub enum Instruction { Multiply(Box<(Instruction, Instruction)>), } -#[derive(Debug, PartialEq, Clone)] -pub enum ParseError { - LexError(LexError), - ExpectedClosingParenthesis, - UnexpectedToken(Token), -} - -impl From for ParseError { - fn from(v: LexError) -> Self { - Self::LexError(v) - } -} - pub struct Parser<'src> { lexer: Lexer<'src>, current: (Token, Span), @@ -137,20 +131,30 @@ impl<'src> Parser<'src> { } } +#[derive(Debug, PartialEq, Clone)] +pub enum ParseError { + LexError(LexError), + ExpectedClosingParenthesis, + UnexpectedToken(Token), +} + +impl From for ParseError { + fn from(v: LexError) -> Self { + Self::LexError(v) + } +} + #[cfg(test)] mod tests { - use crate::{identifier::Identifier, lex::lex, Value}; - use super::{Instruction, Lexer, Parser, Token}; + use super::*; #[test] fn add() { let input = "1 + 2"; - let lexer = Lexer::new(input); - let mut parser = Parser::new(lexer); assert_eq!( - parser.parse(), + parse(input), Ok(( Instruction::Add(Box::new(( Instruction::Constant(Value::integer(1)), @@ -164,11 +168,9 @@ mod tests { #[test] fn multiply() { let input = "1 * 2"; - let lexer = Lexer::new(input); - let mut parser = Parser::new(lexer); assert_eq!( - parser.parse(), + parse(input), Ok(( Instruction::Multiply(Box::new(( Instruction::Constant(Value::integer(1)), @@ -184,26 +186,7 @@ mod tests { let input = "1 + 2 * 3"; assert_eq!( - lex(input), - Ok(vec![ - (Token::Integer(1), (0, 1)), - (Token::Plus, (2, 3)), - (Token::Integer(2), (4, 5)), - (Token::Star, (6, 7)), - (Token::Integer(3), (8, 9)), - (Token::Eof, (9, 9)), - ]) - ); - } - - #[test] - fn parser() { - let input = "1 + 2 * 3"; - let lexer = Lexer::new(input); - let mut parser = Parser::new(lexer); - - assert_eq!( - parser.parse(), + parse(input), Ok(( Instruction::Add(Box::new(( Instruction::Constant(Value::integer(1)), @@ -220,11 +203,9 @@ mod tests { #[test] fn assignment() { let input = "a = 1 + 2 * 3"; - let lexer = Lexer::new(input); - let mut parser = Parser::new(lexer); assert_eq!( - parser.parse(), + parse(input), Ok(( Instruction::Assign(Box::new(( Instruction::Identifier(Identifier::new("a")),