From 6d4d394022e506122587e66d8c93be50ba70b62b Mon Sep 17 00:00:00 2001 From: David Ellis Date: Thu, 22 Feb 2024 18:27:02 -0600 Subject: [PATCH] Add support for return statements (#657) * Add support for return statements * Fix fmt --- src/lntors/function.rs | 6 ++++++ src/program.rs | 33 ++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/lntors/function.rs b/src/lntors/function.rs index dadff979e..21a7243ab 100644 --- a/src/lntors/function.rs +++ b/src/lntors/function.rs @@ -37,6 +37,12 @@ pub fn from_microstatement( }, } } + Microstatement::Return { value } => match value { + Some(val) => { + Ok(format!("return {}", from_microstatement(val, scope, program)?).to_string()) + } + None => Ok("return".to_string()), + }, } } diff --git a/src/program.rs b/src/program.rs index ac5bd43a3..a826084c9 100644 --- a/src/program.rs +++ b/src/program.rs @@ -327,7 +327,10 @@ pub enum Microstatement { Value { typen: String, // TODO: Do better on this, too. representation: String, // TODO: Can we do better here? - }, // TODO: Conditionals, Emits, and Returns + }, // TODO: Conditionals and Emits + Return { + value: Option>, + }, } fn baseassignablelist_to_microstatements( @@ -350,7 +353,7 @@ fn baseassignablelist_to_microstatements( let mut args = Vec::new(); for arg in &call.assignablelist { let mut argmicrostatements = - withoperatorslist_to_microstatement(arg)?; + withoperatorslist_to_microstatements(arg)?; let lastmicrostatement = argmicrostatements.pop().unwrap(); match lastmicrostatement { Microstatement::Assignment { ref name, .. } => { @@ -412,7 +415,7 @@ fn baseassignablelist_to_microstatements( Ok(microstatements) } -fn withoperatorslist_to_microstatement( +fn withoperatorslist_to_microstatements( withoperatorslist: &Vec, ) -> Result, Box> { let mut microstatements = Vec::new(); @@ -433,7 +436,7 @@ fn assignablestatement_to_microstatements( assignable: &parse::AssignableStatement, ) -> Result, Box> { let mut microstatements = Vec::new(); - microstatements.append(&mut withoperatorslist_to_microstatement( + microstatements.append(&mut withoperatorslist_to_microstatements( &assignable.assignables, )?); Ok(microstatements) @@ -446,7 +449,27 @@ fn statement_to_microstatements( match statement { parse::Statement::A(_) => {} parse::Statement::Assignables(assignable) => { - microstatements.append(&mut assignablestatement_to_microstatements(assignable)?) + microstatements.append(&mut assignablestatement_to_microstatements(assignable)?); + } + parse::Statement::Returns(returns) => { + if let Some(retval) = &returns.retval { + // We get all of the microstatements involved in the return statement, then we pop + // off the last one, if any exists, to get the final return value. Then we shove + // the other microstatements into the array and the new Return microstatement with + // that last value attached to it. + let mut retval_microstatements = + withoperatorslist_to_microstatements(&retval.assignables)?; + let value = match retval_microstatements.pop() { + None => None, + Some(v) => Some(Box::new(v)), + }; + if retval_microstatements.len() > 0 { + microstatements.append(&mut retval_microstatements); + } + microstatements.push(Microstatement::Return { value }); + } else { + microstatements.push(Microstatement::Return { value: None }); + } } _ => {} }