From 62185ff0875b45a6da2c0a9564e35801d392ebf6 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 8 Mar 2024 20:30:26 -0500 Subject: [PATCH] Begin implementing ranges --- src/lexer.rs | 21 ++++++++++++++++++--- src/parser.rs | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/lexer.rs b/src/lexer.rs index 00a19ae..59f76e0 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -4,7 +4,7 @@ use chumsky::prelude::*; use crate::error::Error; -#[derive(Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq)] pub enum Token<'src> { Boolean(bool), Integer(i64), @@ -16,7 +16,7 @@ pub enum Token<'src> { Keyword(&'src str), } -#[derive(Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq)] pub enum Operator { Add, AddAssign, @@ -61,7 +61,7 @@ impl Display for Operator { } } -#[derive(Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq)] pub enum Control { CurlyOpen, CurlyClose, @@ -73,6 +73,7 @@ pub enum Control { DoubleColon, Colon, Dot, + DoubleDot, Semicolon, } @@ -89,6 +90,7 @@ impl Display for Control { Control::DoubleColon => write!(f, "::"), Control::Colon => write!(f, ":"), Control::Dot => write!(f, "."), + Control::DoubleDot => write!(f, ".."), Control::Semicolon => write!(f, ";"), } } @@ -202,6 +204,7 @@ pub fn lexer<'src>() -> impl Parser< just(";").padded().to(Control::Semicolon), just("::").padded().to(Control::DoubleColon), just(":").padded().to(Control::Colon), + just("..").padded().to(Control::DoubleDot), just(".").padded().to(Control::Dot), )) .map(Token::Control); @@ -234,6 +237,18 @@ pub fn lexer<'src>() -> impl Parser< mod tests { use super::*; + #[test] + fn range() { + assert_eq!( + lex("1..10").unwrap(), + vec![ + (Token::Integer(1), (0..1).into()), + (Token::Control(Control::DoubleDot), (1..3).into()), + (Token::Integer(10), (3..5).into()) + ] + ) + } + #[test] fn math_operators() { assert_eq!( diff --git a/src/parser.rs b/src/parser.rs index 246e4b1..3cb3e6d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -95,6 +95,18 @@ pub fn parser<'src>() -> DustParser<'src> { .map(|identifier| Expression::Identifier(identifier)) .boxed(); + let range = { + let raw_integer = select! { + Token::Integer(integer) => integer + }; + + raw_integer + .clone() + .then_ignore(just(Token::Control(Control::DoubleDot))) + .then(raw_integer) + .map(|(start, end)| Expression::Value(ValueNode::Range(start..end))) + }; + let list = expression .clone() .separated_by(just(Token::Control(Control::Comma))) @@ -201,6 +213,7 @@ pub fn parser<'src>() -> DustParser<'src> { .boxed(); choice(( + range, r#enum, logic_math_and_index, identifier_expression, @@ -314,6 +327,14 @@ mod tests { use super::*; + #[test] + fn range() { + assert_eq!( + parse(&lex("1..10").unwrap()).unwrap()[0].0, + Statement::Expression(Expression::Value(ValueNode::Range(1..10))) + ) + } + #[test] fn function() { assert_eq!(