-
Notifications
You must be signed in to change notification settings - Fork 675
Repeat expressions #28701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: mainnet
Are you sure you want to change the base?
Repeat expressions #28701
Conversation
3df9ec0
to
f8fad05
Compare
f8fad05
to
10c000c
Compare
10c000c
to
4eb1bfb
Compare
// Handle array with multiple elements: [expr1, expr2, ...] or single element with a trailing comma: [expr,] | ||
if self.eat(&Token::Comma) { | ||
let sep = Some(Token::Comma); | ||
let mut elements = vec![first_expr]; | ||
|
||
while !self.check(&close) { | ||
// Allow parser recovery by accepting optional expressions. | ||
if let Some(elem) = self.parse_expression().map(Some)? { | ||
elements.push(elem); | ||
} | ||
|
||
// If the separator is present, consume it; otherwise, exit loop. | ||
if sep.as_ref().filter(|sep| !self.eat(sep)).is_some() { | ||
break; | ||
} | ||
} | ||
|
||
let span = open_span + self.expect(&close)?; | ||
return Ok(ArrayExpression { elements, span, id: self.node_builder.next_id() }.into()); | ||
} | ||
|
||
// Single-element array with no trailing comma: [expr] | ||
let span = open_span + self.expect(&close)?; | ||
Ok(ArrayExpression { elements: vec![first_expr], span, id: self.node_builder.next_id() }.into()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Handle array with multiple elements: [expr1, expr2, ...] or single element with a trailing comma: [expr,] | |
if self.eat(&Token::Comma) { | |
let sep = Some(Token::Comma); | |
let mut elements = vec![first_expr]; | |
while !self.check(&close) { | |
// Allow parser recovery by accepting optional expressions. | |
if let Some(elem) = self.parse_expression().map(Some)? { | |
elements.push(elem); | |
} | |
// If the separator is present, consume it; otherwise, exit loop. | |
if sep.as_ref().filter(|sep| !self.eat(sep)).is_some() { | |
break; | |
} | |
} | |
let span = open_span + self.expect(&close)?; | |
return Ok(ArrayExpression { elements, span, id: self.node_builder.next_id() }.into()); | |
} | |
// Single-element array with no trailing comma: [expr] | |
let span = open_span + self.expect(&close)?; | |
Ok(ArrayExpression { elements: vec![first_expr], span, id: self.node_builder.next_id() }.into()) | |
// Handle array with multiple elements: [expr1, expr2, ...] or single element with or without trailing comma: [expr,] | |
let mut elements = vec![first_expr]; | |
while self.eat(&Token::Comma) && !self.check(&close) { | |
elements.push(self.parse_expression()?); | |
} | |
let span = open_span + self.expect(&close)?; | |
Ok(ArrayExpression { elements, span, id: self.node_builder.next_id() }.into()) |
@@ -340,6 +342,30 @@ impl CodeGeneratingVisitor<'_> { | |||
(member_access, String::new()) | |||
} | |||
|
|||
fn visit_repeat(&mut self, input: &RepeatExpression) -> (String, String) { | |||
let (operand, mut operand_instructions) = self.visit_expression(&input.expr); | |||
let count = input.count.as_u32().expect("repeat count should be known at this point"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only place unknown repeat counts are disallowed, so if I just have something like this:
transition main(x : u32) -> u32 {
let arr = [3u32; x];
return arr[0u32];
}
This expect
will be triggered.
I think probably the right way forward is for ConstPropagationOutput
to have a repeat_count_not_evaluated
item just like it has array_length_not_evaluated
and so on, and for the ConstPropagationAndUnrollingPass
to check it when it hits a fixed point just as it does for the others. And we should have a test with something like the main
function I wrote above that triggers this error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh absolutely, I did that for array types but forgot to do it here. Thanks for catching this.
@mikebenfield requested changes addressed in this commit: 1bb79ed |
Closes #28670
Also closes #28699
This PR adds repeat expression as in
[3u32; 4]
which is equivalent to[3u32, 3u32, 3u32, 3u32]
. Similarly to array type, the length (or count) is an expression that should evaluate to a constant at some point.Most change in this PR are fairly clear and straightforward. I still made the interpreter work with repeat expressions even though it's getting replaced soon.