diff --git a/src/lexer.rs b/src/lexer.rs index 361fd16..2da5496 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -44,10 +44,14 @@ pub fn lexer<'src>() -> impl Parser< let integer = just('-') .or_not() - .then(text::int(10).padded()) + .then(text::int(10)) .to_slice() .map(|text: &str| { - let integer = text.parse::().unwrap(); + let integer = if let Ok(integer) = text.parse::() { + integer + } else { + panic!("Failed to parse {text} as integer."); + }; Token::Integer(integer) }); diff --git a/src/parser.rs b/src/parser.rs index 4101d4f..83d1dd9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -120,7 +120,15 @@ fn parser<'tokens, 'src: 'tokens>() -> impl Parser< }) .boxed(); - choice([assignment, expression_statement]) + let block = statement + .clone() + .separated_by(just(Token::Control(";")).or_not()) + .collect() + .delimited_by(just(Token::Control("{")), just(Token::Control("}"))) + .map(|statements| Statement::Block(Block::new(statements))) + .boxed(); + + choice([assignment, expression_statement, block]) }); statement @@ -144,6 +152,57 @@ mod tests { use super::*; + #[test] + fn block() { + assert_eq!( + parse(&lex("{ x }").unwrap()).unwrap()[0].0, + Statement::Block(Block::new(vec![Statement::Expression( + Expression::Identifier(Identifier::new("x")) + ),])) + ); + + assert_eq!( + parse( + &lex(" + { + x; + y; + z + } + ") + .unwrap() + ) + .unwrap()[0] + .0, + Statement::Block(Block::new(vec![ + Statement::Expression(Expression::Identifier(Identifier::new("x"))), + Statement::Expression(Expression::Identifier(Identifier::new("y"))), + Statement::Expression(Expression::Identifier(Identifier::new("z"))), + ])) + ); + + assert_eq!( + parse( + &lex(" + { + 1 == 1 + z + } + ") + .unwrap() + ) + .unwrap()[0] + .0, + Statement::Block(Block::new(vec![ + Statement::Expression(Expression::Logic(Box::new(Logic::Equal( + Expression::Value(ValueNode::Integer(1)), + Expression::Value(ValueNode::Integer(1)) + )))), + Statement::Expression(Expression::Identifier(Identifier::new("z"))), + ])) + ); + } + #[test] fn identifier() { assert_eq!(