|
|
@@ -49,69 +49,69 @@ fn exec_op(pos: Location, id: i32, args: &[ParsedExpr], ctx: &Context) -> Result |
|
|
|
} |
|
|
|
1 => { |
|
|
|
// multiply |
|
|
|
if args.len() != 2 { |
|
|
|
return Err(EvalError::InvalidParameters( |
|
|
|
pos, |
|
|
|
format!( |
|
|
|
"multiply operation requires exactly 2 parameters, got {}", |
|
|
|
args.len() |
|
|
|
), |
|
|
|
)); |
|
|
|
} |
|
|
|
|
|
|
|
let a = eval(&args[0], ctx)?; |
|
|
|
let b = eval(&args[1], ctx)?; |
|
|
|
|
|
|
|
Ok(match (a, b) { |
|
|
|
(Value::Nil, b) => b, |
|
|
|
(a, Value::Nil) => a, |
|
|
|
(Value::I32(a), Value::I32(b)) => Value::I32(a * b), |
|
|
|
(Value::String(a), Value::I32(b)) | (Value::I32(b), Value::String(a)) => { |
|
|
|
Value::String(a.repeat(b.max(0) as usize)) |
|
|
|
} |
|
|
|
(Value::String(_), Value::String(_)) => { |
|
|
|
return Err(EvalError::InvalidParameters( |
|
|
|
pos, |
|
|
|
format!("multiply operation cannot be applied to two strings"), |
|
|
|
)) |
|
|
|
} |
|
|
|
(Value::Function(_), _) | (_, Value::Function(_)) => { |
|
|
|
return Err(EvalError::InvalidParameters( |
|
|
|
pos, |
|
|
|
format!("multiply operation cannot be applied to functions"), |
|
|
|
)) |
|
|
|
if args.is_empty() { |
|
|
|
Ok(Value::Nil) |
|
|
|
} else if args.len() == 1 { |
|
|
|
eval(&args[0], ctx) |
|
|
|
} else { |
|
|
|
let mut acc = eval(&args[0], ctx)?; |
|
|
|
for b in args.iter().skip(1) { |
|
|
|
let b = eval(b, ctx)?; |
|
|
|
acc = match (acc, b) { |
|
|
|
(Value::Nil, b) => b, |
|
|
|
(a, Value::Nil) => a, |
|
|
|
(Value::I32(a), Value::I32(b)) => Value::I32(a * b), |
|
|
|
(Value::String(a), Value::I32(b)) | (Value::I32(b), Value::String(a)) => { |
|
|
|
Value::String(a.repeat(b.max(0) as usize)) |
|
|
|
} |
|
|
|
(Value::String(_), Value::String(_)) => { |
|
|
|
return Err(EvalError::InvalidParameters( |
|
|
|
pos, |
|
|
|
format!("multiply operation cannot be applied to two strings"), |
|
|
|
)) |
|
|
|
} |
|
|
|
(Value::Function(_), _) | (_, Value::Function(_)) => { |
|
|
|
return Err(EvalError::InvalidParameters( |
|
|
|
pos, |
|
|
|
format!("multiply operation cannot be applied to functions"), |
|
|
|
)) |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
Ok(acc) |
|
|
|
} |
|
|
|
} |
|
|
|
4 => { |
|
|
|
// add |
|
|
|
if args.len() != 2 { |
|
|
|
return Err(EvalError::InvalidParameters( |
|
|
|
pos, |
|
|
|
format!( |
|
|
|
"add operation requires exactly 2 parameters, got {}", |
|
|
|
args.len() |
|
|
|
), |
|
|
|
)); |
|
|
|
} |
|
|
|
|
|
|
|
let a = eval(&args[0], ctx)?; |
|
|
|
let b = eval(&args[1], ctx)?; |
|
|
|
|
|
|
|
Ok(match (a, b) { |
|
|
|
(Value::Nil, b) => b, |
|
|
|
(a, Value::Nil) => a, |
|
|
|
(Value::I32(a), Value::I32(b)) => Value::I32(a + b), |
|
|
|
(Value::String(a), Value::I32(b)) => Value::String(format!("{}{}", a, b)), |
|
|
|
(Value::I32(a), Value::String(b)) => Value::String(format!("{}{}", a, b)), |
|
|
|
(Value::String(a), Value::String(b)) => Value::String(format!("{}{}", a, b)), |
|
|
|
(Value::Function(_), _) | (_, Value::Function(_)) => { |
|
|
|
return Err(EvalError::InvalidParameters( |
|
|
|
pos, |
|
|
|
format!("add operation cannot be applied to functions"), |
|
|
|
)) |
|
|
|
if args.is_empty() { |
|
|
|
Ok(Value::Nil) |
|
|
|
} else if args.len() == 1 { |
|
|
|
eval(&args[0], ctx) |
|
|
|
} else { |
|
|
|
let mut acc = eval(&args[0], ctx)?; |
|
|
|
for b in args.iter().skip(1) { |
|
|
|
let b = eval(b, ctx)?; |
|
|
|
acc = match (acc, b) { |
|
|
|
(Value::Nil, b) => b, |
|
|
|
(a, Value::Nil) => a, |
|
|
|
(Value::I32(a), Value::I32(b)) => Value::I32(a + b), |
|
|
|
(Value::String(a), Value::I32(b)) => Value::String(format!("{}{}", a, b)), |
|
|
|
(Value::I32(a), Value::String(b)) => Value::String(format!("{}{}", a, b)), |
|
|
|
(Value::String(a), Value::String(b)) => Value::String(format!("{}{}", a, b)), |
|
|
|
(Value::Function(_), _) | (_, Value::Function(_)) => { |
|
|
|
return Err(EvalError::InvalidParameters( |
|
|
|
pos, |
|
|
|
format!("add operation cannot be applied to functions"), |
|
|
|
)) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
Ok(acc) |
|
|
|
} |
|
|
|
} |
|
|
|
8 => { |
|
|
|
// divide |
|
|
|