From 15dde037b76deca70bdc74f09282849dd1c7b213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20H=C3=B6lting?= <87192362+moritz-hoelting@users.noreply.github.com> Date: Wed, 13 Aug 2025 18:05:15 +0200 Subject: [PATCH] only use function arg storage if required --- src/transpile/function.rs | 112 +++++++++++++++++++++--------------- src/transpile/transpiler.rs | 83 +++++++++++++++----------- 2 files changed, 115 insertions(+), 80 deletions(-) diff --git a/src/transpile/function.rs b/src/transpile/function.rs index bd5b35e..c695c0f 100644 --- a/src/transpile/function.rs +++ b/src/transpile/function.rs @@ -32,7 +32,7 @@ use super::{ #[derive(Debug, Clone)] pub enum TranspiledFunctionArguments { None, - Static(BTreeMap), + Static(BTreeMap, Vec), Dynamic(Vec), } @@ -430,9 +430,9 @@ impl Transpiler { } if compiled_args.iter().any(|arg| !arg.is_static()) { - let (mut setup_cmds, move_cmds, static_params) = parameters.clone().into_iter().zip(compiled_args).fold( - (Vec::new(), Vec::new(), BTreeMap::new()), - |(mut acc_setup, mut acc_move, mut statics), (param, data)| { + let (require_dyn_params, mut setup_cmds, move_cmds, static_params) = parameters.clone().into_iter().zip(compiled_args).fold( + (false, Vec::new(), Vec::new(), BTreeMap::new()), + |(mut require_dyn_params, mut acc_setup, mut acc_move, mut statics), (param, data)| { match param.variable_type() { FunctionVariableType::Macro(_) => { let arg_name = crate::util::identifier_to_macro(param.identifier().span.str()); @@ -455,6 +455,7 @@ impl Transpiler { }; } Parameter::Storage { prepare_cmds, storage_name, path } => { + require_dyn_params = true; acc_setup.extend(prepare_cmds); acc_move.push(Command::Raw( format!(r"data modify storage shulkerscript:function_arguments {arg_name} set from storage {storage_name} {path}") @@ -495,6 +496,7 @@ impl Transpiler { } }, FunctionVariableType::Boolean(_) => { + require_dyn_params = true; let target_storage_name = format!("shulkerscript:arguments_{}", function_location.replace(['/', ':'], "_")); let param_str = param.identifier().span.str(); let target_path = crate::util::identifier_to_scoreboard_target(param_str); @@ -524,50 +526,67 @@ impl Transpiler { } }, } - (acc_setup, acc_move, statics)}, + (require_dyn_params, acc_setup, acc_move, statics)}, ); - let statics_len = static_params.len(); - let joined_statics = - super::util::join_macro_strings(static_params.into_iter().enumerate().map( - |(i, (k, v))| match v { - MacroString::String(s) => { - let mut s = format!(r#"{k}:"{s}""#); - if i < statics_len - 1 { - s.push(','); + if require_dyn_params { + let statics_len = static_params.len(); + let joined_statics = super::util::join_macro_strings( + static_params + .into_iter() + .enumerate() + .map(|(i, (k, v))| match v { + MacroString::String(s) => { + let mut s = format!(r#"{k}:"{s}""#); + if i < statics_len - 1 { + s.push(','); + } + MacroString::String(s) } - MacroString::String(s) - } - MacroString::MacroString(mut parts) => { - parts.insert(0, MacroStringPart::String(format!(r#"{k}:""#))); - let mut ending = '"'.to_string(); - if i < statics_len - 1 { - ending.push(','); + MacroString::MacroString(mut parts) => { + parts.insert( + 0, + MacroStringPart::String(format!(r#"{k}:""#)), + ); + let mut ending = '"'.to_string(); + if i < statics_len - 1 { + ending.push(','); + } + parts.push(MacroStringPart::String(ending)); + MacroString::MacroString(parts) } - parts.push(MacroStringPart::String(ending)); - MacroString::MacroString(parts) - } - }, - )); - let statics_cmd = match joined_statics { - MacroString::String(s) => Command::Raw(format!( - r"data merge storage shulkerscript:function_arguments {{{s}}}" - )), - MacroString::MacroString(_) => Command::UsesMacro( - super::util::join_macro_strings([ - MacroString::String( - "data merge storage shulkerscript:function_arguments {" - .to_string(), - ), - joined_statics, - MacroString::String("}".to_string()), - ]) - .into(), - ), - }; - setup_cmds.push(statics_cmd); - setup_cmds.extend(move_cmds); + }), + ); + let storage_suffix = function_location.replace(['/', ':'], "_"); + let statics_cmd = match joined_statics { + MacroString::String(s) => Command::Raw(format!( + r"data merge storage shulkerscript:function_arguments_{storage_suffix} {{{s}}}" + )), + MacroString::MacroString(_) => { + let prefix = MacroString::String( + format!("data merge storage shulkerscript:function_arguments_{storage_suffix} {{"), + ); + Command::UsesMacro( + super::util::join_macro_strings([ + prefix, + joined_statics, + MacroString::String("}".to_string()), + ]) + .into(), + ) + } + }; + setup_cmds.push(statics_cmd); + setup_cmds.extend(move_cmds); - Ok(TranspiledFunctionArguments::Dynamic(setup_cmds)) + Ok(TranspiledFunctionArguments::Dynamic(setup_cmds)) + } else { + setup_cmds.extend(move_cmds); + + Ok(TranspiledFunctionArguments::Static( + static_params, + setup_cmds, + )) + } } else { let function_args = parameters .clone() @@ -579,7 +598,10 @@ impl Transpiler { ) .map(|(k, v)| (k.identifier().span.str().to_string(), v)) .collect(); - Ok(TranspiledFunctionArguments::Static(function_args)) + Ok(TranspiledFunctionArguments::Static( + function_args, + Vec::new(), + )) } } _ => Ok(TranspiledFunctionArguments::None), diff --git a/src/transpile/transpiler.rs b/src/transpile/transpiler.rs index bcd22b0..7b9e3dd 100644 --- a/src/transpile/transpiler.rs +++ b/src/transpile/transpiler.rs @@ -703,48 +703,61 @@ impl Transpiler { )?; let mut function_call = format!("function {location}"); match arguments { - TranspiledFunctionArguments::Static(arguments) => { + TranspiledFunctionArguments::Static(arguments, mut setup_cmds) => { use std::fmt::Write; - let arguments_iter = arguments.iter().map(|(ident, v)| match v { - MacroString::String(s) => MacroString::String(format!( - r#"{macro_name}:"{escaped}""#, - macro_name = crate::util::identifier_to_macro(ident), - escaped = crate::util::escape_str(s) - )), - MacroString::MacroString(parts) => MacroString::MacroString( - std::iter::once(MacroStringPart::String(format!( - r#"{macro_name}:""#, - macro_name = crate::util::identifier_to_macro(ident) - ))) - .chain(parts.clone().into_iter().map(|part| match part { - MacroStringPart::String(s) => { - MacroStringPart::String(crate::util::escape_str(&s).to_string()) - } - macro_usage @ MacroStringPart::MacroUsage(_) => macro_usage, - })) - .chain(std::iter::once(MacroStringPart::String('"'.to_string()))) - .collect(), - ), - }); - let arguments = super::util::join_macro_strings(arguments_iter); - let cmd = match arguments { - MacroString::String(arguments) => { - write!(function_call, " {{{arguments}}}").unwrap(); - Command::Raw(function_call) - } - MacroString::MacroString(mut parts) => { - function_call.push_str(" {"); - parts.insert(0, MacroStringPart::String(function_call)); - parts.push(MacroStringPart::String('}'.to_string())); - Command::UsesMacro(MacroString::MacroString(parts).into()) + let cmd = if arguments.is_empty() { + Command::Raw(function_call) + } else { + let arguments_iter = arguments.iter().map(|(ident, v)| match v { + MacroString::String(s) => MacroString::String(format!( + r#"{macro_name}:"{escaped}""#, + macro_name = crate::util::identifier_to_macro(ident), + escaped = crate::util::escape_str(s) + )), + MacroString::MacroString(parts) => MacroString::MacroString( + std::iter::once(MacroStringPart::String(format!( + r#"{macro_name}:""#, + macro_name = crate::util::identifier_to_macro(ident) + ))) + .chain(parts.clone().into_iter().map(|part| match part { + MacroStringPart::String(s) => MacroStringPart::String( + crate::util::escape_str(&s).to_string(), + ), + macro_usage @ MacroStringPart::MacroUsage(_) => macro_usage, + })) + .chain(std::iter::once(MacroStringPart::String('"'.to_string()))) + .collect(), + ), + }); + let arguments = super::util::join_macro_strings(arguments_iter); + + match arguments { + MacroString::String(arguments) => { + write!(function_call, " {{{arguments}}}").unwrap(); + Command::Raw(function_call) + } + MacroString::MacroString(mut parts) => { + function_call.push_str(" {"); + parts.insert(0, MacroStringPart::String(function_call)); + parts.push(MacroStringPart::String('}'.to_string())); + Command::UsesMacro(MacroString::MacroString(parts).into()) + } } }; - Ok(vec![cmd]) + setup_cmds.push(cmd); + + Ok(setup_cmds) } TranspiledFunctionArguments::Dynamic(mut cmds) => { - function_call.push_str(" with storage shulkerscript:function_arguments"); + use std::fmt::Write as _; + + let _ = write!( + function_call, + " with storage shulkerscript:function_arguments_{suffix}", + suffix = location.replace(['/', ':'], "_") + ); cmds.push(Command::Raw(function_call)); Ok(cmds) }