Add return mechanism to dvm code, and related fixes to dmc.
This commit is contained in:
parent
2e33936842
commit
ec7bf650b2
@ -107,7 +107,9 @@ fn main() {
|
||||
"main",
|
||||
vec![],
|
||||
);
|
||||
println!("{:?}", result);
|
||||
if let Some(value) = result {
|
||||
println!("{}", value);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_and_report_diagnostics(
|
||||
|
||||
@ -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)));
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,6 +244,9 @@ pub fn call<'a>(
|
||||
Value::Null,
|
||||
);
|
||||
|
||||
// container for final return value
|
||||
let mut return_value: Option<Value> = 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
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3
examples/main_return.dm
Normal file
3
examples/main_return.dm
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() -> Int
|
||||
42
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user