diff --git a/src/protocol/parser/pass_rewriting.rs b/src/protocol/parser/pass_rewriting.rs index d4c57df2fb4049f5cad3aa38e938bcff0139d40d..99d2abe78fd4ca490f99cdf3503ca94e6799d2f2 100644 --- a/src/protocol/parser/pass_rewriting.rs +++ b/src/protocol/parser/pass_rewriting.rs @@ -115,7 +115,7 @@ impl Visitor for PassRewriting { ctx: &mut Ctx, containing_procedure_id: ProcedureDefinitionId, select_id: SelectStatementId, case_index: usize, select_var_id: VariableId, select_var_type_id: TypeIdReference - ) -> (IfStatementId, EndIfStatementId) { + ) -> (IfStatementId, EndIfStatementId, ScopeId) { // Retrieve statement IDs associated with case let case = &ctx.heap[select_id].cases[case_index]; let case_guard_id = case.guard; @@ -133,7 +133,7 @@ impl Visitor for PassRewriting { // Link up body statement to end-if set_ast_statement_next(ctx, case_body_id, end_if_stmt_id.upcast()); - return (if_stmt_id, end_if_stmt_id) + return (if_stmt_id, end_if_stmt_id, case_scope_id); } // Precreate the block that will end up containing all of the @@ -206,8 +206,8 @@ impl Visitor for PassRewriting { // Create the call that indicates the start of the select block { - let num_cases_expression_id = create_ast_literal_integer_expr(ctx, self.current_procedure_id, total_num_cases as u64); - let num_ports_expression_id = create_ast_literal_integer_expr(ctx, self.current_procedure_id, total_num_ports as u64); + let num_cases_expression_id = create_ast_literal_integer_expr(ctx, self.current_procedure_id, total_num_cases as u64, ctx.arch.uint32_type_id); + let num_ports_expression_id = create_ast_literal_integer_expr(ctx, self.current_procedure_id, total_num_ports as u64, ctx.arch.uint32_type_id); let arguments = vec![ num_cases_expression_id.upcast(), num_ports_expression_id.upcast() @@ -230,8 +230,8 @@ impl Visitor for PassRewriting { for case_port_index in 0..case_num_ports { // Arguments to runtime call let (port_variable_id, port_variable_type) = locals[total_port_index]; // so far this variable contains the temporary variables for the port expressions - let case_index_expr_id = create_ast_literal_integer_expr(ctx, self.current_procedure_id, case_index as u64); - let port_index_expr_id = create_ast_literal_integer_expr(ctx, self.current_procedure_id, case_port_index as u64); + let case_index_expr_id = create_ast_literal_integer_expr(ctx, self.current_procedure_id, case_index as u64, ctx.arch.uint32_type_id); + let port_index_expr_id = create_ast_literal_integer_expr(ctx, self.current_procedure_id, case_port_index as u64, ctx.arch.uint32_type_id); let port_variable_expr_id = create_ast_variable_expr(ctx, self.current_procedure_id, port_variable_id, port_variable_type); let runtime_call_arguments = vec![ case_index_expr_id.upcast(), @@ -267,18 +267,24 @@ impl Visitor for PassRewriting { // Now we transform each of the select block case's guard and code into // a chained if-else statement. + let mut relative_pos = transformed_stmts.len() as i32; if total_num_cases > 0 { - let (if_stmt_id, end_if_stmt_id) = transform_select_case_code(ctx, self.current_procedure_id, id, 0, select_variable_id, select_variable_type); + let (if_stmt_id, end_if_stmt_id, scope_id) = transform_select_case_code(ctx, self.current_procedure_id, id, 0, select_variable_id, select_variable_type); + link_existing_child_to_new_parent_scope(ctx, &mut self.scope_buffer, outer_scope_id, scope_id, relative_pos); let first_end_if_stmt = &mut ctx.heap[end_if_stmt_id]; first_end_if_stmt.next = outer_end_block_id.upcast(); let mut last_if_stmt_id = if_stmt_id; let mut last_end_if_stmt_id = end_if_stmt_id; + let mut last_parent_scope_id = outer_scope_id; + let mut last_relative_pos = transformed_stmts.len() as i32 + 1; transformed_stmts.push(last_if_stmt_id.upcast()); for case_index in 1..total_num_cases { - let (if_stmt_id, end_if_stmt_id) = transform_select_case_code(ctx, self.current_procedure_id, id, case_index, select_variable_id, select_variable_type); + let (if_stmt_id, end_if_stmt_id, scope_id) = transform_select_case_code(ctx, self.current_procedure_id, id, case_index, select_variable_id, select_variable_type); let false_case_scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::If(last_if_stmt_id, false))); + link_existing_child_to_new_parent_scope(ctx, &mut self.scope_buffer, false_case_scope_id, scope_id, 0); + link_new_child_to_existing_parent_scope(ctx, &mut self.scope_buffer, last_parent_scope_id, false_case_scope_id, last_relative_pos); set_ast_if_statement_false_body(ctx, last_if_stmt_id, last_end_if_stmt_id, IfStatementCase{ body: if_stmt_id.upcast(), scope: false_case_scope_id }); let end_if_stmt = &mut ctx.heap[end_if_stmt_id]; @@ -286,11 +292,13 @@ impl Visitor for PassRewriting { last_if_stmt_id = if_stmt_id; last_end_if_stmt_id = end_if_stmt_id; + last_parent_scope_id = false_case_scope_id; + last_relative_pos = 0; } } // Final steps: set the statements of the replacement block statement, - // and link all of those statements together + // link all of those statements together, and update the scopes. let first_stmt_id = transformed_stmts[0]; let mut last_stmt_id = transformed_stmts[0]; for stmt_id in transformed_stmts.iter().skip(1).copied() { @@ -380,8 +388,8 @@ fn create_ast_call_expr(ctx: &mut Ctx, containing_procedure_id: ProcedureDefinit return call_expression_id; } -fn create_ast_literal_integer_expr(ctx: &mut Ctx, containing_procedure_id: ProcedureDefinitionId, unsigned_value: u64) -> LiteralExpressionId { - let literal_type_index = add_new_procedure_expression_type(ctx, containing_procedure_id, TypeIdReference::DirectTypeId(ctx.arch.uint64_type_id)); +fn create_ast_literal_integer_expr(ctx: &mut Ctx, containing_procedure_id: ProcedureDefinitionId, unsigned_value: u64, type_id: TypeId) -> LiteralExpressionId { + let literal_type_index = add_new_procedure_expression_type(ctx, containing_procedure_id, TypeIdReference::DirectTypeId(type_id)); return ctx.heap.alloc_literal_expression(|this| LiteralExpression{ this, span: InputSpan::new(), @@ -399,7 +407,7 @@ fn create_ast_equality_comparison_expr( variable_id: VariableId, variable_type: TypeIdReference, value: u64 ) -> BinaryExpressionId { let var_expr_id = create_ast_variable_expr(ctx, containing_procedure_id, variable_id, variable_type); - let int_expr_id = create_ast_literal_integer_expr(ctx, containing_procedure_id, value); + let int_expr_id = create_ast_literal_integer_expr(ctx, containing_procedure_id, value, ctx.arch.uint32_type_id); let cmp_type_index = add_new_procedure_expression_type(ctx, containing_procedure_id, TypeIdReference::DirectTypeId(ctx.arch.bool_type_id)); let cmp_expr_id = ctx.heap.alloc_binary_expression(|this| BinaryExpression{ this, @@ -440,6 +448,7 @@ fn create_ast_variable_declaration_stmt( ) -> MemoryStatementId { // Create the assignment expression, assigning the initial value to the variable let variable_expr_id = create_ast_variable_expr(ctx, containing_procedure_id, variable_id, variable_type); + let void_type_index = add_new_procedure_expression_type(ctx, containing_procedure_id, TypeIdReference::DirectTypeId(ctx.arch.void_type_id)); let assignment_expr_id = ctx.heap.alloc_assignment_expression(|this| AssignmentExpression{ this, operator_span: InputSpan::new(), @@ -448,7 +457,7 @@ fn create_ast_variable_declaration_stmt( operation: AssignmentOperator::Set, right: initial_value_expr_id, parent: ExpressionParent::None, - type_index: -1, + type_index: void_type_index, }); // Create the memory statement @@ -623,9 +632,9 @@ fn link_existing_child_to_new_parent_scope(ctx: &mut Ctx, scope_buffer: &mut Sco /// Will add a child scope to a parent scope using the relative position hint. fn add_child_scope_to_parent(ctx: &mut Ctx, scope_buffer: &mut ScopedBuffer, parent_scope_id: ScopeId, child_scope_id: ScopeId, relative_pos_hint: i32) { - let child_scope = &ctx.heap[child_scope_id]; + let parent_scope = &ctx.heap[parent_scope_id]; - let existing_scope_ids = scope_buffer.start_section_initialized(&child_scope.nested); + let existing_scope_ids = scope_buffer.start_section_initialized(&parent_scope.nested); let mut insert_pos = existing_scope_ids.len(); for index in 0..existing_scope_ids.len() { let existing_scope_id = existing_scope_ids[index]; @@ -665,4 +674,4 @@ fn add_new_procedure_expression_type(ctx: &mut Ctx, procedure_id: ProcedureDefin } return type_index as i32; -} +} \ No newline at end of file