mirror of
https://github.com/sagiegurari/duckscript
synced 2024-10-14 03:42:32 +00:00
split condition check to standalone module
This commit is contained in:
parent
5ce4e251e5
commit
730d561965
|
@ -1,5 +1,9 @@
|
||||||
## CHANGELOG
|
## CHANGELOG
|
||||||
|
|
||||||
### v0.1.0
|
### v0.1.2
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
|
### v0.1.0 (2019-12-30)
|
||||||
|
|
||||||
* Initial release
|
* Initial release
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = "true"
|
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = "true"
|
||||||
CARGO_MAKE_DUCKSCRIPT_PROJECT_NAME = "duckscript"
|
|
||||||
CARGO_MAKE_DUCKSCRIPT_VERSION = "0.1.1"
|
|
||||||
|
|
||||||
[env.sdk]
|
[env.sdk]
|
||||||
CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS = "duckscript_sdk;duckscript_cli"
|
CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS = "duckscript_sdk;duckscript_cli"
|
||||||
|
|
||||||
[config]
|
[config]
|
||||||
|
main_project_member = "duckscript_cli"
|
||||||
additional_profiles = [
|
additional_profiles = [
|
||||||
"ci-coverage-tasks",
|
"ci-coverage-tasks",
|
||||||
"ci-all-build-tasks",
|
"ci-all-build-tasks",
|
||||||
|
@ -41,82 +40,3 @@ workspace = false
|
||||||
cwd = "./duckscript_cli"
|
cwd = "./duckscript_cli"
|
||||||
command = "cargo"
|
command = "cargo"
|
||||||
args = [ "install", "--force", "--path", "." ]
|
args = [ "install", "--force", "--path", "." ]
|
||||||
|
|
||||||
[tasks.github-publish-curl]
|
|
||||||
script = [
|
|
||||||
'''
|
|
||||||
API_JSON=$(printf '{"tag_name": "%s","target_commitish": "master","name": "%s v%s","body": "release","draft": false,"prerelease": false}' ${CARGO_MAKE_DUCKSCRIPT_VERSION} ${CARGO_MAKE_DUCKSCRIPT_PROJECT_NAME} ${CARGO_MAKE_DUCKSCRIPT_VERSION})
|
|
||||||
curl --data "$API_JSON" https://api.github.com/repos/${GITHUB_REPO_NAME}/releases?access_token=${GITHUB_API_TOKEN}
|
|
||||||
'''
|
|
||||||
]
|
|
||||||
|
|
||||||
[tasks.zip-release-ci-flow]
|
|
||||||
description = "Compiles the binary in release mode and zips it up"
|
|
||||||
category = "CI"
|
|
||||||
workspace = false
|
|
||||||
condition = { env_set = ["TARGET"] }
|
|
||||||
dependencies = [
|
|
||||||
"clean",
|
|
||||||
"setup-build-env",
|
|
||||||
"build-release-for-target",
|
|
||||||
"zip-release-binary-for-target"
|
|
||||||
]
|
|
||||||
|
|
||||||
[tasks.build-release-for-target]
|
|
||||||
description = "Makes a release build for a given target"
|
|
||||||
condition = { env_set = [ "TARGET" ] }
|
|
||||||
command = "cargo"
|
|
||||||
args = [
|
|
||||||
"build",
|
|
||||||
"--release",
|
|
||||||
"--all-features",
|
|
||||||
"--target",
|
|
||||||
"${TARGET}"
|
|
||||||
]
|
|
||||||
|
|
||||||
[tasks.zip-release-binary-for-target]
|
|
||||||
description = "Zips up the release binary, README, and license(s)"
|
|
||||||
category = "Publish"
|
|
||||||
condition = { env_set = [ "TARGET" ] }
|
|
||||||
env = { "OUTPUT_NAME" = "${CARGO_MAKE_DUCKSCRIPT_PROJECT_NAME}-${TARGET}"}
|
|
||||||
script_runner = "@shell"
|
|
||||||
script = [
|
|
||||||
"mkdir ${OUTPUT_NAME}",
|
|
||||||
"cp target/$TARGET/release/${CARGO_MAKE_DUCKSCRIPT_PROJECT_NAME} ${OUTPUT_NAME}/",
|
|
||||||
"cp README.md LICENSE* ${OUTPUT_NAME}/",
|
|
||||||
"zip -r ${OUTPUT_NAME}.zip ${OUTPUT_NAME}",
|
|
||||||
]
|
|
||||||
|
|
||||||
[tasks.zip-release-binary-for-target.windows]
|
|
||||||
script = [
|
|
||||||
"mkdir ${OUTPUT_NAME}",
|
|
||||||
"dir target",
|
|
||||||
"powershell copy-item -path target/${TARGET}/release/${CARGO_MAKE_DUCKSCRIPT_PROJECT_NAME}.exe -destination ${OUTPUT_NAME}",
|
|
||||||
"powershell copy-item -path README.md -destination ${OUTPUT_NAME}",
|
|
||||||
"powershell copy-item -path LICENSE -destination ${OUTPUT_NAME}",
|
|
||||||
"dir ${OUTPUT_NAME}",
|
|
||||||
"powershell Compress-Archive -Path ${OUTPUT_NAME}/* -DestinationPath ${OUTPUT_NAME}.zip",
|
|
||||||
]
|
|
||||||
|
|
||||||
[tasks.setup-build-env]
|
|
||||||
description = "Sets up any non-rust dependencies in the build environment"
|
|
||||||
linux_alias = "setup-musl"
|
|
||||||
mac_alias = "empty"
|
|
||||||
windows_alias = "empty"
|
|
||||||
|
|
||||||
[tasks.setup-musl]
|
|
||||||
description = "Sets up a musl build environment"
|
|
||||||
windows_alias = "empty"
|
|
||||||
mac_alias = "empty"
|
|
||||||
condition = { env_set = [ "TARGET" ], env_true = [ "CARGO_MAKE_CI" ] }
|
|
||||||
env = { "OPENSSL_DIR" = "${HOME}/openssl-musl", "OPENSSL_VERSION" = "1.0.2l" }
|
|
||||||
script = [
|
|
||||||
'''
|
|
||||||
rustup target add "$TARGET"
|
|
||||||
curl https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz | tar xzf -
|
|
||||||
cd openssl-$OPENSSL_VERSION
|
|
||||||
CC=musl-gcc ./Configure --prefix="$OPENSSL_DIR" no-dso no-ssl2 no-ssl3 linux-x86_64 -fPIC
|
|
||||||
make -j"$(nproc)"
|
|
||||||
make install
|
|
||||||
'''
|
|
||||||
]
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::utils::instruction_query;
|
use crate::utils::instruction_query;
|
||||||
use crate::utils::state::{get_core_sub_state_for_command, get_list, get_sub_state};
|
use crate::utils::state::{get_core_sub_state_for_command, get_list, get_sub_state};
|
||||||
use crate::utils::{condition, eval, pckg};
|
use crate::utils::{condition, pckg};
|
||||||
use duckscript::types::command::{Command, CommandResult, Commands, GoToValue};
|
use duckscript::types::command::{Command, CommandResult, Commands, GoToValue};
|
||||||
use duckscript::types::error::ScriptError;
|
use duckscript::types::error::ScriptError;
|
||||||
use duckscript::types::instruction::Instruction;
|
use duckscript::types::instruction::Instruction;
|
||||||
|
@ -148,23 +148,6 @@ fn deserialize_call_info(sub_state: &mut HashMap<String, StateValue>) -> Option<
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_condition(
|
|
||||||
arguments: Vec<String>,
|
|
||||||
state: &mut HashMap<String, StateValue>,
|
|
||||||
variables: &mut HashMap<String, String>,
|
|
||||||
commands: &mut Commands,
|
|
||||||
) -> Result<bool, String> {
|
|
||||||
match eval::eval(&arguments, state, variables, commands) {
|
|
||||||
CommandResult::Continue(value) => {
|
|
||||||
let passed = condition::is_true(value);
|
|
||||||
|
|
||||||
Ok(passed)
|
|
||||||
}
|
|
||||||
CommandResult::Error(error) => Err(error.to_string()),
|
|
||||||
_ => Err("Invalid condition evaluation result.".to_string()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_if_meta_info_for_line(
|
fn create_if_meta_info_for_line(
|
||||||
line: usize,
|
line: usize,
|
||||||
instructions: &Vec<Instruction>,
|
instructions: &Vec<Instruction>,
|
||||||
|
@ -316,45 +299,47 @@ impl Command for IfCommand {
|
||||||
instructions,
|
instructions,
|
||||||
self.package.clone(),
|
self.package.clone(),
|
||||||
) {
|
) {
|
||||||
Ok(if_else_info) => match eval_condition(arguments, state, variables, commands) {
|
Ok(if_else_info) => {
|
||||||
Ok(passed) => {
|
match condition::eval_condition(arguments, state, variables, commands) {
|
||||||
if passed {
|
Ok(passed) => {
|
||||||
let next_line = if if_else_info.else_lines.is_empty() {
|
if passed {
|
||||||
if_else_info.end
|
let next_line = if if_else_info.else_lines.is_empty() {
|
||||||
|
if_else_info.end
|
||||||
|
} else {
|
||||||
|
if_else_info.else_lines[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
let call_info = CallInfo {
|
||||||
|
current: next_line,
|
||||||
|
passed,
|
||||||
|
else_line_index: 0,
|
||||||
|
meta_info: if_else_info.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
store_call_info(&call_info, state);
|
||||||
|
|
||||||
|
CommandResult::Continue(None)
|
||||||
|
} else if if_else_info.else_lines.is_empty() {
|
||||||
|
let next_line = if_else_info.end + 1;
|
||||||
|
CommandResult::GoTo(None, GoToValue::Line(next_line))
|
||||||
} else {
|
} else {
|
||||||
if_else_info.else_lines[0]
|
let next_line = if_else_info.else_lines[0];
|
||||||
};
|
|
||||||
|
|
||||||
let call_info = CallInfo {
|
let call_info = CallInfo {
|
||||||
current: next_line,
|
current: next_line,
|
||||||
passed,
|
passed: false,
|
||||||
else_line_index: 0,
|
else_line_index: 0,
|
||||||
meta_info: if_else_info.clone(),
|
meta_info: if_else_info.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
store_call_info(&call_info, state);
|
store_call_info(&call_info, state);
|
||||||
|
|
||||||
CommandResult::Continue(None)
|
CommandResult::GoTo(None, GoToValue::Line(next_line))
|
||||||
} else if if_else_info.else_lines.is_empty() {
|
}
|
||||||
let next_line = if_else_info.end + 1;
|
|
||||||
CommandResult::GoTo(None, GoToValue::Line(next_line))
|
|
||||||
} else {
|
|
||||||
let next_line = if_else_info.else_lines[0];
|
|
||||||
|
|
||||||
let call_info = CallInfo {
|
|
||||||
current: next_line,
|
|
||||||
passed: false,
|
|
||||||
else_line_index: 0,
|
|
||||||
meta_info: if_else_info.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
store_call_info(&call_info, state);
|
|
||||||
|
|
||||||
CommandResult::GoTo(None, GoToValue::Line(next_line))
|
|
||||||
}
|
}
|
||||||
|
Err(error) => CommandResult::Error(error.to_string()),
|
||||||
}
|
}
|
||||||
Err(error) => CommandResult::Error(error.to_string()),
|
}
|
||||||
},
|
|
||||||
Err(error) => CommandResult::Error(error.to_string()),
|
Err(error) => CommandResult::Error(error.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,7 +387,7 @@ impl Command for ElseIfCommand {
|
||||||
CommandResult::GoTo(None, GoToValue::Line(next_line))
|
CommandResult::GoTo(None, GoToValue::Line(next_line))
|
||||||
} else {
|
} else {
|
||||||
let if_else_info = call_info.meta_info.clone();
|
let if_else_info = call_info.meta_info.clone();
|
||||||
match eval_condition(arguments, state, variables, commands) {
|
match condition::eval_condition(arguments, state, variables, commands) {
|
||||||
Ok(passed) => {
|
Ok(passed) => {
|
||||||
if passed {
|
if passed {
|
||||||
let next_line = if call_info.else_line_index < if_else_info.else_lines.len() {
|
let next_line = if call_info.else_line_index < if_else_info.else_lines.len() {
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
use crate::utils::eval;
|
||||||
|
use duckscript::types::command::{CommandResult, Commands};
|
||||||
|
use duckscript::types::runtime::StateValue;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "./condition_test.rs"]
|
#[path = "./condition_test.rs"]
|
||||||
mod condition_test;
|
mod condition_test;
|
||||||
|
@ -13,3 +18,40 @@ pub(crate) fn is_true(value: Option<String>) -> bool {
|
||||||
|
|
||||||
!failed
|
!failed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn eval_condition(
|
||||||
|
arguments: Vec<String>,
|
||||||
|
state: &mut HashMap<String, StateValue>,
|
||||||
|
variables: &mut HashMap<String, String>,
|
||||||
|
commands: &mut Commands,
|
||||||
|
) -> Result<bool, String> {
|
||||||
|
let eval_statement = if arguments.len() == 1 {
|
||||||
|
match commands.get(&arguments[0]) {
|
||||||
|
Some(_) => true,
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
|
||||||
|
if eval_statement {
|
||||||
|
match eval::eval(&arguments, state, variables, commands) {
|
||||||
|
CommandResult::Continue(value) => {
|
||||||
|
let passed = is_true(value);
|
||||||
|
|
||||||
|
Ok(passed)
|
||||||
|
}
|
||||||
|
CommandResult::Error(error) => Err(error.to_string()),
|
||||||
|
_ => Err("Invalid condition evaluation result.".to_string()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let value = match variables.get(&arguments[0]) {
|
||||||
|
Some(value) => Some(value.to_string()),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let passed = is_true(value);
|
||||||
|
|
||||||
|
Ok(passed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue