Changeset - 4c7ae98737cf
[Not reviewed]
0 2 0
MH - 3 years ago 2022-02-11 10:50:43
contact@maxhenger.nl
Fix bugs that arose from scoping refactoring
2 files changed with 37 insertions and 21 deletions:
0 comments (0 inline, 0 general)
src/protocol/parser/pass_definitions.rs
Show inline comments
 
@@ -280,13 +280,15 @@ impl PassDefinitions {
 
        )?;
 

	
 
        // Consume block and the definition's scope
 
        let body = self.consume_block_statement(module, iter, ctx)?;
 
        let body_id = self.consume_block_statement(module, iter, ctx)?;
 
        let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::Definition(definition_id)));
 

	
 
        // Assign everything in the preallocated AST node
 
        let function = ctx.heap[definition_id].as_function_mut();
 
        function.return_type = parser_type;
 
        function.parameters = parameters;
 
        function.body = body;
 
        function.scope = scope_id;
 
        function.body = body_id;
 

	
 
        Ok(())
 
    }
 
@@ -315,12 +317,14 @@ impl PassDefinitions {
 
        let parameters = parameter_section.into_vec();
 

	
 
        // Consume block
 
        let body = self.consume_block_statement(module, iter, ctx)?;
 
        let body_id = self.consume_block_statement(module, iter, ctx)?;
 
        let scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::Definition(definition_id)));
 

	
 
        // Assign everything in the AST node
 
        let component = ctx.heap[definition_id].as_component_mut();
 
        component.parameters = parameters;
 
        component.body = body;
 
        component.scope = scope_id;
 
        component.body = body_id;
 

	
 
        Ok(())
 
    }
 
@@ -468,7 +472,7 @@ impl PassDefinitions {
 
            scope: ScopeId::new_invalid(),
 
        };
 

	
 
        let (false_body, false_body_scope_id) = if has_ident(&module.source, iter, KW_STMT_ELSE) {
 
        let false_body = if has_ident(&module.source, iter, KW_STMT_ELSE) {
 
            iter.consume();
 
            let false_body = IfStatementCase{
 
                body: self.consume_statement(module, iter, ctx)?,
 
@@ -476,9 +480,9 @@ impl PassDefinitions {
 
            };
 

	
 
            let false_body_scope_id = false_body.scope;
 
            (Some(false_body), Some(false_body_scope_id))
 
            Some(false_body)
 
        } else {
 
            (None, None)
 
            None
 
        };
 

	
 
        // Construct AST elements
 
@@ -496,13 +500,17 @@ impl PassDefinitions {
 
            next: StatementId::new_invalid(),
 
        });
 
        let true_scope_id = ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::If(if_stmt_id, true)));
 
        let false_scope_id = if false_body.is_some() {
 
            Some(ctx.heap.alloc_scope(|this| Scope::new(this, ScopeAssociation::If(if_stmt_id, false))))
 
        } else {
 
            None
 
        };
 

	
 
        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
 
            false_case.scope = false_scope_id.unwrap();
 
        }
 

	
 
        return Ok(if_stmt_id);
src/protocol/parser/pass_validation_linking.rs
Show inline comments
 
