diff --git a/src/backend/vm.rs b/src/backend/vm.rs index 201c5a4e..89d4c32c 100644 --- a/src/backend/vm.rs +++ b/src/backend/vm.rs @@ -41,6 +41,7 @@ pub enum VMValue { Float(f64), Bool(bool), String(String), + Future(crate::boxes::future::FutureBox), Void, } @@ -52,6 +53,7 @@ impl VMValue { VMValue::Float(f) => Box::new(StringBox::new(&f.to_string())), // Simplified for now VMValue::Bool(b) => Box::new(BoolBox::new(*b)), VMValue::String(s) => Box::new(StringBox::new(s)), + VMValue::Future(f) => Box::new(f.clone()), VMValue::Void => Box::new(VoidBox::new()), } } @@ -63,6 +65,7 @@ impl VMValue { VMValue::Float(f) => f.to_string(), VMValue::Bool(b) => b.to_string(), VMValue::String(s) => s.clone(), + VMValue::Future(f) => f.to_string_box().value, VMValue::Void => "void".to_string(), } } @@ -83,6 +86,23 @@ impl VMValue { _ => Err(VMError::TypeError(format!("Expected bool, got {:?}", self))), } } + + /// Convert from NyashBox to VMValue + pub fn from_nyash_box(nyash_box: Box) -> VMValue { + // Try to downcast to known types + if let Some(int_box) = nyash_box.as_any().downcast_ref::() { + VMValue::Integer(int_box.value) + } else if let Some(bool_box) = nyash_box.as_any().downcast_ref::() { + VMValue::Bool(bool_box.value) + } else if let Some(string_box) = nyash_box.as_any().downcast_ref::() { + VMValue::String(string_box.value.clone()) + } else if let Some(future_box) = nyash_box.as_any().downcast_ref::() { + VMValue::Future(future_box.clone()) + } else { + // For any other type, convert to string representation + VMValue::String(nyash_box.to_string_box().value) + } + } } impl From<&ConstValue> for VMValue { @@ -439,6 +459,43 @@ impl VM { // In a real implementation, this would ensure memory ordering Ok(ControlFlow::Continue) }, + + // Phase 7: Async/Future Operations + MirInstruction::FutureNew { dst, value } => { + let initial_value = self.get_value(*value)?; + let future = crate::boxes::future::FutureBox::new(); + // Convert VMValue to NyashBox and set it in the future + future.set_result(initial_value.to_nyash_box()); + self.values.insert(*dst, VMValue::Future(future)); + Ok(ControlFlow::Continue) + }, + + MirInstruction::FutureSet { future, value } => { + let future_val = self.get_value(*future)?; + let new_value = self.get_value(*value)?; + + if let VMValue::Future(ref future_box) = future_val { + future_box.set_result(new_value.to_nyash_box()); + Ok(ControlFlow::Continue) + } else { + Err(VMError::TypeError(format!("Expected Future, got {:?}", future_val))) + } + }, + + MirInstruction::Await { dst, future } => { + let future_val = self.get_value(*future)?; + + if let VMValue::Future(ref future_box) = future_val { + // This blocks until the future is ready + let result = future_box.get(); + // Convert NyashBox back to VMValue + let vm_value = VMValue::from_nyash_box(result); + self.values.insert(*dst, vm_value); + Ok(ControlFlow::Continue) + } else { + Err(VMError::TypeError(format!("Expected Future, got {:?}", future_val))) + } + }, } } diff --git a/src/mir/instruction.rs b/src/mir/instruction.rs index 941c775f..22c07a11 100644 --- a/src/mir/instruction.rs +++ b/src/mir/instruction.rs @@ -250,6 +250,29 @@ pub enum MirInstruction { BarrierWrite { ptr: ValueId, }, + + // === Phase 7: Async/Future Operations === + + /// Create a new Future with initial value + /// `%dst = future_new %value` + FutureNew { + dst: ValueId, + value: ValueId, + }, + + /// Set Future value and mark as ready + /// `future_set %future = %value` + FutureSet { + future: ValueId, + value: ValueId, + }, + + /// Wait for Future completion and get value + /// `%dst = await %future` + Await { + dst: ValueId, + future: ValueId, + }, } /// Constant values in MIR @@ -304,6 +327,7 @@ pub enum MirType { String, Box(String), // Box type with name Array(Box), + Future(Box), // Future containing a type Void, Unknown, } @@ -360,6 +384,11 @@ impl MirInstruction { MirInstruction::WeakLoad { .. } => EffectMask::READ, // Loading weak ref has read effects MirInstruction::BarrierRead { .. } => EffectMask::READ.add(Effect::Barrier), // Memory barrier with read MirInstruction::BarrierWrite { .. } => EffectMask::WRITE.add(Effect::Barrier), // Memory barrier with write + + // Phase 7: Async/Future Operations + MirInstruction::FutureNew { .. } => EffectMask::PURE.add(Effect::Alloc), // Creating future may allocate + MirInstruction::FutureSet { .. } => EffectMask::WRITE, // Setting future has write effects + MirInstruction::Await { .. } => EffectMask::READ.add(Effect::Async), // Await blocks and reads } } @@ -380,7 +409,9 @@ impl MirInstruction { MirInstruction::RefNew { dst, .. } | MirInstruction::RefGet { dst, .. } | MirInstruction::WeakNew { dst, .. } | - MirInstruction::WeakLoad { dst, .. } => Some(*dst), + MirInstruction::WeakLoad { dst, .. } | + MirInstruction::FutureNew { dst, .. } | + MirInstruction::Await { dst, .. } => Some(*dst), MirInstruction::Call { dst, .. } | MirInstruction::BoxCall { dst, .. } => *dst, @@ -396,6 +427,7 @@ impl MirInstruction { MirInstruction::RefSet { .. } | MirInstruction::BarrierRead { .. } | MirInstruction::BarrierWrite { .. } | + MirInstruction::FutureSet { .. } | MirInstruction::Safepoint | MirInstruction::Nop => None, @@ -463,6 +495,11 @@ impl MirInstruction { MirInstruction::WeakLoad { weak_ref, .. } => vec![*weak_ref], MirInstruction::BarrierRead { ptr } => vec![*ptr], MirInstruction::BarrierWrite { ptr } => vec![*ptr], + + // Phase 7: Async/Future Operations + MirInstruction::FutureNew { value, .. } => vec![*value], + MirInstruction::FutureSet { future, value } => vec![*future, *value], + MirInstruction::Await { future, .. } => vec![*future], } } } diff --git a/src/mir/printer.rs b/src/mir/printer.rs index 91407eb3..565180a3 100644 --- a/src/mir/printer.rs +++ b/src/mir/printer.rs @@ -347,6 +347,19 @@ impl MirPrinter { MirInstruction::BarrierWrite { ptr } => { format!("barrier_write {}", ptr) }, + + // Phase 7: Async/Future Operations + MirInstruction::FutureNew { dst, value } => { + format!("{} = future_new {}", dst, value) + }, + + MirInstruction::FutureSet { future, value } => { + format!("future_set {} = {}", future, value) + }, + + MirInstruction::Await { dst, future } => { + format!("{} = await {}", dst, future) + }, } } @@ -359,6 +372,7 @@ impl MirPrinter { super::MirType::String => "str".to_string(), super::MirType::Box(name) => format!("box<{}>", name), super::MirType::Array(elem_type) => format!("[{}]", self.format_type(elem_type)), + super::MirType::Future(inner_type) => format!("future<{}>", self.format_type(inner_type)), super::MirType::Void => "void".to_string(), super::MirType::Unknown => "?".to_string(), }