diff --git a/src/protocol/parser/pass_definitions.rs b/src/protocol/parser/pass_definitions.rs index 3b0d9abe5004eb827700c49d090cd32e560feba1..383d76f7d9ac00efcd9ea11af1bff108e3bcb3cb 100644 --- a/src/protocol/parser/pass_definitions.rs +++ b/src/protocol/parser/pass_definitions.rs @@ -339,29 +339,9 @@ impl PassDefinitions { // Consume if statement and place end-if statement directly // after it. let id = self.consume_if_statement(module, iter, ctx)?; - - let end_if = ctx.heap.alloc_end_if_statement(|this| EndIfStatement { - this, - start_if: id, - next: StatementId::new_invalid() - }); - - let if_stmt = &mut ctx.heap[id]; - if_stmt.end_if = end_if; - return Ok(id.upcast()); } else if ident == KW_STMT_WHILE { let id = self.consume_while_statement(module, iter, ctx)?; - - let end_while = ctx.heap.alloc_end_while_statement(|this| EndWhileStatement { - this, - start_while: id, - next: StatementId::new_invalid() - }); - - let while_stmt = &mut ctx.heap[id]; - while_stmt.end_while = end_while; - return Ok(id.upcast()); } else if ident == KW_STMT_BREAK { let id = self.consume_break_statement(module, iter, ctx)?; @@ -371,16 +351,6 @@ impl PassDefinitions { return Ok(id.upcast()); } else if ident == KW_STMT_SYNC { let id = self.consume_synchronous_statement(module, iter, ctx)?; - - let end_sync = ctx.heap.alloc_end_synchronous_statement(|this| EndSynchronousStatement { - this, - start_sync: id, - next: StatementId::new_invalid() - }); - - let sync_stmt = &mut ctx.heap[id]; - sync_stmt.end_sync = end_sync; - return Ok(id.upcast()); } else if ident == KW_STMT_FORK { let id = self.consume_fork_statement(module, iter, ctx)?; @@ -397,16 +367,6 @@ impl PassDefinitions { return Ok(id.upcast()); } else if ident == KW_STMT_SELECT { let id = self.consume_select_statement(module, iter, ctx)?; - - let end_select = ctx.heap.alloc_end_select_statement(|this| EndSelectStatement{ - this, - start_select: id, - next: StatementId::new_invalid(), - }); - - let select_stmt = &mut ctx.heap[id]; - select_stmt.end_select = end_select; - return Ok(id.upcast()); } else if ident == KW_STMT_RETURN { let id = self.consume_return_statement(module, iter, ctx)?; @@ -472,7 +432,7 @@ impl PassDefinitions { let mut block_span = consume_token(&module.source, iter, TokenKind::CloseCurly)?; block_span.begin = open_curly_span.begin; - let id = ctx.heap.alloc_block_statement(|this| BlockStatement{ + let block_id = ctx.heap.alloc_block_statement(|this| BlockStatement{ this, is_implicit: false, span: block_span, @@ -481,15 +441,17 @@ impl PassDefinitions { scope: ScopeId::new_invalid(), next: StatementId::new_invalid(), }); + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::Block(block_id))); - let end_block = ctx.heap.alloc_end_block_statement(|this| EndBlockStatement{ - this, start_block: id, next: StatementId::new_invalid() + let end_block_id = ctx.heap.alloc_end_block_statement(|this| EndBlockStatement{ + this, start_block: block_id, next: StatementId::new_invalid() }); - let block_stmt = &mut ctx.heap[id]; - block_stmt.end_block = end_block; + let block_stmt = &mut ctx.heap[block_id]; + block_stmt.end_block = end_block_id; + block_stmt.scope = scope_id; - Ok(id) + Ok(block_id) } fn consume_if_statement( @@ -500,11 +462,11 @@ impl PassDefinitions { let test = self.consume_expression(module, iter, ctx)?; consume_token(&module.source, iter, TokenKind::CloseParen)?; + // Consume bodies of if-statement let true_body = IfStatementCase{ body: self.consume_statement(module, iter, ctx)?, scope: ScopeId::new_invalid(), }; - let true_body_scope_id = true_body.scope; let (false_body, false_body_scope_id) = if has_ident(&module.source, iter, KW_STMT_ELSE) { iter.consume(); @@ -519,6 +481,7 @@ impl PassDefinitions { (None, None) }; + // Construct AST elements let if_stmt_id = ctx.heap.alloc_if_statement(|this| IfStatement{ this, span: if_span, @@ -527,6 +490,20 @@ impl PassDefinitions { false_case: false_body, end_if: EndIfStatementId::new_invalid(), }); + let end_if_stmt_id = ctx.heap.alloc_end_if_statement(|this| EndIfStatement{ + this, + start_if: if_stmt_id, + next: StatementId::new_invalid(), + }); + let true_scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::If(if_stmt_id, true))); + + let if_stmt = &mut ctx.heap[if_stmt_id]; + if_stmt.end_if = end_if_stmt_id; + if_stmt.true_case.scope = true_scope_id; + if let Some(false_case) = &mut if_stmt.false_case { + let false_scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::If(if_stmt_id, false))); + false_case.scope = false_scope_id + } return Ok(if_stmt_id); } @@ -540,7 +517,7 @@ impl PassDefinitions { consume_token(&module.source, iter, TokenKind::CloseParen)?; let body = self.consume_statement(module, iter, ctx)?; - Ok(ctx.heap.alloc_while_statement(|this| WhileStatement{ + let while_stmt_id = ctx.heap.alloc_while_statement(|this| WhileStatement{ this, span: while_span, test, @@ -548,7 +525,19 @@ impl PassDefinitions { body, end_while: EndWhileStatementId::new_invalid(), in_sync: SynchronousStatementId::new_invalid(), - })) + }); + let end_while_stmt_id = ctx.heap.alloc_end_while_statement(|this| EndWhileStatement{ + this, + start_while: while_stmt_id, + next: StatementId::new_invalid(), + }); + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::While(while_stmt_id))); + + let while_stmt = &mut ctx.heap[while_stmt_id]; + while_stmt.scope = scope_id; + while_stmt.end_while = end_while_stmt_id; + + Ok(while_stmt_id) } fn consume_break_statement( @@ -595,13 +584,25 @@ impl PassDefinitions { let synchronous_span = consume_exact_ident(&module.source, iter, KW_STMT_SYNC)?; let body = self.consume_statement(module, iter, ctx)?; - Ok(ctx.heap.alloc_synchronous_statement(|this| SynchronousStatement{ + let sync_stmt_id = ctx.heap.alloc_synchronous_statement(|this| SynchronousStatement{ this, span: synchronous_span, scope: ScopeId::new_invalid(), body, end_sync: EndSynchronousStatementId::new_invalid(), - })) + }); + let end_sync_stmt_id = ctx.heap.alloc_end_synchronous_statement(|this| EndSynchronousStatement{ + this, + start_sync: sync_stmt_id, + next: StatementId::new_invalid(), + }); + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::Synchronous(sync_stmt_id))); + + let sync_stmt = &mut ctx.heap[sync_stmt_id]; + sync_stmt.scope = scope_id; + sync_stmt.end_sync = end_sync_stmt_id; + + return Ok(sync_stmt_id); } fn consume_fork_statement( @@ -668,12 +669,30 @@ impl PassDefinitions { consume_token(&module.source, iter, TokenKind::CloseCurly)?; - Ok(ctx.heap.alloc_select_statement(|this| SelectStatement{ + let num_cases = cases.len(); + let select_stmt_id = ctx.heap.alloc_select_statement(|this| SelectStatement{ this, span: select_span, cases, end_select: EndSelectStatementId::new_invalid(), - })) + }); + let end_select_stmt_id = ctx.heap.alloc_end_select_statement(|this| EndSelectStatement{ + this, + start_select: select_stmt_id, + next: StatementId::new_invalid(), + }); + + let select_stmt = &mut ctx.heap[select_stmt_id]; + select_stmt.end_select = end_select_stmt_id; + + for case_index in 0..num_cases { + let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::SelectCase(select_stmt_id, case_index as u32))); + let select_stmt = &mut ctx.heap[select_stmt_id]; + let select_case = &mut select_stmt.cases[case_index]; + select_case.scope = scope_id; + } + + return Ok(select_stmt_id) } fn consume_return_statement(