added more enviroment functions

This commit is contained in:
afonya 2025-06-16 22:03:13 +02:00
parent cef2217c9e
commit 52b2e6fcc0
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC

View file

@ -44,6 +44,10 @@ fn get_type_str(mem: &VMMemory) -> String {
}
}
fn arg_expect(args: &Vec<VMMemory>, pos: usize, expected_type: &str, machine: &Machine, op: &DecompiledOperation) {
if args.len() <= pos {
let err_str = format!("#{} expected {}, got nil", pos + 1, expected_type);
error(err_str, machine, op);
}
let err_str = format!("#{} expected {}, got {}", pos + 1, expected_type, get_type_str(&args[pos]));
if args.len() <= pos {
error(err_str.clone(), machine, op);
@ -97,6 +101,64 @@ fn get_mem_tbl_val(tbl: &VMMemoryTable, key: VMMemory) -> Option<&VMMemory> {
}
None
}
fn convert_type(mem: &VMMemory, target_type: &str) -> VMMemory {
match (mem, target_type) {
(VMMemory::String(s), "string") => {
VMMemory::String(VMMemoryString { value: s.value.clone(), variable_id: 0 })
},
(VMMemory::String(s), "number") => {
match s.value.parse::<f64>() {
Ok(num) => VMMemory::Number(VMMemoryNumber { value: num, variable_id: 0 }),
Err(_) => VMMemory::Null(VMMemoryNull { variable_id: 0 }),
}
},
(VMMemory::String(s), "boolean") => {
if s.value.to_lowercase() == "true" {
VMMemory::Boolean(VMMemoryBoolean { value: true, variable_id: 0 })
} else if s.value.to_lowercase() == "false" {
VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 })
} else {
VMMemory::Null(VMMemoryNull { variable_id: 0 })
}
},
(VMMemory::Number(n), "string") => {
VMMemory::String(VMMemoryString { value: n.value.to_string(), variable_id: 0 })
},
(VMMemory::Number(n), "number") => {
VMMemory::Number(VMMemoryNumber { value: n.value, variable_id: 0 })
},
(VMMemory::Number(n), "boolean") => {
if n.value != 0.0 {
VMMemory::Boolean(VMMemoryBoolean { value: true, variable_id: 0 })
} else {
VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 })
}
},
(VMMemory::Boolean(b), "string") => {
VMMemory::String(VMMemoryString { value: b.value.to_string(), variable_id: 0 })
},
(VMMemory::Boolean(b), "number") => {
if b.value {
VMMemory::Number(VMMemoryNumber { value: 1.0, variable_id: 0 })
} else {
VMMemory::Number(VMMemoryNumber { value: 0.0, variable_id: 0 })
}
},
(VMMemory::Boolean(b), "boolean") => {
VMMemory::Boolean(VMMemoryBoolean { value: b.value, variable_id: 0 })
},
(VMMemory::Null(_), "string") => {
VMMemory::String(VMMemoryString { value: String::from("null"), variable_id: 0 })
},
(VMMemory::Null(_), "number") => {
VMMemory::Number(VMMemoryNumber { value: 0.0, variable_id: 0 })
},
(VMMemory::Null(_), "boolean") => {
VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 })
},
_ => VMMemory::Null(VMMemoryNull { variable_id: 0 })
}
}
fn ugass(_machine: &mut Machine, _op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
let mut out = String::new();
@ -133,6 +195,15 @@ fn tarh(_machine: &mut Machine, _op: &DecompiledOperation, args: Vec<VMMemory>)
}
return VMMemory::String(VMMemoryString { value: get_type_str(&args[0]), variable_id: 0 });
}
fn bimbabemb(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 1, "string", machine, op);
let val = args[0].clone();
let target = match &args[1] {
VMMemory::String(s) => s.value.clone(),
_ => String::new()
};
return convert_type(&val, &target);
}
fn nerd_abs(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 0, "number", machine, op);
@ -144,6 +215,126 @@ fn nerd_abs(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>
}
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
fn nerd_kerek(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 0, "number", machine, op);
arg_expect(&args, 1, "string", machine, op);
let num = match &args[0] {
VMMemory::Number(n) => n.value,
_ => {
error(String::from("Expected a number"), machine, op);
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
};
let mode = match &args[1] {
VMMemory::String(s) => s.value.clone(),
_ => {
error(String::from("Expected a string"), machine, op);
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
};
let rounded = match mode.as_str() {
"up" => num.ceil(),
"down" => num.floor(),
"nearest" => num.round(),
_ => {
error(format!("Unknown rounding mode: {}", mode), machine, op);
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
};
return VMMemory::Number(VMMemoryNumber { value: rounded, variable_id: 0 });
}
fn nerd_sin(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 0, "number", machine, op);
let num = match &args[0] {
VMMemory::Number(n) => n.value,
_ => {
error(String::from("Expected a number"), machine, op);
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
};
let result = num.sin();
return VMMemory::Number(VMMemoryNumber { value: result, variable_id: 0 });
}
fn nerd_cos(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 0, "number", machine, op);
let num = match &args[0] {
VMMemory::Number(n) => n.value,
_ => {
error(String::from("Expected a number"), machine, op);
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
};
let result = num.cos();
return VMMemory::Number(VMMemoryNumber { value: result, variable_id: 0 });
}
fn nerd_tan(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 0, "number", machine, op);
let num = match &args[0] {
VMMemory::Number(n) => n.value,
_ => {
error(String::from("Expected a number"), machine, op);
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
};
let result = num.tan();
return VMMemory::Number(VMMemoryNumber { value: result, variable_id: 0 });
}
fn nerd_sqrt(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 0, "number", machine, op);
let num = match &args[0] {
VMMemory::Number(n) => n.value,
_ => {
error(String::from("Expected a number"), machine, op);
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
};
let result = num.sqrt();
return VMMemory::Number(VMMemoryNumber { value: result, variable_id: 0 });
}
fn nerd_legnagyobb(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 0, "number", machine, op);
let mut nums = Vec::new();
for arg in 0..args.len() {
match &args[arg] {
VMMemory::Number(n) => nums.push(n.value),
_ => {
error(format!("#{} expected number, got {}", arg, get_type_str(&args[arg])), machine, op);
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
}
}
let mut result: f64 = 0.0;
let mut first = true;
for num in nums {
if first || num > result {
result = num;
}
first = false;
}
return VMMemory::Number(VMMemoryNumber { value: result, variable_id: 0 });
}
fn nerd_legkisebb(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 0, "number", machine, op);
let mut nums = Vec::new();
for arg in 0..args.len() {
match &args[arg] {
VMMemory::Number(n) => nums.push(n.value),
_ => {
error(format!("#{} expected number, got {}", arg, get_type_str(&args[arg])), machine, op);
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
}
}
}
let mut result: f64 = 0.0;
let mut first = true;
for num in nums {
if first || num < result {
result = num;
}
first = false;
}
return VMMemory::Number(VMMemoryNumber { value: result, variable_id: 0 });
}
fn kabel_olvass(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
arg_expect(&args, 0, "table", machine, op);
@ -556,11 +747,40 @@ pub fn generate() -> HashMap<String, VMMemory> {
mem.insert(String::from("bimba"), VMMemory::NativeFunction(VMMemoryNativeFunction { func: bimba, variable_id: 0 }));
mem.insert(String::from("csömör"), VMMemory::NativeFunction(VMMemoryNativeFunction { func: csomor, variable_id: 0 }));
mem.insert(String::from("tarh"), VMMemory::NativeFunction(VMMemoryNativeFunction { func: tarh, variable_id: 0 }));
mem.insert(String::from("bimbabemb"), VMMemory::NativeFunction(VMMemoryNativeFunction { func: bimbabemb, variable_id: 0 }));
let nerd: Vec<TableValue> = vec![
TableValue {
key: VMMemory::String(VMMemoryString { value: String::from("abs"), variable_id: 0 }),
value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: nerd_abs, variable_id: 0 }),
},
TableValue {
key: VMMemory::String(VMMemoryString { value: String::from("kerek"), variable_id: 0 }),
value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: nerd_kerek, variable_id: 0 }),
},
TableValue {
key: VMMemory::String(VMMemoryString { value: String::from("sin"), variable_id: 0 }),
value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: nerd_sin, variable_id: 0 }),
},
TableValue {
key: VMMemory::String(VMMemoryString { value: String::from("cos"), variable_id: 0 }),
value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: nerd_cos, variable_id: 0 }),
},
TableValue {
key: VMMemory::String(VMMemoryString { value: String::from("tan"), variable_id: 0 }),
value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: nerd_tan, variable_id: 0 }),
},
TableValue {
key: VMMemory::String(VMMemoryString { value: String::from("sqrt"), variable_id: 0 }),
value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: nerd_sqrt, variable_id: 0 }),
},
TableValue {
key: VMMemory::String(VMMemoryString { value: String::from("legnagyobb"), variable_id: 0 }),
value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: nerd_legnagyobb, variable_id: 0 }),
},
TableValue {
key: VMMemory::String(VMMemoryString { value: String::from("legkisebb"), variable_id: 0 }),
value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: nerd_legkisebb, variable_id: 0 }),
}
];
mem.insert(String::from("nerd"), VMMemory::Table(VMMemoryTable { values: nerd, variable_id: 0 }));