fix: default value if not found

Signed-off-by: Pakin <pakin.t@forth.co.th>
This commit is contained in:
Pakin 2026-05-25 15:05:37 +07:00
parent ddcbe1b316
commit 2001888cd2

View file

@ -233,8 +233,13 @@ impl Vm {
}),
Expression::Identifier(name) => {
self.globals.get(name).cloned()
.ok_or_else(|| VmError::UndefinedVariable(name.clone()))
match self.globals.get(name) {
Some(val) => Ok(val.clone()),
None => {
eprintln!("[WARN] Undefined variable: {}, defaulting to empty string", name);
Ok(Value::String(String::new()))
}
}
}
Expression::BinaryOp { left, op, right } => {
@ -257,8 +262,13 @@ impl Vm {
Expression::SpecialVar { name, is_negative } => {
let lookup = format!("${}", name);
let val = self.globals.get(&lookup).cloned()
.ok_or_else(|| VmError::UndefinedVariable(format!("${}", name)))?;
let val = match self.globals.get(&lookup) {
Some(val) => val.clone(),
None => {
eprintln!("[WARN] Undefined special variable: {}, defaulting to empty string", lookup);
Value::String(String::new())
}
};
if *is_negative {
val.to_f64()
.map(|n| Value::Number(-n))
@ -285,8 +295,13 @@ impl Vm {
}
Expression::ArrayAccess { name, indices } => {
let base = self.globals.get(name).cloned()
.ok_or_else(|| VmError::UndefinedVariable(name.clone()))?;
let base = match self.globals.get(name) {
Some(val) => val.clone(),
None => {
eprintln!("[WARN] Undefined array variable: {}, defaulting to empty string", name);
return Ok(Value::String(String::new()));
}
};
let idx_vals: VmResult<Vec<Value>> = indices.iter().map(|i| self.eval_expr(i)).collect();
let idx_vals = idx_vals?;
match (&base, idx_vals.first()) {
@ -715,9 +730,10 @@ mod tests {
}
#[test]
fn test_undefined_variable() {
fn test_undefined_variable_defaults_to_empty_string() {
let result = parse_and_run("Var x = unknown_var");
assert!(result.is_err());
assert!(result.is_ok());
assert_eq!(result.unwrap(), Value::String(String::new()));
}
#[test]