From b6e33d381093ca2b52d67ce11f3d695d9f291881 Mon Sep 17 00:00:00 2001
From: SimonFJ20 <simonfromjakobsen@gmail.com>
Date: Thu, 16 Mar 2023 08:48:58 +0100
Subject: [PATCH] add ranges

---
 src/ast.rs    |  8 ++++++++
 src/lexer.rs  |  2 ++
 src/main.rs   |  2 +-
 src/parser.rs | 38 ++++++++++++++++++++++++++++++++------
 src/tokens.rs |  1 +
 5 files changed, 44 insertions(+), 7 deletions(-)

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<Node<Expr>>,
         right: Box<Node<Expr>>,
     },
+    RangeExclusive {
+        begin: Box<Node<Expr>>,
+        end: Box<Node<Expr>>,
+    },
+    RangeInclusive {
+        begin: Box<Node<Expr>>,
+        end: Box<Node<Expr>>,
+    },
 
     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<Expr> {
-        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<Expr> {
+        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<Expr> {
         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,
 }