From 73e25a571f12d3deaa6f4493a5b4792a9dae39eb Mon Sep 17 00:00:00 2001 From: johannst Date: Sat, 24 Sep 2022 22:38:40 +0000 Subject: deploy: 295081130ca1eed6e67dfc035e2df2c9ed49b174 --- src/llvm_kaleidoscope_rs/parser.rs.html | 682 +++++++++++++++++++++++++------- 1 file changed, 537 insertions(+), 145 deletions(-) (limited to 'src/llvm_kaleidoscope_rs/parser.rs.html') diff --git a/src/llvm_kaleidoscope_rs/parser.rs.html b/src/llvm_kaleidoscope_rs/parser.rs.html index 9093695..d3c9594 100644 --- a/src/llvm_kaleidoscope_rs/parser.rs.html +++ b/src/llvm_kaleidoscope_rs/parser.rs.html @@ -1,102 +1,108 @@ -parser.rs - source
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
+parser.rs - source
+    
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
 100
 101
 102
@@ -458,8 +464,201 @@
 458
 459
 460
-
-use crate::lexer::{Lexer, Token};
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+
use crate::lexer::{Lexer, Token};
 
 #[derive(Debug, PartialEq)]
 pub enum ExprAST {
@@ -474,6 +673,22 @@
 
     /// Call - Expression class for function calls.
     Call(String, Vec<ExprAST>),
+
+    /// If - Expression class for if/then/else.
+    If {
+        cond: Box<ExprAST>,
+        then: Box<ExprAST>,
+        else_: Box<ExprAST>,
+    },
+
+    /// ForExprAST - Expression class for for/in.
+    For {
+        var: String,
+        start: Box<ExprAST>,
+        end: Box<ExprAST>,
+        step: Option<Box<ExprAST>>,
+        body: Box<ExprAST>,
+    },
 }
 
 /// PrototypeAST - This class represents the "prototype" for a function,
