feat(tazjin/rlox): Parse function calls
Change-Id: I1836c73dbfd5fc4ca30c2d22bbffee2fb222d566 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2366 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
This commit is contained in:
		
							parent
							
								
									2253617e0b
								
							
						
					
					
						commit
						f3c60865a3
					
				
					 2 changed files with 53 additions and 4 deletions
				
			
		| 
						 | 
					@ -190,6 +190,7 @@ impl Interpreter {
 | 
				
			||||||
            Expr::Binary(binary) => self.eval_binary(binary),
 | 
					            Expr::Binary(binary) => self.eval_binary(binary),
 | 
				
			||||||
            Expr::Variable(var) => self.get_var(var),
 | 
					            Expr::Variable(var) => self.get_var(var),
 | 
				
			||||||
            Expr::Logical(log) => self.eval_logical(log),
 | 
					            Expr::Logical(log) => self.eval_logical(log),
 | 
				
			||||||
 | 
					            Expr::Call(_) => unimplemented!(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,13 @@ pub struct Unary<'a> {
 | 
				
			||||||
    pub right: Box<Expr<'a>>,
 | 
					    pub right: Box<Expr<'a>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					pub struct Call<'a> {
 | 
				
			||||||
 | 
					    pub callee: Box<Expr<'a>>,
 | 
				
			||||||
 | 
					    pub paren: Token<'a>,
 | 
				
			||||||
 | 
					    pub args: Vec<Expr<'a>>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Not to be confused with `Var`, which is for assignment.
 | 
					// Not to be confused with `Var`, which is for assignment.
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub struct Variable<'a>(pub Token<'a>);
 | 
					pub struct Variable<'a>(pub Token<'a>);
 | 
				
			||||||
| 
						 | 
					@ -58,6 +65,7 @@ pub enum Expr<'a> {
 | 
				
			||||||
    Grouping(Grouping<'a>),
 | 
					    Grouping(Grouping<'a>),
 | 
				
			||||||
    Literal(Literal),
 | 
					    Literal(Literal),
 | 
				
			||||||
    Unary(Unary<'a>),
 | 
					    Unary(Unary<'a>),
 | 
				
			||||||
 | 
					    Call(Call<'a>),
 | 
				
			||||||
    Variable(Variable<'a>),
 | 
					    Variable(Variable<'a>),
 | 
				
			||||||
    Logical(Logical<'a>),
 | 
					    Logical(Logical<'a>),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -132,8 +140,9 @@ equality       → comparison ( ( "!=" | "==" ) comparison )* ;
 | 
				
			||||||
comparison     → term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
 | 
					comparison     → term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
 | 
				
			||||||
term           → factor ( ( "-" | "+" ) factor )* ;
 | 
					term           → factor ( ( "-" | "+" ) factor )* ;
 | 
				
			||||||
factor         → unary ( ( "/" | "*" ) unary )* ;
 | 
					factor         → unary ( ( "/" | "*" ) unary )* ;
 | 
				
			||||||
unary          → ( "!" | "-" ) unary
 | 
					unary          → ( "!" | "-" ) unary | call ;
 | 
				
			||||||
               | primary ;
 | 
					call           → primary ( "(" arguments? ")" )* ;
 | 
				
			||||||
 | 
					arguments      → expression ( "," expression )* ;
 | 
				
			||||||
primary        → NUMBER | STRING | "true" | "false" | "nil"
 | 
					primary        → NUMBER | STRING | "true" | "false" | "nil"
 | 
				
			||||||
               | "(" expression ")" ;
 | 
					               | "(" expression ")" ;
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
| 
						 | 
					@ -410,7 +419,46 @@ impl<'a> Parser<'a> {
 | 
				
			||||||
            }));
 | 
					            }));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return self.primary();
 | 
					        return self.call();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn call(&mut self) -> ExprResult<'a> {
 | 
				
			||||||
 | 
					        let mut expr = self.primary()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        loop {
 | 
				
			||||||
 | 
					            if self.match_token(&[TokenKind::LeftParen]) {
 | 
				
			||||||
 | 
					                expr = self.finish_call(expr)?;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(expr)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn finish_call(&mut self, callee: Expr<'a>) -> ExprResult<'a> {
 | 
				
			||||||
 | 
					        let mut args = vec![];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if !self.check_token(&TokenKind::RightParen) {
 | 
				
			||||||
 | 
					            loop {
 | 
				
			||||||
 | 
					                // TODO(tazjin): Check for max args count
 | 
				
			||||||
 | 
					                args.push(self.expression()?);
 | 
				
			||||||
 | 
					                if !self.match_token(&[TokenKind::Comma]) {
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let paren = self.consume(
 | 
				
			||||||
 | 
					            &TokenKind::RightParen,
 | 
				
			||||||
 | 
					            ErrorKind::ExpectedToken("Expect ')' after arguments."),
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(Expr::Call(Call {
 | 
				
			||||||
 | 
					            args,
 | 
				
			||||||
 | 
					            callee: Box::new(callee),
 | 
				
			||||||
 | 
					            paren,
 | 
				
			||||||
 | 
					        }))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn primary(&mut self) -> ExprResult<'a> {
 | 
					    fn primary(&mut self) -> ExprResult<'a> {
 | 
				
			||||||
| 
						 | 
					@ -482,7 +530,7 @@ impl<'a> Parser<'a> {
 | 
				
			||||||
        &self.tokens[self.current - 1]
 | 
					        &self.tokens[self.current - 1]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn consume(&mut self, kind: &TokenKind, err: ErrorKind) -> Result<Token, Error> {
 | 
					    fn consume(&mut self, kind: &TokenKind, err: ErrorKind) -> Result<Token<'a>, Error> {
 | 
				
			||||||
        if self.check_token(kind) {
 | 
					        if self.check_token(kind) {
 | 
				
			||||||
            return Ok(self.advance());
 | 
					            return Ok(self.advance());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue