From 520c07a6740a3eceb842a6586f7798097a7b2820 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Tue, 12 Mar 2024 16:44:41 -0700 Subject: [PATCH] Keep track of mutability in microstatements, afterall (#673) --- src/lntors/function.rs | 4 ++-- src/program.rs | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/lntors/function.rs b/src/lntors/function.rs index 21972f4c..bb593182 100644 --- a/src/lntors/function.rs +++ b/src/lntors/function.rs @@ -13,12 +13,12 @@ pub fn from_microstatement( ) -> Result<(String, OrderedHashMap), Box> { match microstatement { Microstatement::Arg { .. } => Ok(("".to_string(), out)), // Skip arg microstatements that are just used for discovery during generation - Microstatement::Assignment { name, value } => { + Microstatement::Assignment { name, value, mutable } => { let (val, o) = from_microstatement(value, scope, program, out)?; // I wish I didn't have to write the following line because you can't re-assign a // variable in a let destructuring, afaict out = o; - Ok((format!("let {} = {}", name, val,).to_string(), out)) + Ok((format!("let {} {} = {}", if *mutable { "mut" } else { "" }, name, val,).to_string(), out)) } Microstatement::Value { typen, diff --git a/src/program.rs b/src/program.rs index d948317a..b5901cd2 100644 --- a/src/program.rs +++ b/src/program.rs @@ -392,6 +392,7 @@ impl Const { #[derive(Debug)] pub enum Microstatement { Assignment { + mutable: bool, name: String, value: Box, }, @@ -526,6 +527,7 @@ fn baseassignablelist_to_microstatements( Microstatement::Assignment { ref name, ref value, + .. } => { // If the last microstatement is an assignment, we need to // reference it as a value and push it back onto the array @@ -572,7 +574,7 @@ fn baseassignablelist_to_microstatements( let mut first_microstatement = None; for microstatement in microstatements.iter().rev() { match µstatement { - Microstatement::Assignment { name, value } if name == &first_var.to_string() => { + Microstatement::Assignment { name, value, .. } if name == &first_var.to_string() => { first_microstatement = Some(Microstatement::Value { typen: value.get_type(scope, program)?, representation: first_var.to_string(), @@ -969,12 +971,9 @@ fn declarations_to_microstatements( program: &Program, mut microstatements: Vec, ) -> Result, Box> { - // We don't care about const vs let in the microstatement world, everything is - // immutable and we just create a crap-ton of variables. TODO: We might have - // user-provided type declaration data we should look into, at least as a sanity check? - let (name, assignables) = match &declarations { - parse::Declarations::Const(c) => (c.variable.clone(), &c.assignables), - parse::Declarations::Let(l) => (l.variable.clone(), &l.assignables), + let (name, assignables, mutable) = match &declarations { + parse::Declarations::Const(c) => (c.variable.clone(), &c.assignables, false), + parse::Declarations::Let(l) => (l.variable.clone(), &l.assignables, true), }; // Get all of the assignable microstatements generated microstatements = @@ -983,7 +982,7 @@ fn declarations_to_microstatements( None => Err("An assignment without a value should be impossible."), Some(v) => Ok(Box::new(v)), }?; - microstatements.push(Microstatement::Assignment { name, value }); + microstatements.push(Microstatement::Assignment { name, value, mutable }); Ok(microstatements) }