Skip to content

Commit

Permalink
feat: add support for the rest of the operations
Browse files Browse the repository at this point in the history
  • Loading branch information
Ph0enixKM committed Sep 28, 2023
1 parent db2cb68 commit 3e228d6
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 27 deletions.
3 changes: 2 additions & 1 deletion src/modules/command/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ impl TranslateModule for CommandExpr {
} else {
let id = meta.gen_value_id();
let quote = meta.gen_quote();
let dollar = meta.gen_dollar();
let translation = translate_interpolated_region(self.strings.clone(), interps, false);
meta.stmt_queue.push_back(format!("__AMBER_VAL_{id}=$({translation}{silent})"));
meta.stmt_queue.push_back(failed);
format!("{quote}${{__AMBER_VAL_{id}}}{quote}")
format!("{quote}{dollar}{{__AMBER_VAL_{id}}}{quote}")
}
}
}
3 changes: 2 additions & 1 deletion src/modules/expression/literal/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ impl TranslateModule for Array {
let name = format!("__AMBER_ARRAY_{}", meta.gen_array_id());
let args = self.exprs.iter().map(|expr| expr.translate_eval(meta, false)).collect::<Vec<String>>().join(" ");
let quote = meta.gen_quote();
let dollar = meta.gen_dollar();
meta.stmt_queue.push_back(format!("{name}=({args})"));
format!("{quote}${{{name}[@]}}{quote}")
format!("{quote}{dollar}{{{name}[@]}}{quote}")
}
}
18 changes: 10 additions & 8 deletions src/modules/function/invocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,13 @@ impl SyntaxModule<ParserMetadata> for FunctionInvocation {
}

