Skip to content

Commit

Permalink
feat: ref feature support for variable assignment and addition
Browse files Browse the repository at this point in the history
  • Loading branch information
Ph0enixKM committed Sep 27, 2023
1 parent 6c26276 commit db2cb68
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 13 deletions.
3 changes: 2 additions & 1 deletion src/modules/command/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ impl TranslateModule for CommandExpr {
let failed = self.failed.translate(meta);
let silent = self.is_silent_expr.then(|| " 2>/dev/null").unwrap_or("");
if failed.is_empty() {
format!("$({}{silent})", translate_interpolated_region(self.strings.clone(), interps, false))
let translation = translate_interpolated_region(self.strings.clone(), interps, false);
meta.gen_subprocess(&(translation + silent))
} else {
let id = meta.gen_value_id();
let quote = meta.gen_quote();
Expand Down
2 changes: 1 addition & 1 deletion src/modules/condition/ternary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ impl TranslateModule for Ternary {
let cond = self.cond.translate(meta);
let true_expr = self.true_expr.translate(meta);
let false_expr = self.false_expr.translate(meta);
format!("$(if [ {} != 0 ]; then echo {}; else echo {}; fi)", cond, true_expr, false_expr)
meta.gen_subprocess(&format!("if [ {} != 0 ]; then echo {}; else echo {}; fi", cond, true_expr, false_expr))
}
}
2 changes: 1 addition & 1 deletion src/modules/expression/binop/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl TranslateModule for Eq {
if self.left.get_type() == Type::Text && self.right.get_type() == Type::Text {
strip_text_quotes(&mut left);
strip_text_quotes(&mut right);
format!("$([ \"_{left}\" != \"_{right}\" ]; echo $?)")
meta.gen_subprocess(&format!("[ \"_{left}\" != \"_{right}\" ]; echo $?"))
} else {
translate_computation(meta, ArithOp::Eq, Some(left), Some(right))
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/expression/binop/neq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl TranslateModule for Neq {
if self.left.get_type() == Type::Text && self.right.get_type() == Type::Text {
strip_text_quotes(&mut left);
strip_text_quotes(&mut right);
format!("$([ \"_{left}\" == \"_{right}\" ]; echo $?)")
meta.gen_subprocess(&format!("[ \"_{left}\" == \"_{right}\" ]; echo $?"))
} else {
translate_computation(meta, ArithOp::Neq, Some(left), Some(right))
}
Expand Down
4 changes: 2 additions & 2 deletions src/modules/expression/literal/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ impl TranslateModule for Range {
let to = self.to.translate(meta);
if self.neq {
let to_neq = translate_computation(meta, ArithOp::Sub, Some(to), Some("1".to_string()));
format!("$(seq {} {})", from, to_neq)
meta.gen_subprocess(&format!("seq {} {}", from, to_neq))
} else {
format!("$(seq {} {})", from, to)
meta.gen_subprocess(&format!("seq {} {}", from, to))
}
}
}
21 changes: 16 additions & 5 deletions src/modules/shorthand/add.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use heraclitus_compiler::prelude::*;
use crate::modules::expression::{expr::Expr, binop::expression_arms_of_type};
use crate::modules::variable::{variable_name_extensions, handle_variable_reference};
use crate::translate::compute::translate_computation_eval;
use crate::utils::{ParserMetadata, TranslateMetadata};
use crate::translate::{module::TranslateModule, compute::{ArithOp, translate_computation}};
use crate::modules::types::{Type, Typed};
Expand Down Expand Up @@ -49,17 +50,27 @@ impl TranslateModule for ShorthandAdd {
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 {
let name: String = match self.global_id {
Some(id) => format!("__{id}_{}", self.var),
None => if self.is_ref { format!("eval \"${{{}}}\"", self.var) } else { self.var.clone() }
None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() }
};
match self.kind {
let stmt = match self.kind {
Type::Text => format!("{}+={}", name, expr),
Type::Array(_) => format!("{}+=({})", name, expr),
_ => {
let var = format!("${{{name}}}");
format!("{}={}", name, translate_computation(meta, ArithOp::Add, Some(var), Some(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))
} else {
translate_computation(meta, ArithOp::Add, Some(var), Some(expr))
};
format!("{}={}", name, translated_computation)
}
};
if self.is_ref {
format!("eval \"{}\"", stmt)
} else {
stmt
}
}
}
226 changes: 225 additions & 1 deletion src/tests/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,4 +844,228 @@ fn chained_modifiers_functions() {
silent bar()
";
test_amber!(code, "one\ntwo");
}
}

#[test]
fn variable_ref_set_text() {
let code = "
fun foo(ref a) {
a = \"one\"
}
let a = \"two\"
foo(a)
echo a
";
test_amber!(code, "one");
}

#[test]
fn variable_ref_set_num() {
let code = "
fun foo(ref a) {
a = 42
}
let a = 24
foo(a)
echo a
";
test_amber!(code, "42");
}

#[test]
fn variable_ref_set_bool() {
let code = "
fun foo(ref a) {
a = false
}
let a = true
foo(a)
echo a
";
test_amber!(code, "0");
}

#[test]
fn variable_ref_set_array() {
let code = "
fun foo(ref a) {
a = [1, 2, 3]
}
let a = [3, 2, 1]
foo(a)
echo a
";
test_amber!(code, "1 2 3");
}

#[test]
fn variable_ref_add_shorthand_text() {
let code = "
fun foo(ref a) {
a += \"one\"
}
let a = \"two\"
foo(a)
echo a
";
test_amber!(code, "twoone");
}

#[test]
fn variable_ref_add_shorthand_num() {
let code = "
fun foo(ref a) {
a += 12
}
let a = 24
foo(a)
echo a
";
test_amber!(code, "36");
}

#[test]
fn variable_ref_add_shorthand_array() {
let code = "
fun foo(ref a) {
a += [4, 5, 6]
}
let a = [1, 2, 3]
foo(a)
echo a
";
test_amber!(code, "1 2 3 4 5 6");
}

#[test]
fn variable_ref_sub_shorthand_num() {
let code = "
fun foo(ref a) {
a -= 12
}
let a = 36
foo(a)
echo a
";
test_amber!(code, "24");
}

#[test]
fn variable_ref_mul_shorthand_num() {
let code = "
fun foo(ref a) {
a *= 2
}
let a = 6
foo(a)
echo a
";
test_amber!(code, "12");
}

#[test]
fn variable_ref_div_shorthand_num() {
let code = "
fun foo(ref a) {
a /= 3
}
let a = 15
foo(a)
echo a
";
test_amber!(code, "5");
}

#[test]
fn variable_ref_mod_shorthand_num() {
let code = "
fun foo(ref a) {
a %= 5
}
let a = 17
foo(a)
echo a
";
test_amber!(code, "2");
}

#[test]
fn variable_ref_add_arithmetic_text() {
let code = "
fun foo(ref a, b) {
a = a + b
}
let a = \"two\"
foo(a, \"one\")
echo a
";
test_amber!(code, "twoone");
}

#[test]
fn variable_ref_sub_arithmetic_text() {
let code = "
fun foo(ref a, b) {
a = a - b
}
let a = \"twoone\"
foo(a, \"one\")
echo a
";
test_amber!(code, "two");
}

#[test]
fn variable_ref_mul_arithmetic_num() {
let code = "
fun foo(ref a, b) {
a = a * b
}
let a = 6
foo(a, 2)
echo a
";
test_amber!(code, "12");
}

#[test]
fn variable_ref_div_arithmetic_num() {
let code = "
fun foo(ref a, b) {
a = a / b
}
let a = 15
foo(a, 3)
echo a
";
test_amber!(code, "5");
}

#[test]
fn variable_ref_mod_arithmetic_num() {
let code = "
fun foo(ref a, b) {
a = a % b
}
let a = 17
foo(a, 5)
echo a
";
test_amber!(code, "2");
}
10 changes: 9 additions & 1 deletion src/translate/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,15 @@ pub fn translate_computation(meta: &mut TranslateMetadata, operation: ArithOp, l
ArithOp::Or => "||"
};
let math_lib_flag = if math_lib_flag { "-l" } else { "" };
format!("$(echo {left} '{op}' {right} | bc {math_lib_flag} | sed '{sed_regex}')")
meta.gen_subprocess(&format!("echo {left} '{op}' {right} | bc {math_lib_flag} | sed '{sed_regex}'"))
}
}
}

pub fn translate_computation_eval(meta: &mut TranslateMetadata, operation: ArithOp, left: Option<String>, right: Option<String>) -> String {
let old_eval = meta.eval_ctx;
meta.eval_ctx = true;
let result = translate_computation(meta, operation, left, right);
meta.eval_ctx = old_eval;
return result;
}
6 changes: 6 additions & 0 deletions src/utils/metadata/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,10 @@ impl TranslateMetadata {
.then(|| "\\\"")
.unwrap_or("\"")
}

pub fn gen_subprocess(&mut self, stmt: &str) -> String {
self.eval_ctx
.then(|| format!("$(eval \"{}\")", stmt))
.unwrap_or_else(|| format!("$({})", stmt))
}
}

0 comments on commit db2cb68

Please sign in to comment.