Skip to content

Commit

Permalink
fix: validity tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Ph0enixKM committed Mar 1, 2025
1 parent 4d99bfe commit 2285055
Show file tree
Hide file tree
Showing 35 changed files with 230 additions and 136 deletions.
12 changes: 7 additions & 5 deletions src/modules/block.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::VecDeque;
use std::ops::Index;

use crate::fragments;
use crate::modules::prelude::*;
use heraclitus_compiler::prelude::*;
use itertools::Itertools;
Expand Down Expand Up @@ -71,10 +70,13 @@ impl TranslateModule for Block {
// Save the current statement queue and create a new one
let mut new_queue = VecDeque::new();
std::mem::swap(&mut meta.stmt_queue, &mut new_queue);
let result = if self.is_empty() {
fragments!(":")
} else {
let statements = self.statements.iter().map(|statement| statement.translate(meta)).collect();
let result = {
let mut statements = vec![];
for statement in &self.statements {
let statement = statement.translate(meta);
statements.extend(meta.stmt_queue.drain(..));
statements.push(statement);
}
BlockFragment::new(statements, self.should_indent).to_frag()
};
// Restore the old statement queue
Expand Down
2 changes: 1 addition & 1 deletion src/modules/builtin/len.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl TranslateModule for Len {
fn translate(&self, meta: &mut TranslateMetadata) -> TranslationFragment {
let value = self.value.translate(meta);
let id = meta.gen_value_id();
let var_fragment = meta.push_stmt_variable("__length", Some(id), Type::Num, value).set_get_length();
let var_fragment = meta.push_stmt_variable_lazy("__length", Some(id), Type::Num, value).set_get_length();
var_fragment.to_frag()
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/builtin/lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl TranslateModule for LinesInvocation {
.expect("Cannot read lines without provided path");
let indent = TranslateMetadata::single_indent();
let id = meta.gen_value_id();
let value = meta.push_stmt_variable("__array", Some(id), Type::array_of(Type::Text), fragments!("()"));
let value = meta.push_stmt_variable_lazy("__array", Some(id), Type::array_of(Type::Text), TranslationFragment::Empty);
meta.stmt_queue.extend([
fragments!(raw: "while IFS= read -r {temp}; do"),
fragments!(raw: "{indent}{}+=(\"${}\")", value.get_name(), temp),
Expand Down
6 changes: 3 additions & 3 deletions src/modules/command/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl Command {
fn translate_command(&self, meta: &mut TranslateMetadata, is_statement: bool) -> TranslationFragment {
// Translate all interpolations
let interps = self.interps.iter()
.map(|item| item.translate(meta))
.map(|item| item.translate(meta).unquote())
.collect::<Vec<TranslationFragment>>();
let failed = self.failed.translate(meta);

Expand All @@ -81,10 +81,10 @@ impl Command {
}

if let TranslationFragment::Empty = failed {
meta.gen_subprocess(translation)
SubprocessFragment::new(translation).to_frag()
} else {
let id = meta.gen_value_id();
let value = fragments!("$(", translation, ")");
let value = SubprocessFragment::new(translation).to_frag();
let variable = meta.push_stmt_variable("__command", Some(id), Type::Text, value);
meta.stmt_queue.push_back(failed);
variable.to_frag()
Expand Down
12 changes: 9 additions & 3 deletions src/modules/condition/failed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,17 @@ impl TranslateModule for Failed {
fragments!("fi"),
], false).to_frag()
}
if let TranslationFragment::Empty = block {
return fragments!("__status=$?")
match &block {
TranslationFragment::Empty => {
return fragments!("__status=$?")
},
TranslationFragment::Block(block) if block.is_empty() => {
return fragments!("__status=$?")
},
_ => {}
}
BlockFragment::new(vec![
fragments!("__status=$?;"),
fragments!("__status=$?"),
fragments!("if [ $__status != 0 ]; then"),
block,
fragments!("fi"),
Expand Down
4 changes: 2 additions & 2 deletions src/modules/expression/binop/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ impl TranslateModule for Add {
match self.kind {
Type::Array(_) => {
let id = meta.gen_value_id();
let value = fragments!("(", left, " ", right, ")");
let var = meta.push_stmt_variable("__array_add", Some(id), self.kind.clone(), value);
let value = fragments!(left, " ", right);
let var = meta.push_stmt_variable_lazy("__array_add", Some(id), self.kind.clone(), value);
var.to_frag()
},
Type::Text => fragments!(left, right),
Expand Down
2 changes: 1 addition & 1 deletion src/modules/expression/binop/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl TranslateModule for Eq {
let right = self.right.translate(meta).unquote();
// Handle text comparison
if self.left.get_type() == Type::Text && self.right.get_type() == Type::Text {
meta.gen_subprocess(fragments!("[ \"_", left, "\" != \"_", right, "\" ]; echo $?"))
SubprocessFragment::new(fragments!("[ \"_", left, "\" != \"_", right, "\" ]; echo $?")).to_frag()
} 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 @@ -54,7 +54,7 @@ impl TranslateModule for Neq {
let left = self.left.translate(meta).unquote();
let right = self.right.translate(meta).unquote();
if self.left.get_type() == Type::Text && self.right.get_type() == Type::Text {
meta.gen_subprocess(fragments!("[ \"_", left, "\" == \"_", right, "\" ]; echo $?"))
SubprocessFragment::new(fragments!("[ \"_", left, "\" == \"_", right, "\" ]; echo $?")).to_frag()
} else {
translate_computation(meta, ArithOp::Neq, Some(left), Some(right))
}
Expand Down
14 changes: 5 additions & 9 deletions src/modules/expression/binop/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl TranslateModule for Range {
}
};
let expr = fragments!("seq ", from, " ", to);
meta.gen_subprocess(expr)
SubprocessFragment::new(expr).to_frag()
}
}

Expand Down Expand Up @@ -108,21 +108,17 @@ impl Range {
let offset = {
let offset_id = Some(meta.gen_value_id());
let offset_val = self.from.translate(meta);
let offset_var = meta.push_stmt_variable("__slice_offset", offset_id, Type::Num, offset_val);
let offset_var_name = RawFragment::new(&offset_var.get_name()).to_frag();
let offset_var = offset_var.to_frag();
let offset_cap = fragments!(offset_var_name, "=$((", offset_var.clone(), " > 0 ? ", offset_var, " : 0))");
let offset_var = meta.push_stmt_variable("__slice_offset", offset_id, Type::Num, offset_val).to_frag();
let offset_cap = fragments!("$((", offset_var.clone(), " > 0 ? ", offset_var, " : 0))");
meta.push_stmt_variable("__slice_offset", offset_id, Type::Num, offset_cap).to_frag()
};

// Cap the slice length at zero.
let length = {
let length_id = Some(meta.gen_value_id());
let length_val = translate_computation(meta, ArithOp::Sub, Some(upper), Some(offset.clone()));
let length_var = meta.push_stmt_variable("__slice_length", length_id, Type::Num, length_val);
let length_var_name = RawFragment::new(&length_var.get_name()).to_frag();
let length_var = length_var.to_frag();
let length_cap = fragments!(length_var_name, "=$((", length_var.clone(), " > 0 ? ", length_var, " : 0))");
let length_var = meta.push_stmt_variable("__slice_length", length_id, Type::Num, length_val).to_frag();
let length_cap = fragments!("$((", length_var.clone(), " > 0 ? ", length_var, " : 0))");
meta.push_stmt_variable("__slice_length", length_id, Type::Num, length_cap).to_frag()
};

Expand Down
3 changes: 1 addition & 2 deletions src/modules/expression/literal/array.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use heraclitus_compiler::prelude::*;
use crate::fragments;
use crate::modules::expression::expr::Expr;
use crate::modules::types::{try_parse_type, Type, Typed};
use crate::modules::prelude::*;
Expand Down Expand Up @@ -88,7 +87,7 @@ impl TranslateModule for Array {
let id = meta.gen_value_id();
let args = self.exprs.iter().map(|expr| expr.translate_eval(meta, false)).collect::<Vec<TranslationFragment>>();
let args = ListFragment::new(args, " ").to_frag();
let var = meta.push_stmt_variable("__array", Some(id), self.kind.clone(), fragments!("(", args, ")"));
let var = meta.push_stmt_variable_lazy("__array", Some(id), self.kind.clone(), args);
var.to_frag()
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/expression/literal/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl TranslateModule for Text {
fn translate(&self, meta: &mut TranslateMetadata) -> TranslationFragment {
// Translate all interpolations
let interps = self.interps.iter()
.map(|item| item.translate(meta))
.map(|item| item.translate(meta).unquote())
.collect::<Vec<TranslationFragment>>();
InterpolableFragment::new(self.strings.clone(), interps, InterpolableRenderType::StringLiteral).to_frag()
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/expression/ternop/ternary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl TranslateModule for Ternary {
let true_expr = self.true_expr.translate(meta);
let false_expr = self.false_expr.translate(meta);
let expr = fragments!("if [ ", cond, " != 0 ]; then echo ", true_expr, "; else echo ", false_expr, "; fi");
meta.gen_subprocess(expr)
SubprocessFragment::new(expr).to_frag()
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/modules/function/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ impl TranslateModule for FunctionDeclaration {
meta.fun_meta = Some(FunctionMetadata::new(&self.name, self.id, index, &self.returns));
// Parse the function body
let name = fragments!(raw: "{}__{}_v{}", self.name, self.id, index);
result.push(fragments!(name, "() {{"));
result.push(fragments!(name, "() {"));
if let Some(args) = self.set_args_as_variables(meta, function, &self.arg_refs) {
result.push(args);
}
Expand Down
9 changes: 4 additions & 5 deletions src/modules/function/invocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,22 @@ impl TranslateModule for FunctionInvocation {

let args = izip!(self.args.iter(), self.refs.iter()).map(| (arg, is_ref) | match arg.translate(meta) {
TranslationFragment::Var(var) if *is_ref => var.set_render_type(VarRenderType::BashName).to_frag(),
TranslationFragment::Var(var) if var.kind.is_array() => var.set_render_type(VarRenderType::BashName).to_frag(),
TranslationFragment::Var(var) if var.kind.is_array() => fragments!(var.set_render_type(VarRenderType::BashName).to_frag().unquote(), "[@]"),
_ if *is_ref => panic!("Reference value accepts only variables"),
var @ _ => var
}).collect::<Vec<TranslationFragment>>();
let args = ListFragment::new(args, " ").to_frag();
meta.stmt_queue.push_back(fragments!(name, " ", args, silent));

let invocation_return = &format!("__returned_{}{}_v{}", self.name, self.id, self.variant_id);
let invocation_instance = &format!("__returned_{}{}_v{}__{}_{}", self.name, self.id, self.variant_id, self.line, self.col);
let invocation_return = &format!("__ret_{}{}_v{}", self.name, self.id, self.variant_id);
let invocation_instance = &format!("__ret_{}{}_v{}__{}_{}", self.name, self.id, self.variant_id, self.line, self.col);
let parsed_invocation_return = self.get_variable(meta, invocation_return);
swap(&mut is_silent, &mut meta.silenced);
if self.is_failable {
let failed = self.failed.translate(meta);
meta.stmt_queue.push_back(failed);
}
let ret_value = if self.kind.is_array() { format!("({})", parsed_invocation_return) } else { parsed_invocation_return };
let variable = meta.push_stmt_variable(invocation_instance, None, self.kind.clone(), fragments!(raw: "{}", ret_value));
let variable = meta.push_stmt_variable_lazy(invocation_instance, None, self.kind.clone(), fragments!(raw: "{}", parsed_invocation_return));
variable.to_frag()
}
}
Expand Down
5 changes: 0 additions & 5 deletions src/modules/function/ret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,6 @@ impl TranslateModule for Return {
.map(FunctionMetadata::mangled_name)
.expect("Function name and return type not set");
let result = self.expr.translate(meta);
let result = if self.expr.get_type().is_array() {
fragments!("(", result, ")")
} else {
result
};
meta.push_stmt_variable(&fun_name, None, self.expr.get_type(), result);
fragments!("return 0")
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub use crate::translate::fragments::{
block::BlockFragment, compound::CompoundFragment, fragment::TranslationFragment,
raw::RawFragment, var::VarFragment, var::VarRenderType,
interpolable::InterpolableFragment, interpolable::InterpolableRenderType,
list::ListFragment,
list::ListFragment, subprocess::SubprocessFragment
};
pub use crate::translate::module::TranslateModule;
pub use crate::docs::module::DocumentationModule;
Expand Down
9 changes: 4 additions & 5 deletions src/modules/shorthand/add.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::modules::prelude::*;
use crate::{error_type_match, fragments};
use crate::error_type_match;
use crate::modules::expression::expr::Expr;
use crate::modules::variable::{handle_variable_reference, prevent_constant_mutation, variable_name_extensions};
use crate::translate::compute::translate_computation_eval;
Expand Down Expand Up @@ -51,17 +51,16 @@ impl TranslateModule for ShorthandAdd {
//noinspection DuplicatedCode
fn translate(&self, meta: &mut TranslateMetadata) -> TranslationFragment {
let var = VarFragment::new(&self.var, self.kind.clone(), self.is_ref, self.global_id);
let name = var.get_name();
match self.kind {
Type::Text | Type::Array(_) => {
let expr = self.expr.translate_eval(meta, self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&name, self.global_id, self.kind.clone(), self.is_ref, None, "+=", expr);
let (stmt, _var) = meta.gen_stmt_variable(&self.var, self.global_id, self.kind.clone(), self.is_ref, None, "+=", expr);
stmt
}
_ => {
let expr = self.expr.translate_eval(meta, self.is_ref);
let expr = translate_computation_eval(meta, ArithOp::Add, Some(fragments!(raw: "{}", name)), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&name, self.global_id, self.kind.clone(), self.is_ref, None, "+=", expr);
let expr = translate_computation_eval(meta, ArithOp::Add, Some(var.to_frag()), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&self.var, self.global_id, self.kind.clone(), self.is_ref, None, "=", expr);
stmt
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/modules/shorthand/div.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::modules::prelude::*;
use crate::{error_type_match, fragments};
use crate::error_type_match;
use crate::modules::expression::expr::Expr;
use crate::modules::variable::{handle_variable_reference, prevent_constant_mutation, variable_name_extensions};
use crate::translate::compute::translate_computation_eval;
Expand Down Expand Up @@ -51,11 +51,9 @@ impl TranslateModule for ShorthandDiv {
//noinspection DuplicatedCode
fn translate(&self, meta: &mut TranslateMetadata) -> TranslationFragment {
let var = VarFragment::new(&self.var, self.kind.clone(), self.is_ref, self.global_id);
let name = var.get_name();

let expr = self.expr.translate_eval(meta, self.is_ref);
let expr = translate_computation_eval(meta, ArithOp::Div, Some(fragments!(raw: "{}", name)), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&name, self.global_id, self.kind.clone(), self.is_ref, None, "=", expr);
let expr = translate_computation_eval(meta, ArithOp::Div, Some(var.to_frag()), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&self.var, self.global_id, self.kind.clone(), self.is_ref, None, "=", expr);
stmt
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/modules/shorthand/modulo.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::modules::prelude::*;
use crate::{error_type_match, fragments};
use crate::error_type_match;
use crate::modules::expression::expr::Expr;
use crate::modules::variable::{handle_variable_reference, prevent_constant_mutation, variable_name_extensions};
use crate::translate::compute::translate_computation_eval;
Expand Down Expand Up @@ -51,11 +51,9 @@ impl TranslateModule for ShorthandModulo {
//noinspection DuplicatedCode
fn translate(&self, meta: &mut TranslateMetadata) -> TranslationFragment {
let var = VarFragment::new(&self.var, self.kind.clone(), self.is_ref, self.global_id);
let name = var.get_name();

let expr = self.expr.translate_eval(meta, self.is_ref);
let expr = translate_computation_eval(meta, ArithOp::Modulo, Some(fragments!(raw: "{}", name)), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&name, self.global_id, self.kind.clone(), self.is_ref, None, "=", expr);
let expr = translate_computation_eval(meta, ArithOp::Modulo, Some(var.to_frag()), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&self.var, self.global_id, self.kind.clone(), self.is_ref, None, "=", expr);
stmt
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/modules/shorthand/mul.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::modules::prelude::*;
use crate::{error_type_match, fragments};
use crate::error_type_match;
use crate::modules::expression::expr::Expr;
use crate::modules::variable::{handle_variable_reference, prevent_constant_mutation, variable_name_extensions};
use crate::translate::compute::translate_computation_eval;
Expand Down Expand Up @@ -51,11 +51,9 @@ impl TranslateModule for ShorthandMul {
//noinspection DuplicatedCode
fn translate(&self, meta: &mut TranslateMetadata) -> TranslationFragment {
let var = VarFragment::new(&self.var, self.kind.clone(), self.is_ref, self.global_id);
let name = var.get_name();

let expr = self.expr.translate_eval(meta, self.is_ref);
let expr = translate_computation_eval(meta, ArithOp::Mul, Some(fragments!(raw: "{}", name)), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&name, self.global_id, self.kind.clone(), self.is_ref, None, "=", expr);
let expr = translate_computation_eval(meta, ArithOp::Mul, Some(var.to_frag()), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&self.var, self.global_id, self.kind.clone(), self.is_ref, None, "=", expr);
stmt
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/modules/shorthand/sub.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::modules::prelude::*;
use crate::{error_type_match, fragments};
use crate::error_type_match;
use crate::modules::expression::expr::Expr;
use crate::modules::variable::{handle_variable_reference, prevent_constant_mutation, variable_name_extensions};
use crate::translate::compute::translate_computation_eval;
Expand Down Expand Up @@ -51,11 +51,9 @@ impl TranslateModule for ShorthandSub {
//noinspection DuplicatedCode
fn translate(&self, meta: &mut TranslateMetadata) -> TranslationFragment {
let var = VarFragment::new(&self.var, self.kind.clone(), self.is_ref, self.global_id);
let name = var.get_name();

let expr = self.expr.translate_eval(meta, self.is_ref);
let expr = translate_computation_eval(meta, ArithOp::Sub, Some(fragments!(raw: "{}", name)), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&name, self.global_id, self.kind.clone(), self.is_ref, None, "=", expr);
let expr = translate_computation_eval(meta, ArithOp::Sub, Some(var.to_frag()), Some(expr), self.is_ref);
let (stmt, _var) = meta.gen_stmt_variable(&self.var, self.global_id, self.kind.clone(), self.is_ref, None, "=", expr);
stmt
}
}
Expand Down
6 changes: 1 addition & 5 deletions src/modules/statement/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,7 @@ impl TranslateModule for Statement {
},
_ => self.translate_match(meta, statement)
};
if meta.stmt_queue.is_empty() {
return translated;
} else {
return BlockFragment::new(meta.stmt_queue.drain(..).collect(), false).to_frag()
}
translated
}
}

Expand Down
Loading

0 comments on commit 2285055

Please sign in to comment.