impl FunctionInvocation {
fn get_variable(&self, meta: &mut TranslateMetadata, name: &str) -> String {
fn get_variable(&self, meta: &mut TranslateMetadata, name: &str, dollar_override: bool) -> String {
let dollar = dollar_override.then(|| "$").unwrap_or_else(|| meta.gen_dollar());
if matches!(self.kind, Type::Array(_)) {
let quote = meta.gen_quote();
format!("{quote}${{{name}[@]}}{quote}")
format!("{quote}{dollar}{{{name}[@]}}{quote}")
} else {
format!("${{{name}}}")
format!("{dollar}{{{name}}}")
}
}
}
Expand All @@ -121,20 +122,21 @@ impl TranslateModule for FunctionInvocation {
}
}).collect::<Vec<String>>().join(" ");
meta.stmt_queue.push_back(format!("{name} {args}{silent}"));
let invocation_return = self.get_variable(meta, &format!("__AMBER_FUN_{}{}_v{}", self.name, self.id, self.variant_id));
let invocation_instance = self.get_variable(meta, &format!("__AMBER_FUN_{}{}_v{}__{}", self.name, self.id, self.variant_id, self.line));
let invocation_return = &format!("__AMBER_FUN_{}{}_v{}", self.name, self.id, self.variant_id);
let invocation_instance = &format!("__AMBER_FUN_{}{}_v{}__{}", self.name, self.id, self.variant_id, self.line);
let parsed_invocation_return = self.get_variable(meta, invocation_return, true);
if self.is_failable {
let failed = self.failed.translate(meta);
meta.stmt_queue.push_back(failed);
}
meta.stmt_queue.push_back(
format!("__AMBER_FUN_{}{}_v{}__{}={}", self.name, self.id, self.variant_id, self.line, if matches!(self.kind, Type::Array(_)) {
// If the function returns an array we have to store the intermediate result in a variable that is of type array
format!("({})", invocation_return)
format!("({})", parsed_invocation_return)
} else {
invocation_return
parsed_invocation_return
})
);
invocation_instance
self.get_variable(meta, invocation_instance, false)
}
}
13 changes: 10 additions & 3 deletions src/modules/shorthand/div.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 @@ -51,9 +52,15 @@ impl TranslateModule for ShorthandDiv {
.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!("eval \"${{{}}}\"", self.var) } else { self.var.clone() }
None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() }
};
let var = format!("${{{name}}}");
format!("{}={}", name, translate_computation(meta, ArithOp::Div, Some(var), Some(expr)))
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)
} else {
let eval = translate_computation(meta, ArithOp::Div, Some(var), Some(expr));
format!("{}={}", name, eval)
}
}
}
13 changes: 10 additions & 3 deletions src/modules/shorthand/modulo.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 @@ -51,9 +52,15 @@ impl TranslateModule for ShorthandModulo {
.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!("eval \"${{{}}}\"", self.var) } else { self.var.clone() }
None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() }
};
let var = format!("${{{name}}}");
format!("{}={}", name, translate_computation(meta, ArithOp::Modulo, Some(var), Some(expr)))
let var = if self.is_ref { format!("\\${{{name}}}") } else { format!("${{{name}}}") };
if self.is_ref {
let expr = translate_computation_eval(meta, ArithOp::Modulo, Some(var), Some(expr));
format!("eval \"{}={}\"", name, expr)
} else {
let expr = translate_computation(meta, ArithOp::Modulo, Some(var), Some(expr));
format!("{}={}", name, expr)
}
}
}
13 changes: 10 additions & 3 deletions src/modules/shorthand/mul.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 @@ -51,9 +52,15 @@ impl TranslateModule for ShorthandMul {
.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!("eval \"${{{}}}\"", self.var) } else { self.var.clone() }
None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() }
};
let var = format!("${{{name}}}");
format!("{}={}", name, translate_computation(meta, ArithOp::Mul, Some(var), Some(expr)))
let var = if self.is_ref { format!("\\${{{name}}}") } else { format!("${{{name}}}") };
if self.is_ref {
let expr = translate_computation_eval(meta, ArithOp::Mul, Some(var), Some(expr));
format!("eval \"{}={}\"", name, expr)
} else {
let expr = translate_computation(meta, ArithOp::Mul, Some(var), Some(expr));
format!("{}={}", name, expr)
}
}
}
13 changes: 10 additions & 3 deletions src/modules/shorthand/sub.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 @@ -51,9 +52,15 @@ impl TranslateModule for ShorthandSub {
.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!("eval \"${{{}}}\"", self.var) } else { self.var.clone() }
None => if self.is_ref { format!("${{{}}}", self.var) } else { self.var.clone() }
};
let var = format!("${{{name}}}");
format!("{}={}", name, translate_computation(meta, ArithOp::Sub, Some(var), Some(expr)))
let var = if self.is_ref { format!("\\${{{name}}}") } else { format!("${{{name}}}") };
if self.is_ref {
let expr = translate_computation_eval(meta, ArithOp::Sub, Some(var), Some(expr));
format!("eval \"{}={}\"", name, expr)
} else {
let expr = translate_computation(meta, ArithOp::Sub, Some(var), Some(expr));
format!("{}={}", name, expr)
}
}
}
41 changes: 37 additions & 4 deletions src/tests/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,19 +1015,20 @@ fn variable_ref_add_arithmetic_text() {
}

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


#[test]
fn variable_ref_mul_arithmetic_num() {
let code = "
Expand Down Expand Up @@ -1069,3 +1070,35 @@ fn variable_ref_mod_arithmetic_num() {
";
test_amber!(code, "2");
}

#[test]
fn variable_ref_command() {
let code = "
fun foo(ref a) {
a = $echo Test$?
}
let a = \"\"
unsafe foo(a)
echo a
";
test_amber!(code, "Test");
}

#[test]
fn variable_ref_function_invocation() {
let code = "
fun reverse(input: Text): Text {
return unsafe $echo {input} | rev$
}
fun foo(ref a) {
a = reverse(\"mars\")
}
let a = \"\"
unsafe foo(a)
echo a
";
test_amber!(code, "sram");
}
8 changes: 7 additions & 1 deletion src/utils/metadata/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,15 @@ impl TranslateMetadata {
.unwrap_or("\"")
}

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

pub fn gen_dollar(&self) -> &'static str {
self.eval_ctx
.then(|| "\\$")
.unwrap_or_else(|| "$")
}
}

0 comments on commit 3e228d6

Please sign in to comment.