diff --git a/src/ast.rs b/src/ast.rs index d37c9b2..13b35d5 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -46,6 +46,14 @@ pub enum Expr { left: Box>, right: Box>, }, + RangeExclusive { + begin: Box>, + end: Box>, + }, + RangeInclusive { + begin: Box>, + end: Box>, + }, Assign { assign_type: AssignType, diff --git a/src/lexer.rs b/src/lexer.rs index 4e45450..9d35768 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -236,6 +236,8 @@ impl<'a> Lexer<'a> { self.step(); if !self.done() && self.current() == '.' { self.step_and_token(TokenType::DotDotDot, start) + } else if !self.done() && self.current() == '=' { + self.step_and_token(TokenType::DotDotEqual, start) } else { self.token(TokenType::DotDot, start) } diff --git a/src/main.rs b/src/main.rs index 9f9c0df..95bc199 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ fn main() { // }); // println!("]"); - let text2 = "[1, 2, ...a]"; + let text2 = "[1, 1..=2, ...a]"; let lexer2 = Lexer::new(text2); println!("tokens = ["); lexer2.for_each(|token| { diff --git a/src/parser.rs b/src/parser.rs index 231f94f..24593a9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -315,11 +315,11 @@ where } fn parse_prec_lt_lte_gt_gte_in(&mut self) -> Node { - let mut left = self.parse_prec_add_subtract(); + let mut left = self.parse_prec_range(); while !self.done() { if self.current_is(TokenType::LessThan) { self.step(); - let right = self.parse_prec_add_subtract(); + let right = self.parse_prec_range(); left = self.node(Expr::Binary { binary_type: BinaryType::LT, left: Box::new(left), @@ -327,7 +327,7 @@ where }); } else if self.current_is(TokenType::GreaterThan) { self.step(); - let right = self.parse_prec_add_subtract(); + let right = self.parse_prec_range(); left = self.node(Expr::Binary { binary_type: BinaryType::GT, left: Box::new(left), @@ -335,7 +335,7 @@ where }); } else if self.current_is(TokenType::LessThanEqual) { self.step(); - let right = self.parse_prec_add_subtract(); + let right = self.parse_prec_range(); left = self.node(Expr::Binary { binary_type: BinaryType::LTE, left: Box::new(left), @@ -343,7 +343,7 @@ where }); } else if self.current_is(TokenType::GreaterThanEqual) { self.step(); - let right = self.parse_prec_add_subtract(); + let right = self.parse_prec_range(); left = self.node(Expr::Binary { binary_type: BinaryType::GTE, left: Box::new(left), @@ -351,7 +351,7 @@ where }); } else if self.current_is(TokenType::In) { self.step(); - let right = self.parse_prec_add_subtract(); + let right = self.parse_prec_range(); left = self.node(Expr::Binary { binary_type: BinaryType::In, left: Box::new(left), @@ -364,6 +364,32 @@ where left } + fn parse_prec_range(&mut self) -> Node { + let begin = self.parse_prec_add_subtract(); + if self.done() { + return begin; + } + match self.current().token_type { + TokenType::DotDot => { + self.step(); + let end = self.parse_prec_add_subtract(); + self.node(Expr::RangeExclusive { + begin: Box::new(begin), + end: Box::new(end), + }) + } + TokenType::DotDotEqual => { + self.step(); + let end = self.parse_prec_add_subtract(); + self.node(Expr::RangeExclusive { + begin: Box::new(begin), + end: Box::new(end), + }) + } + _ => begin, + } + } + fn parse_prec_add_subtract(&mut self) -> Node { let mut left = self.parse_prec_multiply_divide_modulo(); while !self.done() { diff --git a/src/tokens.rs b/src/tokens.rs index 789fbdf..af7c1aa 100644 --- a/src/tokens.rs +++ b/src/tokens.rs @@ -75,6 +75,7 @@ pub enum TokenType { Semicolon, Ampersand, DotDot, + DotDotEqual, DotDotDot, EqualLessThan, }