mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
added boolean functions not(a), and(a v) and or(a b). and and or are short-circuiting.
This commit is contained in:
parent
ea5346f81c
commit
2293e9365c
2
gui.mers
2
gui.mers
@ -14,7 +14,7 @@ second_text = column.gui_add(Text: "press the button above to remove this text!"
|
||||
while {
|
||||
for event gui_updates() {
|
||||
switch! event {
|
||||
ButtonPressed([int]) {
|
||||
ButtonPressed([int ...]) {
|
||||
e = event.noenum()
|
||||
match e {
|
||||
&e.eq(&button) println("First button pressed")
|
||||
|
@ -152,6 +152,9 @@ pub fn parse_step_libs_load(
|
||||
let cmd_path = cmd.get_program().to_string_lossy().into_owned();
|
||||
match libs::Lib::launch(cmd, &mut ginfo.enum_variants) {
|
||||
Ok(lib) => {
|
||||
for (i, (func, _, _)) in lib.registered_fns.iter().enumerate() {
|
||||
ginfo.lib_fns.insert(func.clone(), (libs.len(), i));
|
||||
}
|
||||
libs.push(lib);
|
||||
}
|
||||
Err(e) => return Err(UnableToLoadLibrary(cmd_path, e)),
|
||||
|
@ -50,6 +50,10 @@ pub enum BuiltinFunction {
|
||||
// OS
|
||||
RunCommand,
|
||||
RunCommandGetBytes,
|
||||
// Bool
|
||||
Not,
|
||||
And,
|
||||
Or,
|
||||
// Math
|
||||
Add,
|
||||
Sub,
|
||||
@ -75,6 +79,7 @@ pub enum BuiltinFunction {
|
||||
Contains,
|
||||
StartsWith,
|
||||
EndsWith,
|
||||
IndexOf,
|
||||
Trim,
|
||||
Substring,
|
||||
Regex,
|
||||
@ -108,6 +113,9 @@ impl BuiltinFunction {
|
||||
"string_to_bytes" => Self::StringToBytes,
|
||||
"run_command" => Self::RunCommand,
|
||||
"run_command_get_bytes" => Self::RunCommandGetBytes,
|
||||
"not" => Self::Not,
|
||||
"and" => Self::And,
|
||||
"or" => Self::Or,
|
||||
"add" => Self::Add,
|
||||
"sub" => Self::Sub,
|
||||
"mul" => Self::Mul,
|
||||
@ -130,6 +138,7 @@ impl BuiltinFunction {
|
||||
"contains" => Self::Contains,
|
||||
"starts_with" => Self::StartsWith,
|
||||
"ends_with" => Self::EndsWith,
|
||||
"index_of" => Self::IndexOf,
|
||||
"trim" => Self::Trim,
|
||||
"substring" => Self::Substring,
|
||||
"regex" => Self::Regex,
|
||||
@ -309,6 +318,13 @@ impl BuiltinFunction {
|
||||
|| (input[0].fits_in(&st).is_empty() && input[1].fits_in(&st).is_empty())
|
||||
}
|
||||
}
|
||||
Self::Not => input.len() == 1 && input[0].fits_in(&VSingleType::Bool.to()).is_empty(),
|
||||
Self::And | Self::Or => {
|
||||
input.len() == 2
|
||||
&& input
|
||||
.iter()
|
||||
.all(|v| v.fits_in(&VSingleType::Bool.to()).is_empty())
|
||||
}
|
||||
Self::Sub
|
||||
| Self::Mul
|
||||
| Self::Div
|
||||
@ -421,12 +437,26 @@ impl BuiltinFunction {
|
||||
false
|
||||
}
|
||||
}
|
||||
// two strings
|
||||
Self::Contains | Self::StartsWith | Self::EndsWith | Self::Regex => {
|
||||
input.len() == 2
|
||||
&& input
|
||||
.iter()
|
||||
.all(|v| v.fits_in(&VSingleType::String.to()).is_empty())
|
||||
}
|
||||
// two strings or &strings
|
||||
Self::IndexOf => {
|
||||
input.len() == 2
|
||||
&& input.iter().all(|v| {
|
||||
v.fits_in(&VType {
|
||||
types: vec![
|
||||
VSingleType::String,
|
||||
VSingleType::Reference(Box::new(VSingleType::String)),
|
||||
],
|
||||
})
|
||||
.is_empty()
|
||||
})
|
||||
}
|
||||
Self::Trim => {
|
||||
input.len() == 1 && input[0].fits_in(&VSingleType::String.to()).is_empty()
|
||||
}
|
||||
@ -591,6 +621,7 @@ impl BuiltinFunction {
|
||||
]),
|
||||
],
|
||||
},
|
||||
Self::Not | Self::And | Self::Or => VSingleType::Bool.to(),
|
||||
Self::Add
|
||||
| Self::Sub
|
||||
| Self::Mul
|
||||
@ -641,6 +672,9 @@ impl BuiltinFunction {
|
||||
Self::Push | Self::Insert => VSingleType::Tuple(vec![]).into(),
|
||||
Self::Len => VSingleType::Int.into(),
|
||||
Self::Contains | Self::StartsWith | Self::EndsWith => VSingleType::Bool.into(),
|
||||
Self::IndexOf => VType {
|
||||
types: vec![VSingleType::Tuple(vec![]), VSingleType::Int],
|
||||
},
|
||||
Self::Trim => VSingleType::String.into(),
|
||||
Self::Substring => VSingleType::String.into(),
|
||||
Self::Regex => VType {
|
||||
@ -1067,6 +1101,43 @@ impl BuiltinFunction {
|
||||
unreachable!("run_command not 1 arg")
|
||||
}
|
||||
}
|
||||
Self::Not => {
|
||||
if let VDataEnum::Bool(v) = args[0].run(vars, libs).data {
|
||||
VDataEnum::Bool(!v).to()
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
Self::And => {
|
||||
if let VDataEnum::Bool(a) = args[0].run(vars, libs).data {
|
||||
if a == false {
|
||||
VDataEnum::Bool(false).to()
|
||||
} else {
|
||||
if let VDataEnum::Bool(b) = args[1].run(vars, libs).data {
|
||||
VDataEnum::Bool(b).to()
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
Self::Or => {
|
||||
if let VDataEnum::Bool(a) = args[0].run(vars, libs).data {
|
||||
if a == true {
|
||||
VDataEnum::Bool(true).to()
|
||||
} else {
|
||||
if let VDataEnum::Bool(b) = args[1].run(vars, libs).data {
|
||||
VDataEnum::Bool(b).to()
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
Self::Add => {
|
||||
if args.len() == 2 {
|
||||
match (args[0].run(vars, libs).data, args[1].run(vars, libs).data) {
|
||||
@ -1458,6 +1529,61 @@ impl BuiltinFunction {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
Self::IndexOf => {
|
||||
if args.len() == 2 {
|
||||
let find_in = args[0].run(vars, libs);
|
||||
let pat = args[1].run(vars, libs);
|
||||
fn find(find_in: &String, pat: &String) -> VData {
|
||||
if let Some(found_byte_index) = find_in.find(pat) {
|
||||
if let Some(char_index) = find_in.char_indices().enumerate().find_map(
|
||||
|(char_index, (byte_index, _char))| {
|
||||
if byte_index == found_byte_index {
|
||||
Some(char_index)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
) {
|
||||
VDataEnum::Int(char_index as _).to()
|
||||
} else {
|
||||
VDataEnum::Tuple(vec![]).to()
|
||||
}
|
||||
} else {
|
||||
VDataEnum::Tuple(vec![]).to()
|
||||
}
|
||||
}
|
||||
match (find_in.data, pat.data) {
|
||||
(VDataEnum::String(a), VDataEnum::String(b)) => find(&a, &b),
|
||||
(VDataEnum::String(a), VDataEnum::Reference(b)) => {
|
||||
match &b.lock().unwrap().data {
|
||||
VDataEnum::String(b) => find(&a, b),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
(VDataEnum::Reference(a), VDataEnum::String(b)) => {
|
||||
match &a.lock().unwrap().data {
|
||||
VDataEnum::String(a) => find(a, &b),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
(VDataEnum::Reference(a), VDataEnum::Reference(b)) => {
|
||||
if Arc::ptr_eq(&a, &b) {
|
||||
// point to the same string
|
||||
// (this is required because a.lock() would cause b.lock() to wait indefinitely if you pass a two references to the same string here)
|
||||
VDataEnum::Int(0).to()
|
||||
} else {
|
||||
match (&a.lock().unwrap().data, &b.lock().unwrap().data) {
|
||||
(VDataEnum::String(a), VDataEnum::String(b)) => find(a, b),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
Self::Trim => {
|
||||
if args.len() == 1 {
|
||||
if let VDataEnum::String(a) = args[0].run(vars, libs).data {
|
||||
|
@ -55,7 +55,7 @@ fn get_db_contents() {
|
||||
for entry entries {
|
||||
lines = entry.regex(".*")
|
||||
switch! lines {
|
||||
[string] {
|
||||
[string ...] {
|
||||
index_line = &lines.get(0).assume1()
|
||||
index = index_line.substring(1 index_line.len().sub(1)).parse_int().assume1()
|
||||
title = &lines.get(1).assume1().substring(1)
|
||||
@ -168,7 +168,7 @@ thread(() {
|
||||
while {
|
||||
for event gui_updates() {
|
||||
switch! event {
|
||||
ButtonPressed([int]) {
|
||||
ButtonPressed([int ...]) {
|
||||
e = event.noenum()
|
||||
println("Pressed button {0}".format(e.to_string()))
|
||||
match e {
|
||||
|
Loading…
Reference in New Issue
Block a user