From 188abb45436c5987f103fee782c1de44d3a50e44 Mon Sep 17 00:00:00 2001 From: hdwalters Date: Thu, 7 Nov 2024 17:25:59 +0000 Subject: [PATCH] Builtin lines function part I - Refactoring (#565) --- src/modules/expression/binop/add.rs | 7 ++-- src/modules/shorthand/add.rs | 56 ++++++++++++++++++----------- src/modules/shorthand/div.rs | 26 ++++++++------ src/modules/shorthand/modulo.rs | 22 +++++++----- src/modules/shorthand/mul.rs | 22 +++++++----- src/modules/shorthand/sub.rs | 22 +++++++----- src/modules/variable/init.rs | 12 ++++--- src/modules/variable/set.rs | 46 +++++++++++++----------- 8 files changed, 127 insertions(+), 86 deletions(-) diff --git a/src/modules/expression/binop/add.rs b/src/modules/expression/binop/add.rs index f7f9a1b0..d23caf64 100644 --- a/src/modules/expression/binop/add.rs +++ b/src/modules/expression/binop/add.rs @@ -62,12 +62,13 @@ impl TranslateModule for Add { fn translate(&self, meta: &mut TranslateMetadata) -> String { let left = self.left.translate_eval(meta, false); let right = self.right.translate_eval(meta, false); - let quote = meta.gen_quote(); match self.kind { Type::Array(_) => { + let quote = meta.gen_quote(); let id = meta.gen_array_id(); - meta.stmt_queue.push_back(format!("__AMBER_ARRAY_ADD_{id}=({left} {right})")); - format!("{quote}${{__AMBER_ARRAY_ADD_{id}[@]}}{quote}") + let name = format!("__AMBER_ARRAY_ADD_{id}"); + meta.stmt_queue.push_back(format!("{name}=({left} {right})")); + format!("{quote}${{{name}[@]}}{quote}") }, Type::Text => format!("{}{}", left, right), _ => translate_computation(meta, ArithOp::Add, Some(left), Some(right)) diff --git a/src/modules/shorthand/add.rs b/src/modules/shorthand/add.rs index 792a5a6c..0afeb2ea 100644 --- a/src/modules/shorthand/add.rs +++ b/src/modules/shorthand/add.rs @@ -48,31 +48,47 @@ impl SyntaxModule for ShorthandAdd { } impl TranslateModule for ShorthandAdd { + //noinspection DuplicatedCode fn translate(&self, meta: &mut TranslateMetadata) -> String { - let expr = self.is_ref - .then(|| self.expr.translate_eval(meta, true)) - .unwrap_or_else(|| self.expr.translate(meta)); - let name: String = match self.global_id { - Some(id) => format!("__{id}_{}", self.var), - None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() } + let name = if let Some(id) = self.global_id { + format!("__{id}_{}", self.var) + } else if self.is_ref { + format!("${{{}}}", self.var) + } else { + self.var.clone() }; - let stmt = match self.kind { - Type::Text => format!("{}+={}", name, expr), - Type::Array(_) => format!("{}+=({})", name, expr), + match self.kind { + Type::Text => { + if self.is_ref { + let expr = self.expr.translate_eval(meta, true); + format!("eval \"{name}+={expr}\"") + } else { + let expr = self.expr.translate(meta); + format!("{name}+={expr}") + } + } + Type::Array(_) => { + if self.is_ref { + let expr = self.expr.translate_eval(meta, true); + format!("eval \"{name}+=({expr})\"") + } else { + let expr = self.expr.translate(meta); + format!("{name}+=({expr})") + } + } _ => { - let var = if self.is_ref { format!("\\${{{name}}}") } else { format!("${{{name}}}") }; - let translated_computation = if self.is_ref { - translate_computation_eval(meta, ArithOp::Add, Some(var), Some(expr)) + if self.is_ref { + let var = format!("\\${{{name}}}"); + let expr = self.expr.translate_eval(meta, true); + let expr = translate_computation_eval(meta, ArithOp::Add, Some(var), Some(expr)); + format!("eval \"{name}={expr}\"") } else { - translate_computation(meta, ArithOp::Add, Some(var), Some(expr)) - }; - format!("{}={}", name, translated_computation) + let var = format!("${{{name}}}"); + let expr = self.expr.translate(meta); + let expr = translate_computation(meta, ArithOp::Add, Some(var), Some(expr)); + format!("{name}={expr}") + } } - }; - if self.is_ref { - format!("eval \"{}\"", stmt) - } else { - stmt } } } diff --git a/src/modules/shorthand/div.rs b/src/modules/shorthand/div.rs index 99d372c6..79a68d9b 100644 --- a/src/modules/shorthand/div.rs +++ b/src/modules/shorthand/div.rs @@ -48,21 +48,25 @@ impl SyntaxModule for ShorthandDiv { } impl TranslateModule for ShorthandDiv { + //noinspection DuplicatedCode fn translate(&self, meta: &mut TranslateMetadata) -> String { - let expr = self.is_ref - .then(|| self.expr.translate_eval(meta, true)) - .unwrap_or_else(|| self.expr.translate(meta)); - let name = match self.global_id { - Some(id) => format!("__{id}_{}", self.var), - None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() } + let name = if let Some(id) = self.global_id { + format!("__{id}_{}", self.var) + } else if self.is_ref { + format!("${{{}}}", self.var) + } else { + self.var.clone() }; - let var = if self.is_ref { format!("\\${{{name}}}") } else { format!("${{{name}}}") }; if self.is_ref { - let eval = translate_computation_eval(meta, ArithOp::Div, Some(var), Some(expr)); - format!("eval \"{}={}\"", name, eval) + let var = format!("\\${{{name}}}"); + let expr = self.expr.translate_eval(meta, true); + let expr = translate_computation_eval(meta, ArithOp::Div, Some(var), Some(expr)); + format!("eval \"{name}={expr}\"") } else { - let eval = translate_computation(meta, ArithOp::Div, Some(var), Some(expr)); - format!("{}={}", name, eval) + let var = format!("${{{name}}}"); + let expr = self.expr.translate(meta); + let expr = translate_computation(meta, ArithOp::Div, Some(var), Some(expr)); + format!("{name}={expr}") } } } diff --git a/src/modules/shorthand/modulo.rs b/src/modules/shorthand/modulo.rs index 1b234ce9..f9f92ff9 100644 --- a/src/modules/shorthand/modulo.rs +++ b/src/modules/shorthand/modulo.rs @@ -48,21 +48,25 @@ impl SyntaxModule for ShorthandModulo { } impl TranslateModule for ShorthandModulo { + //noinspection DuplicatedCode fn translate(&self, meta: &mut TranslateMetadata) -> String { - let expr = self.is_ref - .then(|| self.expr.translate_eval(meta, true)) - .unwrap_or_else(|| self.expr.translate(meta)); - let name = match self.global_id { - Some(id) => format!("__{id}_{}", self.var), - None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() } + let name = if let Some(id) = self.global_id { + format!("__{id}_{}", self.var) + } else if self.is_ref { + format!("${{{}}}", self.var) + } else { + self.var.clone() }; - let var = if self.is_ref { format!("\\${{{name}}}") } else { format!("${{{name}}}") }; if self.is_ref { + let var = format!("\\${{{name}}}"); + let expr = self.expr.translate_eval(meta, true); let expr = translate_computation_eval(meta, ArithOp::Modulo, Some(var), Some(expr)); - format!("eval \"{}={}\"", name, expr) + format!("eval \"{name}={expr}\"") } else { + let var = format!("${{{name}}}"); + let expr = self.expr.translate(meta); let expr = translate_computation(meta, ArithOp::Modulo, Some(var), Some(expr)); - format!("{}={}", name, expr) + format!("{name}={expr}") } } } diff --git a/src/modules/shorthand/mul.rs b/src/modules/shorthand/mul.rs index a601b0e1..7d06c87e 100644 --- a/src/modules/shorthand/mul.rs +++ b/src/modules/shorthand/mul.rs @@ -48,21 +48,25 @@ impl SyntaxModule for ShorthandMul { } impl TranslateModule for ShorthandMul { + //noinspection DuplicatedCode fn translate(&self, meta: &mut TranslateMetadata) -> String { - let expr = self.is_ref - .then(|| self.expr.translate_eval(meta, true)) - .unwrap_or_else(|| self.expr.translate(meta)); - let name = match self.global_id { - Some(id) => format!("__{id}_{}", self.var), - None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() } + let name = if let Some(id) = self.global_id { + format!("__{id}_{}", self.var) + } else if self.is_ref { + format!("${{{}}}", self.var) + } else { + self.var.clone() }; - let var = if self.is_ref { format!("\\${{{name}}}") } else { format!("${{{name}}}") }; if self.is_ref { + let var = format!("\\${{{name}}}"); + let expr = self.expr.translate_eval(meta, true); let expr = translate_computation_eval(meta, ArithOp::Mul, Some(var), Some(expr)); - format!("eval \"{}={}\"", name, expr) + format!("eval \"{name}={expr}\"") } else { + let var = format!("${{{name}}}"); + let expr = self.expr.translate(meta); let expr = translate_computation(meta, ArithOp::Mul, Some(var), Some(expr)); - format!("{}={}", name, expr) + format!("{name}={expr}") } } } diff --git a/src/modules/shorthand/sub.rs b/src/modules/shorthand/sub.rs index 6334c040..0aed82cc 100644 --- a/src/modules/shorthand/sub.rs +++ b/src/modules/shorthand/sub.rs @@ -48,21 +48,25 @@ impl SyntaxModule for ShorthandSub { } impl TranslateModule for ShorthandSub { + //noinspection DuplicatedCode fn translate(&self, meta: &mut TranslateMetadata) -> String { - let expr = self.is_ref - .then(|| self.expr.translate_eval(meta, true)) - .unwrap_or_else(|| self.expr.translate(meta)); - let name = match self.global_id { - Some(id) => format!("__{id}_{}", self.var), - None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() } + let name = if let Some(id) = self.global_id { + format!("__{id}_{}", self.var) + } else if self.is_ref { + format!("${{{}}}", self.var) + } else { + self.var.clone() }; - let var = if self.is_ref { format!("\\${{{name}}}") } else { format!("${{{name}}}") }; if self.is_ref { + let var = format!("\\${{{name}}}"); + let expr = self.expr.translate_eval(meta, true); let expr = translate_computation_eval(meta, ArithOp::Sub, Some(var), Some(expr)); - format!("eval \"{}={}\"", name, expr) + format!("eval \"{name}={expr}\"") } else { + let var = format!("${{{name}}}"); + let expr = self.expr.translate(meta); let expr = translate_computation(meta, ArithOp::Sub, Some(var), Some(expr)); - format!("{}={}", name, expr) + format!("{name}={expr}") } } } diff --git a/src/modules/variable/init.rs b/src/modules/variable/init.rs index 2638db00..ad4171c8 100644 --- a/src/modules/variable/init.rs +++ b/src/modules/variable/init.rs @@ -55,14 +55,16 @@ impl SyntaxModule for VariableInit { impl TranslateModule for VariableInit { fn translate(&self, meta: &mut TranslateMetadata) -> String { let name = self.name.clone(); - let mut expr = self.expr.translate(meta); + let mut expr = self.expr.translate(meta); if let Type::Array(_) = self.expr.get_type() { expr = format!("({expr})"); } - let local = if self.is_fun_ctx { "local " } else { "" }; - match self.global_id { - Some(id) => format!("__{id}_{name}={expr}"), - None => format!("{local}{name}={expr}") + if let Some(id) = self.global_id { + format!("__{id}_{name}={expr}") + } else if self.is_fun_ctx { + format!("local {name}={expr}") + } else { + format!("{name}={expr}") } } } diff --git a/src/modules/variable/set.rs b/src/modules/variable/set.rs index 6a03ca7c..94fe4031 100644 --- a/src/modules/variable/set.rs +++ b/src/modules/variable/set.rs @@ -8,19 +8,29 @@ use crate::modules::types::{Typed, Type}; #[derive(Debug, Clone)] pub struct VariableSet { name: String, - value: Box, + expr: Box, global_id: Option, index: Option, is_ref: bool } +impl VariableSet { + fn translate_eval_if_ref(&self, expr: &Expr, meta: &mut TranslateMetadata) -> String { + if self.is_ref { + expr.translate_eval(meta, true) + } else { + expr.translate(meta) + } + } +} + impl SyntaxModule for VariableSet { syntax_name!("Variable Set"); fn new() -> Self { VariableSet { name: String::new(), - value: Box::new(Expr::new()), + expr: Box::new(Expr::new()), global_id: None, index: None, is_ref: false @@ -32,13 +42,13 @@ impl SyntaxModule for VariableSet { self.name = variable(meta, variable_name_extensions())?; self.index = handle_index_accessor(meta)?; token(meta, "=")?; - syntax(meta, &mut *self.value)?; + syntax(meta, &mut *self.expr)?; let variable = handle_variable_reference(meta, tok.clone(), &self.name)?; self.global_id = variable.global_id; self.is_ref = variable.is_ref; // Typecheck the variable let left_type = variable.kind.clone(); - let right_type = self.value.get_type(); + let right_type = self.expr.get_type(); // Check if the variable can be indexed if self.index.is_some() && !matches!(variable.kind, Type::Array(_)) { return error!(meta, tok, format!("Cannot assign a value to an index of a non-array variable of type '{left_type}'")); @@ -47,14 +57,14 @@ impl SyntaxModule for VariableSet { if self.index.is_some() { // Check if the assigned value is compatible with the array if let Type::Array(kind) = variable.kind.clone() { - if *kind != self.value.get_type() { - let right_type = self.value.get_type(); + if *kind != self.expr.get_type() { + let right_type = self.expr.get_type(); return error!(meta, tok, format!("Cannot assign value of type '{right_type}' to an array of '{kind}'")); } } } // Check if the variable is compatible with the assigned value - else if variable.kind != self.value.get_type() { + else if variable.kind != self.expr.get_type() { return error!(meta, tok, format!("Cannot assign value of type '{right_type}' to a variable of type '{left_type}'")); } Ok(()) @@ -65,23 +75,19 @@ impl TranslateModule for VariableSet { fn translate(&self, meta: &mut TranslateMetadata) -> String { let name = self.name.clone(); let index = self.index.as_ref() - .map(|index| format!("[{}]", self.is_ref - .then(|| index.translate_eval(meta, true)) - .unwrap_or_else(|| index.translate(meta)))) + .map(|index| self.translate_eval_if_ref(index, meta)) + .map(|index| format!("[{index}]")) .unwrap_or_default(); - let mut expr = self.is_ref - .then(|| self.value.translate_eval(meta, true)) - .unwrap_or_else(|| self.value.translate(meta)); - if let Type::Array(_) = self.value.get_type() { - expr = format!("({})", expr); + let mut expr = self.translate_eval_if_ref(self.expr.as_ref(), meta); + if let Type::Array(_) = self.expr.get_type() { + expr = format!("({expr})"); } - if self.is_ref { + if let Some(id) = self.global_id { + format!("__{id}_{name}{index}={expr}") + } else if self.is_ref { format!("eval \"${{{name}}}{index}={expr}\"") } else { - match self.global_id { - Some(id) => format!("__{id}_{name}{index}={expr}"), - None => format!("{name}{index}={expr}") - } + format!("{name}{index}={expr}") } } }