diff --git a/src/protocol/parser/pass_definitions.rs b/src/protocol/parser/pass_definitions.rs index af7df9289e33d4f14b041012aed4b6d3581b76fe..885c5aa4a83626d35fed98fa687fed9be50e92ff 100644 --- a/src/protocol/parser/pass_definitions.rs +++ b/src/protocol/parser/pass_definitions.rs @@ -487,7 +487,8 @@ impl PassDefinitions { // Two fallback possibilities: the first one is a memory // declaration, the other one is to parse it as a normal // expression. This is a bit ugly. - if let Some((memory_stmt_id, assignment_stmt_id)) = self.maybe_consume_memory_statement(module, iter, ctx)? { + if let Some((memory_stmt_id, assignment_stmt_id)) = self.maybe_consume_memory_statement_without_semicolon(module, iter, ctx)? { + consume_token(&module.source, iter, TokenKind::SemiColon)?; section.push(memory_stmt_id.upcast().upcast()); section.push(assignment_stmt_id.upcast()); } else { @@ -497,7 +498,8 @@ impl PassDefinitions { } } else if next == TokenKind::OpenParen { // Same as above: memory statement or normal expression - if let Some((memory_stmt_id, assignment_stmt_id)) = self.maybe_consume_memory_statement(module, iter, ctx)? { + if let Some((memory_stmt_id, assignment_stmt_id)) = self.maybe_consume_memory_statement_without_semicolon(module, iter, ctx)? { + consume_token(&module.source, iter, TokenKind::SemiColon); section.push(memory_stmt_id.upcast().upcast()); section.push(assignment_stmt_id.upcast()); } else { @@ -691,28 +693,34 @@ impl PassDefinitions { consume_token(&module.source, iter, TokenKind::OpenCurly)?; let mut cases = Vec::new(); - consume_comma_separated_until( - TokenKind::CloseCurly, &module.source, iter, ctx, - |source, iter, ctx| { - // A select arm starts with a guard, being something of the form - // `defined_var = get(port)`, `get(port)` or - // `Type var = get(port)`. So: - let (guard_var, guard_expr) = match self.maybe_consume_memory_statement(module, iter, ctx)? { - Some((guard_var, guard_expr)) => { - (Some(guard_var), guard_expr) - }, - None => { - let guard_expr = self.consume_expression_statement(module, iter, ctx)?; - (None, guard_expr) - }, - }; - consume_token(source, iter, TokenKind::ArrowRight)?; - let block = self.consume_block_or_wrapped_statement(module, iter, ctx)?; + let mut next = iter.next(); - Ok(SelectCase{ guard_var, guard_expr, block }) - }, - &mut cases, "select arm", None - )?; + while Some(TokenKind::CloseCurly) != next { + let (guard_var, guard_expr) = match self.maybe_consume_memory_statement_without_semicolon(module, iter, ctx)? { + Some(guard_var_and_expr) => guard_var_and_expr, + None => { + let start_pos = iter.last_valid_pos(); + let expr = self.consume_expression(module, iter, ctx)?; + let end_pos = iter.last_valid_pos(); + + let guard_expr = ctx.heap.alloc_expression_statement(|this| ExpressionStatement{ + this, + span: InputSpan::from_positions(start_pos, end_pos), + expression: expr, + next: StatementId::new_invalid(), + }); + + (MemoryStatementId::new_invalid(), guard_expr) + }, + }; + consume_token(&module.source, iter, TokenKind::ArrowRight)?; + let block = self.consume_block_or_wrapped_statement(module, iter, ctx)?; + cases.push(SelectCase{ guard_var, guard_expr, block }); + + next = iter.next(); + } + + consume_token(&module.source, iter, TokenKind::CloseCurly)?; Ok(ctx.heap.alloc_select_statement(|this| SelectStatement{ this, @@ -917,7 +925,7 @@ impl PassDefinitions { Ok(()) } - fn maybe_consume_memory_statement( + fn maybe_consume_memory_statement_without_semicolon( &mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx ) -> Result, ParseError> { // This is a bit ugly. It would be nicer if we could somehow @@ -942,7 +950,6 @@ impl PassDefinitions { let initial_expr_begin_pos = iter.last_valid_pos(); let initial_expr_id = self.consume_expression(module, iter, ctx)?; let initial_expr_end_pos = iter.last_valid_pos(); - consume_token(&module.source, iter, TokenKind::SemiColon)?; // Allocate the memory statement with the variable let local_id = ctx.heap.alloc_variable(|this| Variable{