@@ -225,7 +225,7 @@ impl Visitor for PassValidationLinking {
 
        let section = self.variable_buffer.start_section_initialized(&definition.parameters);
 
        for variable_idx in 0..section.len() {
 
            let variable_id = section[variable_idx];
 
            self.checked_at_single_scope_add_local(ctx, self.cur_scope, variable_idx as i32, variable_id)?;
 
            self.checked_at_single_scope_add_local(ctx, self.cur_scope, -1, variable_id)?;
 
        }
 
        self.relative_pos_in_parent = section.len() as i32;
 

	
 
@@ -264,7 +264,7 @@ impl Visitor for PassValidationLinking {
 
        let section = self.variable_buffer.start_section_initialized(&definition.parameters);
 
        for variable_idx in 0..section.len() {
 
            let variable_id = section[variable_idx];
 
            self.checked_at_single_scope_add_local(ctx, self.cur_scope, variable_idx as i32, variable_id)?;
 
            self.checked_at_single_scope_add_local(ctx, self.cur_scope, -1, variable_id)?;
 
        }
 
        section.forget();
 

	
 
@@ -315,6 +315,9 @@ impl Visitor for PassValidationLinking {
 
        let expr_id = stmt.initial_expr;
 
        let variable_id = stmt.variable;
 

	
 
        if ctx.heap[variable_id].identifier.value.as_str() == "counter" {
 
            let a = 1;
 
        }
 
        self.checked_add_local(ctx, self.cur_scope, self.relative_pos_in_parent, variable_id)?;
 

	
 
        assign_and_replace_next_stmt!(self, ctx, id.upcast().upcast());
 
@@ -570,6 +573,7 @@ impl Visitor for PassValidationLinking {
 
            self.in_select_guard = SelectStatementId::new_invalid();
 

	
 
            // Visit the code associated with the guard
 
            self.relative_pos_in_parent += 1;
 
            self.visit_stmt(ctx, case_body_id)?;
 
            self.pop_scope(old_scope);
 

	
 
@@ -1351,6 +1355,10 @@ impl Visitor for PassValidationLinking {
 
        let mut is_binding_target = false;
 

	
 
        // Otherwise try to find it
 
        if var_expr.identifier.value.as_str() == "new_value" {
 
            let a = 0; // TODO: REMOVE!
 
        }
 

	
 
        if variable_id.is_none() {
 
            variable_id = self.find_variable(ctx, self.relative_pos_in_parent, &var_expr.identifier);
 
        }
 
@@ -1471,7 +1479,7 @@ impl PassValidationLinking {
 
        let old_scope_id = self.cur_scope;
 

	
 
        let scope = &mut ctx.heap[pushed_scope_id];
 
        if is_top_level_scope {
 
        if !is_top_level_scope {
 
            scope.parent = Some(old_scope_id);
 
        }
 

	
 
@@ -1613,8 +1621,8 @@ impl PassValidationLinking {
 

	
 
    /// Adds a local variable to the current scope. It will also annotate the
 
    /// `Local` in the AST with its relative position in the block.
 
    fn checked_add_local(&mut self, ctx: &mut Ctx, target_scope_id: ScopeId, target_relative_pos: i32, id: VariableId) -> Result<(), ParseError> {
 
        let local = &ctx.heap[id];
 
    fn checked_add_local(&mut self, ctx: &mut Ctx, target_scope_id: ScopeId, target_relative_pos: i32, new_variable_id: VariableId) -> Result<(), ParseError> {
 
        let new_variable = &ctx.heap[new_variable_id];
 

	
 
        // We immediately go to the parent scope. We check the target scope
 
        // in the call at the end. That is also where we check for collisions
 
@@ -1626,15 +1634,15 @@ impl PassValidationLinking {
 

	
 
            // Check for collisions
 
            for variable_id in scope.variables.iter().copied() {
 
                let variable = &ctx.heap[variable_id];
 
                if variable.identifier == variable.identifier &&
 
                    variable.this != id &&
 
                    cur_relative_pos >= variable.relative_pos_in_parent {
 
                let existing_variable = &ctx.heap[variable_id];
 
                if existing_variable.identifier == new_variable.identifier &&
 
                    existing_variable.this != new_variable_id &&
 
                    cur_relative_pos >= existing_variable.relative_pos_in_parent {
 
                    return Err(
 
                        ParseError::new_error_str_at_span(
 
                            &ctx.module().source, local.identifier.span, "Local variable name conflicts with another variable"
 
                            &ctx.module().source, new_variable.identifier.span, "Local variable name conflicts with another variable"
 
                        ).with_info_str_at_span(
 
                            &ctx.module().source, variable.identifier.span, "Previous variable is found here"
 
                            &ctx.module().source, existing_variable.identifier.span, "Previous variable is found here"
 
                        )
 
                    );
 
                }
 
@@ -1644,7 +1652,7 @@ impl PassValidationLinking {
 
        }
 

	
 
        // No collisions in any of the parent scope, attempt to add to scope
 
        self.checked_at_single_scope_add_local(ctx, target_scope_id, target_relative_pos, id)
 
        self.checked_at_single_scope_add_local(ctx, target_scope_id, target_relative_pos, new_variable_id)
 
    }
 

	
 
    /// Adds a local variable to the specified scope. Will check the specified
0 comments (0 inline, 0 general)