@@ -502,7 +717,7 @@
 where
     I: Iterator<Item = char>,
 {
-    pub fn new(lexer: Lexer<I>) -> Self {
+    pub fn new(lexer: Lexer<I>) -> Self {
         Parser {
             lexer,
             cur_tok: None,
@@ -517,14 +732,14 @@
     ///
     /// # Panics
     /// Panics if the parser doesn't have a current token.
-    pub fn cur_tok(&self) -> &Token {
+    pub fn cur_tok(&self) -> &Token {
         self.cur_tok.as_ref().expect("Parser: Expected cur_token!")
     }
 
     /// Advance the `cur_tok` by getting the next token from the lexer.
     ///
     /// Implement the fucntion `int getNextToken();` from the tutorial.
-    pub fn get_next_token(&mut self) {
+    pub fn get_next_token(&mut self) {
         self.cur_tok = Some(self.lexer.gettok());
     }
 
@@ -535,28 +750,28 @@
     /// numberexpr ::= number
     ///
     /// Implement `std::unique_ptr<ExprAST> ParseNumberExpr();` from the tutorial.
-    fn parse_num_expr(&mut self) -> ParseResult<ExprAST> {
+    fn parse_num_expr(&mut self) -> ParseResult<ExprAST> {
         match *self.cur_tok() {
-            Token::Number(num) => {
+            Token::Number(num) => {
                 // Consume the number token.
                 self.get_next_token();
                 Ok(ExprAST::Number(num))
             }
-            _ => unreachable!(),
+            _ => unreachable!(),
         }
     }
 
     /// parenexpr ::= '(' expression ')'
     ///
     /// Implement `std::unique_ptr<ExprAST> ParseParenExpr();` from the tutorial.
-    fn parse_paren_expr(&mut self) -> ParseResult<ExprAST> {
+    fn parse_paren_expr(&mut self) -> ParseResult<ExprAST> {
         // Eat '(' token.
         assert_eq!(*self.cur_tok(), Token::Char('('));
         self.get_next_token();
 
         let v = self.parse_expression()?;
 
-        if *self.cur_tok() == Token::Char(')') {
+        if *self.cur_tok() == Token::Char(')') {
             // Eat ')' token.
             self.get_next_token();
             Ok(v)
@@ -570,14 +785,14 @@
     ///   ::= identifier '(' expression* ')'
     ///
     /// Implement `std::unique_ptr<ExprAST> ParseIdentifierExpr();` from the tutorial.
-    fn parse_identifier_expr(&mut self) -> ParseResult<ExprAST> {
+    fn parse_identifier_expr(&mut self) -> ParseResult<ExprAST> {
         let id_name = match self.cur_tok.take() {
-            Some(Token::Identifier(id)) => {
+            Some(Token::Identifier(id)) => {
                 // Consume identifier.
                 self.get_next_token();
                 id
             }
-            _ => unreachable!(),
+            _ => unreachable!(),
         };
 
         if *self.cur_tok() != Token::Char('(') {
@@ -597,9 +812,7 @@
                     let arg = self.parse_expression()?;
                     args.push(arg);
 
-                    if *self.cur_tok() == Token::Char(')') {
-                        // Eat ')' token.
-                        self.get_next_token();
+                    if *self.cur_tok() == Token::Char(')') {
                         break;
                     }
 
@@ -611,22 +824,119 @@
                 }
             }
 
+            assert_eq!(*self.cur_tok(), Token::Char(')'));
+            // Eat ')' token.
+            self.get_next_token();
+
             Ok(ExprAST::Call(id_name, args))
         }
     }
 
+    /// ifexpr ::= 'if' expression 'then' expression 'else' expression
+    ///
+    /// Implement `std::unique_ptr<ExprAST> ParseIfExpr();` from the tutorial.
+    fn parse_if_expr(&mut self) -> ParseResult<ExprAST> {
+        // Consume 'if' token.
+        assert_eq!(*self.cur_tok(), Token::If);
+        self.get_next_token();
+
+        let cond = self.parse_expression()?;
+
+        if *dbg!(self.cur_tok()) != Token::Then {
+            return Err("Expected 'then'".into());
+        }
+        // Consume 'then' token.
+        self.get_next_token();
+
+        let then = self.parse_expression()?;
+
+        if *self.cur_tok() != Token::Else {
+            return Err("Expected 'else'".into());
+        }
+        // Consume 'else' token.
+        self.get_next_token();
+
+        let else_ = self.parse_expression()?;
+
+        Ok(ExprAST::If {
+            cond: Box::new(cond),
+            then: Box::new(then),
+            else_: Box::new(else_),
+        })
+    }
+
+    /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
+    ///
+    /// Implement `std::unique_ptr<ExprAST> ParseForExpr();` from the tutorial.
+    fn parse_for_expr(&mut self) -> ParseResult<ExprAST> {
+        // Consume the 'for' token.
+        assert_eq!(*self.cur_tok(), Token::For);
+        self.get_next_token();
+
+        let var = match self
+            .parse_identifier_expr()
+            .map_err(|_| String::from("expected identifier after 'for'"))?
+        {
+            ExprAST::Variable(var) => var,
+            _ => unreachable!(),
+        };
+
+        // Consume the '=' token.
+        if *self.cur_tok() != Token::Char('=') {
+            return Err("expected '=' after for".into());
+        }
+        self.get_next_token();
+
+        let start = self.parse_expression()?;
+
+        // Consume the ',' token.
+        if *self.cur_tok() != Token::Char(',') {
+            return Err("expected ',' after for start value".into());
+        }
+        self.get_next_token();
+
+        let end = self.parse_expression()?;
+
+        let step = if *self.cur_tok() == Token::Char(',') {
+            // Consume the ',' token.
+            self.get_next_token();
+
+            Some(self.parse_expression()?)
+        } else {
+            None
+        };
+
+        // Consume the 'in' token.
+        if *self.cur_tok() != Token::In {
+            return Err("expected 'in' after for".into());
+        }
+        self.get_next_token();
+
+        let body = self.parse_expression()?;
+
+        Ok(ExprAST::For {
+            var,
+            start: Box::new(start),
+            end: Box::new(end),
+            step: step.map(|s| Box::new(s)),
+            body: Box::new(body),
+        })
+    }
+
     /// primary
     ///   ::= identifierexpr
     ///   ::= numberexpr
     ///   ::= parenexpr
     ///
     /// Implement `std::unique_ptr<ExprAST> ParsePrimary();` from the tutorial.
-    fn parse_primary(&mut self) -> ParseResult<ExprAST> {
+    fn parse_primary(&mut self) -> ParseResult<ExprAST> {
         match *self.cur_tok() {
-            Token::Identifier(_) => self.parse_identifier_expr(),
-            Token::Number(_) => self.parse_num_expr(),
-            Token::Char('(') => self.parse_paren_expr(),
-            _ => Err("unknown token when expecting an expression".into()),
+            Token::Identifier(_) => self.parse_identifier_expr(),
+            Token::Number(_) => self.parse_num_expr(),
+            Token::Char('(') => self.parse_paren_expr(),
+            Token::If => self.parse_if_expr(),
+            Token::For => self.parse_for_expr(),
+            _ => Err("unknown token when expecting an expression".into()),
         }
     }
 
@@ -638,7 +948,7 @@
     ///   ::= primary binoprhs
     ///
     /// Implement `std::unique_ptr<ExprAST> ParseExpression();` from the tutorial.
-    fn parse_expression(&mut self) -> ParseResult<ExprAST> {
+    fn parse_expression(&mut self) -> ParseResult<ExprAST> {
         let lhs = self.parse_primary()?;
         self.parse_bin_op_rhs(0, lhs)
     }
@@ -647,7 +957,7 @@
     ///   ::= ('+' primary)*
     ///
     /// Implement `std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS);` from the tutorial.
-    fn parse_bin_op_rhs(&mut self, expr_prec: isize, mut lhs: ExprAST) -> ParseResult<ExprAST> {
+    fn parse_bin_op_rhs(&mut self, expr_prec: isize, mut lhs: ExprAST) -> ParseResult<ExprAST> {
         loop {
             let tok_prec = get_tok_precedence(self.cur_tok());
 
@@ -657,12 +967,12 @@
             }
 
             let binop = match self.cur_tok.take() {
-                Some(Token::Char(c)) => {
+                Some(Token::Char(c)) => {
                     // Eat binary operator.
                     self.get_next_token();
                     c
                 }
-                _ => unreachable!(),
+                _ => unreachable!(),
             };
 
             // lhs BINOP1 rhs BINOP2 remrhs
@@ -696,14 +1006,14 @@
     ///   ::= id '(' id* ')'
     ///
     /// Implement `std::unique_ptr<PrototypeAST> ParsePrototype();` from the tutorial.
-    fn parse_prototype(&mut self) -> ParseResult<PrototypeAST> {
+    fn parse_prototype(&mut self) -> ParseResult<PrototypeAST> {
         let id_name = match self.cur_tok.take() {
-            Some(Token::Identifier(id)) => {
+            Some(Token::Identifier(id)) => {
                 // Consume the identifier.
                 self.get_next_token();
                 id
             }
-            other => {
+            other => {
                 // Plug back current token.
                 self.cur_tok = other;
                 return Err("Expected function name in prototype".into());
@@ -719,9 +1029,9 @@
             self.get_next_token();
 
             match self.cur_tok.take() {
-                Some(Token::Identifier(arg)) => args.push(arg),
-                Some(Token::Char(',')) => {}
-                other => {
+                Some(Token::Identifier(arg)) => args.push(arg),
+                Some(Token::Char(',')) => {}
+                other => {
                     self.cur_tok = other;
                     break;
                 }
@@ -741,7 +1051,7 @@
     /// definition ::= 'def' prototype expression
     ///
     /// Implement `std::unique_ptr<FunctionAST> ParseDefinition();` from the tutorial.
-    pub fn parse_definition(&mut self) -> ParseResult<FunctionAST> {
+    pub fn parse_definition(&mut self) -> ParseResult<FunctionAST> {
         // Consume 'def' token.
         assert_eq!(*self.cur_tok(), Token::Def);
         self.get_next_token();
@@ -755,7 +1065,7 @@
     /// external ::= 'extern' prototype
     ///
     /// Implement `std::unique_ptr<PrototypeAST> ParseExtern();` from the tutorial.
-    pub fn parse_extern(&mut self) -> ParseResult<PrototypeAST> {
+    pub fn parse_extern(&mut self) -> ParseResult<PrototypeAST> {
         // Consume 'extern' token.
         assert_eq!(*self.cur_tok(), Token::Extern);
         self.get_next_token();
@@ -766,7 +1076,7 @@
     /// toplevelexpr ::= expression
     ///
     /// Implement `std::unique_ptr<FunctionAST> ParseTopLevelExpr();` from the tutorial.
-    pub fn parse_top_level_expr(&mut self) -> ParseResult<FunctionAST> {
+    pub fn parse_top_level_expr(&mut self) -> ParseResult<FunctionAST> {
         let e = self.parse_expression()?;
         let proto = PrototypeAST("__anon_expr".into(), Vec::new());
         Ok(FunctionAST(proto, e))
@@ -776,22 +1086,22 @@
 /// Get the binary operator precedence.
 ///
 /// Implement `int GetTokPrecedence();` from the tutorial.
-fn get_tok_precedence(tok: &Token) -> isize {
+fn get_tok_precedence(tok: &Token) -> isize {
     match tok {
-        Token::Char('<') => 10,
-        Token::Char('+') => 20,
-        Token::Char('-') => 20,
-        Token::Char('*') => 40,
-        _ => -1,
+        Token::Char('<') => 10,
+        Token::Char('+') => 20,
+        Token::Char('-') => 20,
+        Token::Char('*') => 40,
+        _ => -1,
     }
 }
 
 #[cfg(test)]
 mod test {
     use super::{ExprAST, FunctionAST, Parser, PrototypeAST};
-    use crate::lexer::Lexer;
+    use crate::lexer::Lexer;
 
-    fn parser(input: &str) -> Parser<std::str::Chars> {
+    fn parser(input: &str) -> Parser<std::str::Chars> {
         let l = Lexer::new(input.chars());
         let mut p = Parser::new(l);
 
@@ -818,9 +1128,72 @@
         );
     }
 
+    #[test]
+    fn parse_if() {
+        let mut p = parser("if 1 then 2 else 3");
+
+        let cond = Box::new(ExprAST::Number(1f64));
+        let then = Box::new(ExprAST::Number(2f64));
+        let else_ = Box::new(ExprAST::Number(3f64));
+
+        assert_eq!(p.parse_if_expr(), Ok(ExprAST::If { cond, then, else_ }));
+
+        let mut p = parser("if foo() then bar(2) else baz(3)");
+
+        let cond = Box::new(ExprAST::Call("foo".into(), vec![]));
+        let then = Box::new(ExprAST::Call("bar".into(), vec![ExprAST::Number(2f64)]));
+        let else_ = Box::new(ExprAST::Call("baz".into(), vec![ExprAST::Number(3f64)]));
+
+        assert_eq!(p.parse_if_expr(), Ok(ExprAST::If { cond, then, else_ }));
+    }
+
+    #[test]
+    fn parse_for() {
+        let mut p = parser("for i = 1, 2, 3 in 4");
+
+        let var = String::from("i");
+        let start = Box::new(ExprAST::Number(1f64));
+        let end = Box::new(ExprAST::Number(2f64));
+        let step = Some(Box::new(ExprAST::Number(3f64)));
+        let body = Box::new(ExprAST::Number(4f64));
+
+        assert_eq!(
+            p.parse_for_expr(),
+            Ok(ExprAST::For {
+                var,
+                start,
+                end,
+                step,
+                body
+            })
+        );
+    }
+
+    #[test]
+    fn parse_for_no_step() {
+        let mut p = parser("for i = 1, 2 in 4");
+
+        let var = String::from("i");
+        let start = Box::new(ExprAST::Number(1f64));
+        let end = Box::new(ExprAST::Number(2f64));
+        let step = None;
+        let body = Box::new(ExprAST::Number(4f64));
+
+        assert_eq!(
+            p.parse_for_expr(),
+            Ok(ExprAST::For {
+                var,
+                start,
+                end,
+                step,
+                body
+            })
+        );
+    }
+
     #[test]
     fn parse_primary() {
-        let mut p = parser("1337 foop \n bla(123)");
+        let mut p = parser("1337 foop \n bla(123) \n if a then b else c \n for x=1,2 in 3");
 
         assert_eq!(p.parse_primary(), Ok(ExprAST::Number(1337f64)));
 
@@ -830,6 +1203,26 @@
             p.parse_primary(),
             Ok(ExprAST::Call("bla".into(), vec![ExprAST::Number(123f64)]))
         );
+
+        assert_eq!(
+            p.parse_primary(),
+            Ok(ExprAST::If {
+                cond: Box::new(ExprAST::Variable("a".into())),
+                then: Box::new(ExprAST::Variable("b".into())),
+                else_: Box::new(ExprAST::Variable("c".into())),
+            })
+        );
+
+        assert_eq!(
+            p.parse_primary(),
+            Ok(ExprAST::For {
+                var: String::from("x"),
+                start: Box::new(ExprAST::Number(1f64)),
+                end: Box::new(ExprAST::Number(2f64)),
+                step: None,
+                body: Box::new(ExprAST::Number(3f64)),
+            })
+        );
     }
 
     #[test]
@@ -919,7 +1312,6 @@
         assert_eq!(p.parse_extern(), Ok(proto));
     }
 }
-
-
- +
+
\ No newline at end of file -- cgit v1.2.3