feat(tazjin/rlox): Parse & interpret logical operators
Change-Id: I1a7d0eda61f7f077b820dc0d2c2516e204966962 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2324 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
This commit is contained in:
parent
93122a212e
commit
0a0335ae6c
2 changed files with 55 additions and 2 deletions
|
|
@ -23,6 +23,13 @@ pub struct Binary<'a> {
|
|||
pub right: Box<Expr<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Logical<'a> {
|
||||
pub left: Box<Expr<'a>>,
|
||||
pub operator: Token<'a>,
|
||||
pub right: Box<Expr<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Grouping<'a>(pub Box<Expr<'a>>);
|
||||
|
||||
|
|
@ -52,6 +59,7 @@ pub enum Expr<'a> {
|
|||
Literal(Literal),
|
||||
Unary(Unary<'a>),
|
||||
Variable(Variable<'a>),
|
||||
Logical(Logical<'a>),
|
||||
}
|
||||
|
||||
// Variable assignment. Not to be confused with `Variable`, which is
|
||||
|
|
@ -102,7 +110,9 @@ printStmt → "print" expression ";" ;
|
|||
|
||||
expression → assignment ;
|
||||
assignment → IDENTIFIER "=" assignment
|
||||
| equality ;
|
||||
| logic_or ;
|
||||
logic_or → logic_and ( "or" logic_and )* ;
|
||||
logic_and → equality ( "and" equality )* ;
|
||||
equality → comparison ( ( "!=" | "==" ) comparison )* ;
|
||||
comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
|
||||
term → factor ( ( "-" | "+" ) factor )* ;
|
||||
|
|
@ -222,7 +232,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
fn assignment(&mut self) -> ExprResult<'a> {
|
||||
let expr = self.equality()?;
|
||||
let expr = self.logic_or()?;
|
||||
|
||||
if self.match_token(&[TokenKind::Equal]) {
|
||||
let equals = self.previous().clone();
|
||||
|
|
@ -244,6 +254,34 @@ impl<'a> Parser<'a> {
|
|||
Ok(expr)
|
||||
}
|
||||
|
||||
fn logic_or(&mut self) -> ExprResult<'a> {
|
||||
let mut expr = self.logic_and()?;
|
||||
|
||||
while self.match_token(&[TokenKind::Or]) {
|
||||
expr = Expr::Logical(Logical {
|
||||
left: Box::new(expr),
|
||||
operator: self.previous().clone(),
|
||||
right: Box::new(self.logic_and()?),
|
||||
})
|
||||
}
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
fn logic_and(&mut self) -> ExprResult<'a> {
|
||||
let mut expr = self.equality()?;
|
||||
|
||||
while self.match_token(&[TokenKind::And]) {
|
||||
expr = Expr::Logical(Logical {
|
||||
left: Box::new(expr),
|
||||
operator: self.previous().clone(),
|
||||
right: Box::new(self.equality()?),
|
||||
})
|
||||
}
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
fn equality(&mut self) -> ExprResult<'a> {
|
||||
self.binary_operator(
|
||||
&[TokenKind::BangEqual, TokenKind::EqualEqual],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue