[add] modules::fs::mkdir

[add] modules::math::mod (modulo)
This commit is contained in:
hkau 2024-02-24 21:31:17 -05:00
parent 878a785dd9
commit 5e40183d20
4 changed files with 121 additions and 83 deletions

View file

@ -30,9 +30,9 @@ RETURN = { "return" ~ any }
CLASSDEC = { ("class" | "meta" | "%:") ~ IDENTIFIER ~ ":" ~ BLOCKS* ~ "<end>" }
FNDEC = { ("def" | "fn" | "function" | "@:") ~ IDENTIFIER ~ "(" ~ any* ~ "):" ~ BLOCKS* ~ "<end>" }
CONDITIONAL_IF = { "if" ~ (any ~ OPERATOR ~ any)+ ~ (":" | "then") ~ BLOCKS* ~ "<end>" ~ (CONDITIONAL_ELSE | CONDITIONAL_ELIF)? }
CONDITIONAL_IF = { "if" ~ FNCALL ~ (":" | "then") ~ BLOCKS+ ~ "<end>" ~ (CONDITIONAL_ELSE | CONDITIONAL_ELIF)? }
CONDITIONAL_ELSE = { "else:" ~ BLOCKS* ~ "<end>" }
CONDITIONAL_ELIF = { "elif" ~ (any ~ OPERATOR ~ any)* ~ ":" ~ BLOCKS* ~ "<end>" ~ (CONDITIONAL_ELSE | CONDITIONAL_ELIF)? }
CONDITIONAL_ELIF = { "elif" ~ FNCALL ~ ":" ~ BLOCKS+ ~ "<end>" ~ (CONDITIONAL_ELSE | CONDITIONAL_ELIF)? }
QUICK_CONDITIONAL_IF = { any ~ (OPERATOR ~ any)+ }
QUICK_CONDITIONAL_BLOCK = _{ "(" ~ QUICK_CONDITIONAL_IF ~ ")" }

View file

