-
Notifications
You must be signed in to change notification settings - Fork 199
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: optimize
Quoted::as_expr
by parsing just once (#6237)
# Description ## Problem Follow-up to the parser PR to avoid calling the parser three times in `Quoted::as_expr()` ## Summary This PR replaces `parse_lvalue_or_error`, which was only used in `Quoted::as_expr()`, with `parse_statement_or_expression_or_lvalue`, which is what `Quoted::as_expr()` needs. This avoids cloning the token stream, and also calls the parser just once. ## Additional Context ## Documentation Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Maxim Vezenov <mvezenov@gmail.com>
- Loading branch information
Showing
4 changed files
with
78 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
compiler/noirc_frontend/src/parser/parser/statement_or_expression_or_lvalue.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use crate::{ | ||
ast::{AssignStatement, Expression, LValue, Statement, StatementKind}, | ||
token::{Token, TokenKind}, | ||
}; | ||
|
||
use super::Parser; | ||
|
||
#[derive(Debug)] | ||
pub enum StatementOrExpressionOrLValue { | ||
Statement(Statement), | ||
Expression(Expression), | ||
LValue(LValue), | ||
} | ||
|
||
impl<'a> Parser<'a> { | ||
/// Parses either a statement, an expression or an LValue. Returns `StatementKind::Error` | ||
/// if none can be parsed, recording an error if so. | ||
/// | ||
/// This method is only used in `Quoted::as_expr`. | ||
pub(crate) fn parse_statement_or_expression_or_lvalue( | ||
&mut self, | ||
) -> StatementOrExpressionOrLValue { | ||
let start_span = self.current_token_span; | ||
|
||
// First check if it's an interned LValue | ||
if let Some(token) = self.eat_kind(TokenKind::InternedLValue) { | ||
match token.into_token() { | ||
Token::InternedLValue(lvalue) => { | ||
let lvalue = LValue::Interned(lvalue, self.span_since(start_span)); | ||
|
||
// If it is, it could be something like `lvalue = expr`: check that. | ||
if self.eat(Token::Assign) { | ||
let expression = self.parse_expression_or_error(); | ||
let kind = StatementKind::Assign(AssignStatement { lvalue, expression }); | ||
return StatementOrExpressionOrLValue::Statement(Statement { | ||
kind, | ||
span: self.span_since(start_span), | ||
}); | ||
} else { | ||
return StatementOrExpressionOrLValue::LValue(lvalue); | ||
} | ||
} | ||
_ => unreachable!(), | ||
} | ||
} | ||
|
||
// Otherwise, check if it's a statement (which in turn checks if it's an expression) | ||
let statement = self.parse_statement_or_error(); | ||
if let StatementKind::Expression(expr) = statement.kind { | ||
StatementOrExpressionOrLValue::Expression(expr) | ||
} else { | ||
StatementOrExpressionOrLValue::Statement(statement) | ||
} | ||
} | ||
} |