From ec7bf650b246588e242621165d2372d706fd0583 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 8 Mar 2026 13:33:06 -0500 Subject: [PATCH] Add return mechanism to dvm code, and related fixes to dmc. --- dm/src/main.rs | 4 +++- dmc-lib/src/ast/expression_statement.rs | 9 +++++++-- dmc-lib/src/ast/function.rs | 17 +++++++++++------ dmc-lib/src/ast/statement.rs | 9 +++++++-- dvm-lib/src/vm/mod.rs | 9 ++++++++- dvm-lib/src/vm/value.rs | 17 +++++++++++++++++ examples/main_return.dm | 3 +++ 7 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 examples/main_return.dm diff --git a/dm/src/main.rs b/dm/src/main.rs index cca055a..ec87e68 100644 --- a/dm/src/main.rs +++ b/dm/src/main.rs @@ -107,7 +107,9 @@ fn main() { "main", vec![], ); - println!("{:?}", result); + if let Some(value) = result { + println!("{}", value); + } } fn check_and_report_diagnostics( diff --git a/dmc-lib/src/ast/expression_statement.rs b/dmc-lib/src/ast/expression_statement.rs index 6c5878b..a94d34e 100644 --- a/dmc-lib/src/ast/expression_statement.rs +++ b/dmc-lib/src/ast/expression_statement.rs @@ -32,9 +32,14 @@ impl ExpressionStatement { self.expression.type_check(symbol_table) } - pub fn to_ir(&self, builder: &mut IrBuilder, symbol_table: &SymbolTable, is_last: bool) { + pub fn to_ir( + &self, + builder: &mut IrBuilder, + symbol_table: &SymbolTable, + should_return_value: bool, + ) { let ir_expression = self.expression.to_ir(builder, symbol_table); - if ir_expression.is_some() && is_last { + if ir_expression.is_some() && should_return_value { builder .current_block_mut() .add_statement(IrStatement::Return(IrReturn::new(ir_expression))); diff --git a/dmc-lib/src/ast/function.rs b/dmc-lib/src/ast/function.rs index 64ed7a5..a0f93bd 100644 --- a/dmc-lib/src/ast/function.rs +++ b/dmc-lib/src/ast/function.rs @@ -171,17 +171,22 @@ impl Function { } let entry_block_id = builder.new_block(); + + let return_type_info = self + .function_symbol + .as_ref() + .unwrap() + .borrow() + .return_type(); + + let should_return_value = !matches!(return_type_info, TypeInfo::Void); + for (i, statement) in self.statements.iter().enumerate() { let is_last = i == self.statements.len() - 1; - statement.to_ir(&mut builder, symbol_table, is_last); + statement.to_ir(&mut builder, symbol_table, should_return_value && is_last); } builder.finish_block(); - let return_type_info = self - .return_type - .as_ref() - .map(|return_type| return_type.to_type_info()) - .unwrap_or(TypeInfo::Void); let entry_block = builder.get_block(entry_block_id).clone(); IrFunction::new( self.function_symbol.as_ref().unwrap().clone(), diff --git a/dmc-lib/src/ast/statement.rs b/dmc-lib/src/ast/statement.rs index c022791..bb965f7 100644 --- a/dmc-lib/src/ast/statement.rs +++ b/dmc-lib/src/ast/statement.rs @@ -37,13 +37,18 @@ impl Statement { } } - pub fn to_ir(&self, builder: &mut IrBuilder, symbol_table: &SymbolTable, is_last: bool) { + pub fn to_ir( + &self, + builder: &mut IrBuilder, + symbol_table: &SymbolTable, + should_return_value: bool, + ) { match self { Statement::Let(let_statement) => { let_statement.to_ir(builder, symbol_table); } Statement::Expression(expression_statement) => { - expression_statement.to_ir(builder, symbol_table, is_last); + expression_statement.to_ir(builder, symbol_table, should_return_value); } } } diff --git a/dvm-lib/src/vm/mod.rs b/dvm-lib/src/vm/mod.rs index 4718bfc..0677686 100644 --- a/dvm-lib/src/vm/mod.rs +++ b/dvm-lib/src/vm/mod.rs @@ -244,6 +244,9 @@ pub fn call<'a>( Value::Null, ); + // container for final return value + let mut return_value: Option = None; + while call_stack.maybe_top().is_some() && call_stack.top().ip() < call_stack.top().instructions().len() { @@ -486,6 +489,10 @@ pub fn call<'a>( // n.b. callee caller.stack_mut().push(return_value); } + } else { + // callee is the bottommost frame ("main" or whatever was called) + // set the return value + return_value = callee.take_return_value(); } // do not increment ip of the caller; this was done above BEFORE the call } @@ -499,5 +506,5 @@ pub fn call<'a>( } } } - None // todo: returning results from main functions + return_value } diff --git a/dvm-lib/src/vm/value.rs b/dvm-lib/src/vm/value.rs index 20d7ca4..8d8c83c 100644 --- a/dvm-lib/src/vm/value.rs +++ b/dvm-lib/src/vm/value.rs @@ -1,3 +1,4 @@ +use std::fmt::{Display, Formatter}; use std::rc::Rc; #[derive(Clone, Debug)] @@ -28,3 +29,19 @@ impl Value { } } } + +impl Display for Value { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Value::Int(i) => { + write!(f, "{}", i) + } + Value::String(s) => { + write!(f, "{}", s) + } + Value::Null => { + write!(f, "Null") + } + } + } +} diff --git a/examples/main_return.dm b/examples/main_return.dm new file mode 100644 index 0000000..c40ac87 --- /dev/null +++ b/examples/main_return.dm @@ -0,0 +1,3 @@ +fn main() -> Int + 42 +end \ No newline at end of file