@ -371,13 +371,8 @@ pub fn from_tree(
let inner = block.into_inner().collect::<Vec<Pair<'_, Rule>>>();
// get compared, operator, and compare_with
let compared = inner.get(0);
let op = inner.get(1);
let compare_with = inner.get(2);
// get values
let compared = get_block_value(
compared.unwrap().to_owned(),
let res = get_block_value(
inner.get(0).unwrap().to_owned(),
true,
Option::None,
&functions,
@ -385,27 +380,6 @@ pub fn from_tree(
&variables,
);
let op = get_block_value(
op.unwrap().to_owned(),
true,
Option::None,
&functions,
&rt_functions,
&variables,
);
let compare_with = get_block_value(
compare_with.unwrap().to_owned(),
true,
Option::None,
&functions,
&rt_functions,
&variables,
);
// compare
let res = run_conditional(compared, op, compare_with);
if res.rule == Rule::bool {
if res.value.to_lowercase() == String::from("true") {
from_tree(
@ -423,14 +397,9 @@ pub fn from_tree(
let elif_inner_vec =
elif_inner.clone().collect::<Vec<Pair<'_, Rule>>>();
// get compared, operator, and compare_with
let compared = elif_inner_vec.get(0);
let op = elif_inner_vec.get(1);
let compare_with = elif_inner_vec.get(2);
// get values
let compared = get_block_value(
compared.unwrap().to_owned(),
// ...
let res = get_block_value(
elif_inner_vec.get(0).unwrap().to_owned(),
true,
Option::None,
&functions,
@ -438,27 +407,6 @@ pub fn from_tree(
&variables,
);
let op = get_block_value(
op.unwrap().to_owned(),
true,
Option::None,
&functions,
&rt_functions,
&variables,
);
let compare_with = get_block_value(
compare_with.unwrap().to_owned(),
true,
Option::None,
&functions,
&rt_functions,
&variables,
);
// compare
let res = run_conditional(compared, op, compare_with);
// run body
if res.value == "true" {
from_tree(
@ -466,6 +414,7 @@ pub fn from_tree(
Option::Some(variables.clone()),
Option::Some(rt_functions.clone()),
);
continue;
} else {
// TODO: rerun search but a layer down (block = elif_block)

View file

@ -135,6 +135,44 @@ pub fn remove(args: Vec<ReturnValue>) -> ReturnValue {
}
}
/// Create a new directory at a [`string`](crate::modules::methods::table) path, returns `NULL null` on error and `BOOL true` on success
///
/// # Arguments:
/// * `path` - [`string`](crate::modules::methods::string) containing the path of the new directory
///
/// # Example:
/// ```py
/// fs:mkdir("existing_directory/new_directory")
/// ```
pub fn mkdir(args: Vec<ReturnValue>) -> ReturnValue {
let args = args.get(0).unwrap().children.as_ref().unwrap();
// get args
let arg = args.get(0);
if (arg.is_none()) | (arg.is_some() && arg.unwrap().rule != Rule::string) {
error_exit(
"ARGS,TYPE",
"expected function to be called with an argument of type 'string'",
)
}
// remove file
let res = std::fs::create_dir(arg.unwrap().value.clone().replace("\"", ""));
if res.is_err() {
return ReturnValue::new(Rule::null);
}
// return
ReturnValue {
rule: Rule::bool,
value: String::from("true"),
children: Option::None,
attributes: Option::None,
}
}
// ...
/// Import module
pub fn import() -> FunctionsStore {
@ -156,6 +194,11 @@ pub fn import() -> FunctionsStore {
Box::new(|args, _| remove(args)),
);
functions.insert(
String::from("#ST_fs_mkdir"),
Box::new(|args, _| mkdir(args)),
);
// return
functions
}

View file

@ -24,12 +24,12 @@ pub fn abs(args: Vec<ReturnValue>) -> ReturnValue {
}
// return
return ReturnValue {
ReturnValue {
rule: Rule::number,
value: arg.unwrap().value.parse::<f32>().unwrap().abs().to_string(),
children: Option::None,
attributes: Option::None,
};
}
}
/// Add two [`numbers`](crate::modules::methods::default) together (`num1 + num2`)
@ -69,12 +69,12 @@ pub fn add(args: Vec<ReturnValue>) -> ReturnValue {
let num2 = num2.unwrap().value.parse::<f32>().unwrap();
// return
return ReturnValue {
ReturnValue {
rule: Rule::number,
value: (num1 + num2).to_string(),
children: Option::None,
attributes: Option::None,
};
}
}
/// Subtract two [`numbers`](crate::modules::methods::default) (`num1 - num2`)
@ -114,12 +114,12 @@ pub fn sub(args: Vec<ReturnValue>) -> ReturnValue {
let num2 = num2.unwrap().value.parse::<f32>().unwrap();
// return
return ReturnValue {
ReturnValue {
rule: Rule::number,
value: (num1 - num2).to_string(),
children: Option::None,
attributes: Option::None,
};
}
}
/// Multiply two [`numbers`](crate::modules::methods::default) together (`num1 * num2`)
@ -159,12 +159,12 @@ pub fn mul(args: Vec<ReturnValue>) -> ReturnValue {
let num2 = num2.unwrap().value.parse::<f32>().unwrap();
// return
return ReturnValue {
ReturnValue {
rule: Rule::number,
value: (num1 * num2).to_string(),
children: Option::None,
attributes: Option::None,
};
}
}
/// Divide two [`numbers`](crate::modules::methods::default) (`num1 / num2`)
@ -204,12 +204,12 @@ pub fn div(args: Vec<ReturnValue>) -> ReturnValue {
let num2 = num2.unwrap().value.parse::<f32>().unwrap();
// return
return ReturnValue {
ReturnValue {
rule: Rule::number,
value: (num1 / num2).to_string(),
children: Option::None,
attributes: Option::None,
};
}
}
/// Returns the given [`number`](crate::modules::methods::default) value raised to the [`number`](crate::modules::methods::default)-power
@ -238,7 +238,7 @@ pub fn pow(args: Vec<ReturnValue>) -> ReturnValue {
}
// return
return ReturnValue {
ReturnValue {
rule: Rule::number,
value: arg
.unwrap()
@ -249,7 +249,43 @@ pub fn pow(args: Vec<ReturnValue>) -> ReturnValue {
.to_string(),
children: Option::None,
attributes: Option::None,
};
}
}
/// Returns [`div()`] remainder given two [`numbers`](crate::modules::methods::default)
///
/// See: <https://doc.rust-lang.org/book/appendix-02-operators.html> (`%`)
pub fn r#mod(args: Vec<ReturnValue>) -> ReturnValue {
let args = args.get(0).unwrap().children.as_ref().unwrap();
// get args
let arg = args.get(0);
if (arg.is_none()) | (arg.is_some() && arg.unwrap().rule != Rule::number) {
error_exit(
"ARGS,TYPE",
"expected function to be called with an argument of type 'number'",
)
}
let arg1 = args.get(1);
if (arg1.is_none()) | (arg1.is_some() && arg1.unwrap().rule != Rule::number) {
error_exit(
"ARGS,TYPE",
"expected function to be called with a second argument of type 'number'",
)
}
// return
ReturnValue {
rule: Rule::number,
value: (arg.unwrap().value.parse::<f32>().unwrap()
% arg1.unwrap().value.parse::<f32>().unwrap())
.to_string(),
children: Option::None,
attributes: Option::None,
}
}
// (compare)
@ -287,12 +323,12 @@ pub fn eq(args: Vec<ReturnValue>) -> ReturnValue {
}
// return
return ReturnValue {
ReturnValue {
rule: Rule::bool,
value: (arg1 == arg2).to_string(),
children: Option::None,
attributes: Option::None,
};
}
}
/// Returns `true` is both given arguments are not equal
@ -331,12 +367,12 @@ pub fn neq(args: Vec<ReturnValue>) -> ReturnValue {
}
// return
return ReturnValue {
ReturnValue {
rule: Rule::bool,
value: (arg1 != arg2).to_string(),
children: Option::None,
attributes: Option::None,
};
}
}
/// Reverse a [`boolean`](crate::modules::methods::default)
@ -363,7 +399,7 @@ pub fn not(args: Vec<ReturnValue>) -> ReturnValue {
}
// return
return ReturnValue {
ReturnValue {
rule: Rule::bool,
value: if arg1.unwrap().value == "true" {
String::from("false")
@ -372,7 +408,7 @@ pub fn not(args: Vec<ReturnValue>) -> ReturnValue {
},
children: Option::None,
attributes: Option::None,
};
}
}
/// Functional conditionals
@ -434,15 +470,14 @@ pub fn con_eval(args: Vec<ReturnValue>, vars: VariablesStore) -> ReturnValue {
.get("then")
.expect("provided callback table has no continuation");
con_eval_run(func, vars);
return con_eval_run(func, vars);
} else {
// otherwise
let attrs = arg2.unwrap().attributes.clone().unwrap();
let func = attrs.k_fn.get("otherwise");
if func.is_some() {
con_eval_run(func.unwrap(), vars);
return con_eval_run(func.unwrap(), vars);
}
}
@ -451,7 +486,7 @@ pub fn con_eval(args: Vec<ReturnValue>, vars: VariablesStore) -> ReturnValue {
}
/// Private function to run callback functions in [`con_eval()`]
fn con_eval_run(func: &str, vars: VariablesStore) {
fn con_eval_run(func: &str, vars: VariablesStore) -> ReturnValue {
let content = crate::parser::parse(func);
// this is the same thing as crate::interpret::run_function (but with no arguments)
@ -472,8 +507,15 @@ fn con_eval_run(func: &str, vars: VariablesStore) {
.clone()
.into_inner();
// technically we *could* return the result of the conditional here instead...
crate::interpret::from_tree(&inner, Option::Some(vars), Option::Some(HashMap::new()));
let res = crate::interpret::from_tree(&inner, Option::Some(vars), Option::Some(HashMap::new()));
let ret = res.kv.get("return");
if ret.is_none() {
return ReturnValue::new(Rule::null);
}
// return
ret.unwrap().to_owned()
}
// ...
@ -490,6 +532,10 @@ pub fn import() -> FunctionsStore {
functions.insert(String::from("#ST_math_sub"), Box::new(|args, _| sub(args)));
functions.insert(String::from("#ST_math_mul"), Box::new(|args, _| mul(args)));
functions.insert(String::from("#ST_math_div"), Box::new(|args, _| div(args)));
functions.insert(
String::from("#ST_math_mod"),
Box::new(|args, _| r#mod(args)),
);
// (compare)
functions.insert(String::from("#ST_math_eq"), Box::new(|args, _| eq(args)));