Begin implementing ranges

This commit is contained in:
Jeff 2024-03-08 20:30:26 -05:00
parent a92074a77b
commit 62185ff087
2 changed files with 39 additions and 3 deletions

View File

@ -4,7 +4,7 @@ use chumsky::prelude::*;
use crate::error::Error; use crate::error::Error;
#[derive(Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
pub enum Token<'src> { pub enum Token<'src> {
Boolean(bool), Boolean(bool),
Integer(i64), Integer(i64),
@ -16,7 +16,7 @@ pub enum Token<'src> {
Keyword(&'src str), Keyword(&'src str),
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
pub enum Operator { pub enum Operator {
Add, Add,
AddAssign, AddAssign,
@ -61,7 +61,7 @@ impl Display for Operator {
} }
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
pub enum Control { pub enum Control {
CurlyOpen, CurlyOpen,
CurlyClose, CurlyClose,
@ -73,6 +73,7 @@ pub enum Control {
DoubleColon, DoubleColon,
Colon, Colon,
Dot, Dot,
DoubleDot,
Semicolon, Semicolon,
} }
@ -89,6 +90,7 @@ impl Display for Control {
Control::DoubleColon => write!(f, "::"), Control::DoubleColon => write!(f, "::"),
Control::Colon => write!(f, ":"), Control::Colon => write!(f, ":"),
Control::Dot => write!(f, "."), Control::Dot => write!(f, "."),
Control::DoubleDot => write!(f, ".."),
Control::Semicolon => 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::Semicolon),
just("::").padded().to(Control::DoubleColon), just("::").padded().to(Control::DoubleColon),
just(":").padded().to(Control::Colon), just(":").padded().to(Control::Colon),
just("..").padded().to(Control::DoubleDot),
just(".").padded().to(Control::Dot), just(".").padded().to(Control::Dot),
)) ))
.map(Token::Control); .map(Token::Control);
@ -234,6 +237,18 @@ pub fn lexer<'src>() -> impl Parser<
mod tests { mod tests {
use super::*; 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] #[test]
fn math_operators() { fn math_operators() {
assert_eq!( assert_eq!(

View File

@ -95,6 +95,18 @@ pub fn parser<'src>() -> DustParser<'src> {
.map(|identifier| Expression::Identifier(identifier)) .map(|identifier| Expression::Identifier(identifier))
.boxed(); .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 let list = expression
.clone() .clone()
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
@ -201,6 +213,7 @@ pub fn parser<'src>() -> DustParser<'src> {
.boxed(); .boxed();
choice(( choice((
range,
r#enum, r#enum,
logic_math_and_index, logic_math_and_index,
identifier_expression, identifier_expression,
@ -314,6 +327,14 @@ mod tests {
use super::*; use super::*;
#[test]
fn range() {
assert_eq!(
parse(&lex("1..10").unwrap()).unwrap()[0].0,
Statement::Expression(Expression::Value(ValueNode::Range(1..10)))
)
}
#[test] #[test]
fn function() { fn function() {
assert_eq!( assert_eq!(