Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A86 Fix if chain error regarding overwriting values #57

Merged
merged 2 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion setup/install.ab
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ unsafe {
not hasFailed("ruby -v") {
let code = "require \"open-uri\"; open(\"{target}\", \"wb\") do |file|; file << open(\"{url}\").read; end"
echo "Using ruby as a download method..."
$sudo ruby -e "{code}"$
$sudo ruby -e "{code}"$ failed {
echo "Ruby failed to download amber."
echo "Please try again or use another download method."
$exit 1$
}
}
not hasFailed("curl -v") {
echo "Using curl as a download method..."
Expand Down
28 changes: 12 additions & 16 deletions setup/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ function hasFailed__18_v0 {
${command} > /dev/null 2>&1
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
__AMBER_FUN_hasFailed18_v0=$(echo $__AMBER_STATUS '!=' 0 | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//');
Expand All @@ -16,22 +15,19 @@ __3_place="/opt/amber";
__AMBER_VAL_0=$(uname -s);
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
os=$(if [ $([ "_${__AMBER_VAL_0}" != "_Darwin" ]; echo $?) != 0 ]; then echo "macos"; else echo "linux"; fi);
__AMBER_VAL_1=$(uname -m);
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
arch=$(if [ $([ "_${__AMBER_VAL_1}" != "_arm64" ]; echo $?) != 0 ]; then echo "aarch64"; else echo "x86_64"; fi);
url="https://github.com/Ph0enixKM/${__0_name}/releases/download/${__2_tag}/amber_${os}_${arch}";
test -d "${__3_place}"
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
if [ $(echo $__AMBER_STATUS '==' 0 | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
Expand All @@ -42,37 +38,42 @@ fi;
exit 0
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi
fi;
echo "Installing Amber";
hasFailed__18_v0 "ruby -v";
__AMBER_FUN_hasFailed18_v0__36=${__AMBER_FUN_hasFailed18_v0};
hasFailed__18_v0 "curl -v";
__AMBER_FUN_hasFailed18_v0__45=${__AMBER_FUN_hasFailed18_v0};
hasFailed__18_v0 "wget -V";
if [ $(echo '!' ${__AMBER_FUN_hasFailed18_v0} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
__AMBER_FUN_hasFailed18_v0__49=${__AMBER_FUN_hasFailed18_v0};
if [ $(echo '!' ${__AMBER_FUN_hasFailed18_v0__36} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
code="require \"open-uri\"; open(\"${__1_target}\", \"wb\") do |file|; file << open(\"${url}\").read; end";
echo "Using ruby as a download method...";
sudo ruby -e "${code}"
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
echo "Ruby failed to download amber.";
echo "Please try again or use another download method.";
exit 1
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
:
fi
elif [ $(echo '!' ${__AMBER_FUN_hasFailed18_v0} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
fi
elif [ $(echo '!' ${__AMBER_FUN_hasFailed18_v0__45} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
echo "Using curl as a download method...";
curl -o "${__1_target}" "${url}"
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi
elif [ $(echo '!' ${__AMBER_FUN_hasFailed18_v0} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
elif [ $(echo '!' ${__AMBER_FUN_hasFailed18_v0__49} | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
echo "Using wget as a download method...";
wget -O "${__1_target}" "${url}"
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi
else
Expand All @@ -81,32 +82,27 @@ else
exit 1
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi
fi;
sudo mkdir "${__3_place}" > /dev/null
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
sudo mv "${__1_target}" "${__3_place}/${__1_target}"
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
sudo chmod +x "${__3_place}/${__1_target}"
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
sudo ln -s "${__3_place}/${__1_target}" "/usr/local/bin/${__1_target}"
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
echo "Amber has been installed successfully. 🎉"
4 changes: 0 additions & 4 deletions setup/uninstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,22 @@
test -d "${place}" > /dev/null
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
__AMBER_VAL_0=$(echo $?);
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
if [ $([ "_${__AMBER_VAL_0}" != "_0" ]; echo $?) != 0 ]; then
sudo rm -rf "${place}"
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
sudo rm "/usr/local/bin/amber"
__AMBER_STATUS=$?;
if [ $__AMBER_STATUS != 0 ]; then
$(exit $__AMBER_STATUS)
:
fi;
echo "Uninstalled Amber successfully 🎉"
Expand Down
61 changes: 31 additions & 30 deletions src/modules/condition/failed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,39 +26,42 @@ impl SyntaxModule<ParserMetadata> for Failed {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
let tok = meta.get_current_token();
if meta.context.is_unsafe_ctx {
self.is_main = meta.context.is_main_ctx;
self.is_parsed = true;
return Ok(());
}
if let Ok(_) = token(meta, "?") {
if !meta.context.is_fun_ctx && !meta.context.is_main_ctx {
if !meta.context.is_fun_ctx && !meta.context.is_main_ctx && !meta.context.is_unsafe_ctx {
return error!(meta, tok, "The '?' operator can only be used in the main block or function body")
}
self.is_question_mark = true;
} else {
token(meta, "failed")?;
match token(meta, "{") {
Ok(_) => {
let tok = meta.get_current_token();
syntax(meta, &mut *self.block)?;
if self.block.is_empty() {
let message = Message::new_warn_at_token(meta, tok)
.message("Empty failed block")
.comment("You should use 'unsafe' modifier to run commands without handling errors");
meta.messages.push(message);
match token(meta, "failed") {
Ok(_) => match token(meta, "{") {
Ok(_) => {
let tok = meta.get_current_token();
syntax(meta, &mut *self.block)?;
if self.block.is_empty() {
let message = Message::new_warn_at_token(meta, tok)
.message("Empty failed block")
.comment("You should use 'unsafe' modifier to run commands without handling errors");
meta.messages.push(message);
}
token(meta, "}")?;
},
Err(_) => {
match token(meta, ":") {
Ok(_) => {
let mut statement = Statement::new();
syntax(meta, &mut statement)?;
self.block.push_statement(statement);
},
Err(_) => return error!(meta, tok, "Failed expression must be followed by a block or statement")
}
}
token(meta, "}")?;
},
Err(_) => {
match token(meta, ":") {
Ok(_) => {
let mut statement = Statement::new();
syntax(meta, &mut statement)?;
self.block.push_statement(statement);
},
Err(_) => return error!(meta, tok, "Failed expression must be followed by a block or statement")
}
Err(_) => if meta.context.is_unsafe_ctx {
self.is_main = meta.context.is_main_ctx;
self.is_parsed = true;
return Ok(());
} else {
return error!(meta, tok, "Failed expression must be followed by a block or statement")
}
}
}
Expand All @@ -73,8 +76,8 @@ impl TranslateModule for Failed {
if self.is_parsed {
let block = self.block.translate(meta);
let ret = self.is_main
.then(|| "exit $?")
.unwrap_or("return $?");
.then(|| "exit $__AMBER_STATUS")
.unwrap_or("return $__AMBER_STATUS");
// the condition of '$?' clears the status code thus we need to store it in a variable
if self.is_question_mark {
// if the failed expression is in the main block we need to clear the return value
Expand All @@ -88,15 +91,13 @@ impl TranslateModule for Failed {
"__AMBER_STATUS=$?;",
"if [ $__AMBER_STATUS != 0 ]; then",
&clear_return,
&format!("$(exit $__AMBER_STATUS)"),
ret,
"fi"
].join("\n")
} else {
vec![
"__AMBER_STATUS=$?;",
"if [ $__AMBER_STATUS != 0 ]; then",
&format!("$(exit $__AMBER_STATUS)"),
&block,
"fi"
].join("\n")
Expand Down
33 changes: 27 additions & 6 deletions src/modules/function/invocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct FunctionInvocation {
kind: Type,
variant_id: usize,
id: usize,
line: usize,
failed: Failed,
is_failable: bool
}
Expand All @@ -37,6 +38,7 @@ impl SyntaxModule<ParserMetadata> for FunctionInvocation {
kind: Type::Null,
variant_id: 0,
id: 0,
line: 0,
failed: Failed::new(),
is_failable: false
}
Expand All @@ -45,6 +47,9 @@ impl SyntaxModule<ParserMetadata> for FunctionInvocation {
fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
// Get the function name
let tok = meta.get_current_token();
if let Some(ref tok) = tok {
self.line = tok.pos.0;
}
self.name = variable(meta, variable_name_extensions())?;
// Get the arguments
token(meta, "(")?;
Expand Down Expand Up @@ -89,6 +94,17 @@ impl SyntaxModule<ParserMetadata> for FunctionInvocation {
}
}

impl FunctionInvocation {
fn get_variable(&self, meta: &mut TranslateMetadata, name: &str) -> String {
if matches!(self.kind, Type::Array(_)) {
let quote = meta.gen_quote();
format!("{quote}${{{name}[@]}}{quote}")
} else {
format!("${{{name}}}")
}
}
}

impl TranslateModule for FunctionInvocation {
fn translate(&self, meta: &mut TranslateMetadata) -> String {
let name = format!("{}__{}_v{}", self.name, self.id, self.variant_id);
Expand All @@ -105,15 +121,20 @@ 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));
if self.is_failable {
let failed = self.failed.translate(meta);
meta.stmt_queue.push_back(failed);
}
if matches!(self.kind, Type::Array(_)) {
let quote = meta.gen_quote();
format!("{quote}${{__AMBER_FUN_{}{}_v{}[@]}}{quote}", self.name, self.id, self.variant_id)
} else {
format!("${{__AMBER_FUN_{}{}_v{}}}", self.name, self.id, self.variant_id)
}
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)
} else {
invocation_return
})
);
invocation_instance
}
}