From 08b5bba2c4d28877bd8207f40826fe3a80525731 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Thu, 12 Mar 2026 14:07:27 +0100 Subject: [PATCH] Add purity to LocalInfo and initialize in binder The `LocalInfo` struct now includes a `purity` field to track the purity of local variables and function arguments. This is initialized to `Purity::Impure` for local variables and arguments within functions and when registering native functions. Additionally, the `Environment` struct is updated to include `root_scopes` and `root_slot_count` to support parallel mode compilation by populating the root scope with initial function and native function information. --- src/ast/compiler/binder.rs | 5 ++++- src/ast/environment.rs | 44 +++++++++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/ast/compiler/binder.rs b/src/ast/compiler/binder.rs index 67b27d5..0575284 100644 --- a/src/ast/compiler/binder.rs +++ b/src/ast/compiler/binder.rs @@ -3,7 +3,7 @@ use crate::ast::compiler::bound_nodes::{ }; use crate::ast::diagnostics::Diagnostics; use crate::ast::nodes::{Node, Symbol, UntypedKind}; -use crate::ast::types::{Identity, StaticType}; +use crate::ast::types::{Identity, StaticType, Purity}; use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; @@ -13,6 +13,7 @@ pub struct LocalInfo { pub addr: Address, pub identity: Identity, pub _ty: StaticType, + pub purity: Purity, } #[derive(Debug, Clone)] @@ -69,6 +70,7 @@ impl FunctionCompiler { addr: Address::Local(slot), identity, _ty: StaticType::Any, + purity: Purity::Impure, }, ); self.slot_count += 1; @@ -191,6 +193,7 @@ impl Binder { addr, identity, _ty: StaticType::Any, + purity: Purity::Impure, }, ); return Some(addr); diff --git a/src/ast/environment.rs b/src/ast/environment.rs index 090a4da..5c0cf11 100644 --- a/src/ast/environment.rs +++ b/src/ast/environment.rs @@ -76,6 +76,8 @@ pub struct Environment { pub global_purity: Rc>>, pub global_values: Rc>>, pub fixed_scope_idx: i32, + pub root_scopes: Rc>>, + pub root_slot_count: Rc>, pub function_registry: Rc>, pub typed_function_registry: Rc>, pub monomorph_cache: Rc>, @@ -164,6 +166,8 @@ impl Environment { global_purity: Rc::new(RefCell::new(HashMap::new())), global_values: Rc::new(RefCell::new(Vec::new())), fixed_scope_idx: -1, + root_scopes: Rc::new(RefCell::new(vec![crate::ast::compiler::binder::CompilerScope::new()])), + root_slot_count: Rc::new(RefCell::new(0)), function_registry: Rc::new(RefCell::new(HashMap::new())), typed_function_registry: Rc::new(RefCell::new(HashMap::new())), monomorph_cache: Rc::new(RefCell::new(HashMap::new())), @@ -504,10 +508,25 @@ impl Environment { let idx = GlobalIdx(values.len() as u32); let identity = NodeIdentity::new(SourceLocation { line: 0, col: 0 }); - names.insert(Symbol::from(name), (idx, identity)); - types.insert(idx, ty); + names.insert(Symbol::from(name), (idx, identity.clone())); + types.insert(idx, ty.clone()); purity.insert(idx, func.purity); - values.push(Value::Function(func)); + values.push(Value::Function(func.clone())); + + // Parallel mode: populate root_scopes[0] + let mut root_scopes = self.root_scopes.borrow_mut(); + let mut slot_count = self.root_slot_count.borrow_mut(); + let slot = crate::ast::compiler::bound_nodes::LocalSlot(*slot_count); + root_scopes[0].locals.insert( + Symbol::from(name), + crate::ast::compiler::binder::LocalInfo { + addr: Address::Local(slot), + identity, + _ty: ty, + purity: func.purity, + }, + ); + *slot_count += 1; } pub fn register_native_fn( @@ -535,10 +554,25 @@ impl Environment { let idx = GlobalIdx(values.len() as u32); let identity = NodeIdentity::new(SourceLocation { line: 0, col: 0 }); - names.insert(Symbol::from(name), (idx, identity)); - types.insert(idx, ty); + names.insert(Symbol::from(name), (idx, identity.clone())); + types.insert(idx, ty.clone()); purity.insert(idx, Purity::Pure); values.push(val); + + // Parallel mode: populate root_scopes[0] + let mut root_scopes = self.root_scopes.borrow_mut(); + let mut slot_count = self.root_slot_count.borrow_mut(); + let slot = crate::ast::compiler::bound_nodes::LocalSlot(*slot_count); + root_scopes[0].locals.insert( + Symbol::from(name), + crate::ast::compiler::binder::LocalInfo { + addr: Address::Local(slot), + identity, + _ty: ty, + purity: Purity::Pure, + }, + ); + *slot_count += 1; }