fix: default value if not found
Signed-off-by: Pakin <pakin.t@forth.co.th>
This commit is contained in:
parent
ddcbe1b316
commit
2001888cd2
1 changed files with 24 additions and 8 deletions
|
|
@ -233,8 +233,13 @@ impl Vm {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Expression::Identifier(name) => {
|
Expression::Identifier(name) => {
|
||||||
self.globals.get(name).cloned()
|
match self.globals.get(name) {
|
||||||
.ok_or_else(|| VmError::UndefinedVariable(name.clone()))
|
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 } => {
|
Expression::BinaryOp { left, op, right } => {
|
||||||
|
|
@ -257,8 +262,13 @@ impl Vm {
|
||||||
|
|
||||||
Expression::SpecialVar { name, is_negative } => {
|
Expression::SpecialVar { name, is_negative } => {
|
||||||
let lookup = format!("${}", name);
|
let lookup = format!("${}", name);
|
||||||
let val = self.globals.get(&lookup).cloned()
|
let val = match self.globals.get(&lookup) {
|
||||||
.ok_or_else(|| VmError::UndefinedVariable(format!("${}", name)))?;
|
Some(val) => val.clone(),
|
||||||
|
None => {
|
||||||
|
eprintln!("[WARN] Undefined special variable: {}, defaulting to empty string", lookup);
|
||||||
|
Value::String(String::new())
|
||||||
|
}
|
||||||
|
};
|
||||||
if *is_negative {
|
if *is_negative {
|
||||||
val.to_f64()
|
val.to_f64()
|
||||||
.map(|n| Value::Number(-n))
|
.map(|n| Value::Number(-n))
|
||||||
|
|
@ -285,8 +295,13 @@ impl Vm {
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression::ArrayAccess { name, indices } => {
|
Expression::ArrayAccess { name, indices } => {
|
||||||
let base = self.globals.get(name).cloned()
|
let base = match self.globals.get(name) {
|
||||||
.ok_or_else(|| VmError::UndefinedVariable(name.clone()))?;
|
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: VmResult<Vec<Value>> = indices.iter().map(|i| self.eval_expr(i)).collect();
|
||||||
let idx_vals = idx_vals?;
|
let idx_vals = idx_vals?;
|
||||||
match (&base, idx_vals.first()) {
|
match (&base, idx_vals.first()) {
|
||||||
|
|
@ -715,9 +730,10 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_undefined_variable() {
|
fn test_undefined_variable_defaults_to_empty_string() {
|
||||||
let result = parse_and_run("Var x = unknown_var");
|
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]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue