feat: 添加赋值运算符支持,更新解析器、解释器和词法分析器以处理相关语法
This commit is contained in:
@@ -141,8 +141,15 @@ impl Interpreter {
|
||||
}),
|
||||
}
|
||||
}
|
||||
Expr::Assign { name, value } => {
|
||||
let val = self.evaluate(*value)?;
|
||||
Expr::Assign { name, op, value } => {
|
||||
let rhs = self.evaluate(*value)?;
|
||||
let val = match op {
|
||||
AssignOp::Equal => rhs,
|
||||
_ => {
|
||||
let current = self.env.borrow().get(&name).ok_or_else(|| RuntimeError::RuntimeError { message: format!("Undefined variable '{}'", name), token: None })?;
|
||||
self.apply_assign_op(current.clone(), rhs, op)?
|
||||
}
|
||||
};
|
||||
if !self.env.borrow_mut().assign(&name, val.clone()) {
|
||||
return Err(RuntimeError::RuntimeError {
|
||||
message: format!("Undefined variable '{}'", name),
|
||||
@@ -169,11 +176,19 @@ impl Interpreter {
|
||||
}),
|
||||
}
|
||||
}
|
||||
Expr::Set { object, name, value } => {
|
||||
Expr::Set { object, name, op, value } => {
|
||||
let obj = self.evaluate(*object)?;
|
||||
let rhs = self.evaluate(*value)?;
|
||||
match obj {
|
||||
Value::Object(map) => {
|
||||
let val = self.evaluate(*value)?;
|
||||
let val = match op {
|
||||
AssignOp::Equal => rhs,
|
||||
_ => {
|
||||
let map_borrow = map.borrow();
|
||||
let current = map_borrow.get(&name).ok_or_else(|| RuntimeError::RuntimeError { message: format!("Property '{}' does not exist", name), token: None })?;
|
||||
self.apply_assign_op(current.clone(), rhs, op)?
|
||||
}
|
||||
};
|
||||
map.borrow_mut().insert(name, val.clone());
|
||||
Ok(val)
|
||||
}
|
||||
@@ -208,10 +223,10 @@ impl Interpreter {
|
||||
}),
|
||||
}
|
||||
}
|
||||
Expr::IndexSet { array, index, value } => {
|
||||
Expr::IndexSet { array, index, op, value } => {
|
||||
let arr = self.evaluate(*array)?;
|
||||
let idx = self.evaluate(*index)?;
|
||||
let val = self.evaluate(*value)?;
|
||||
let rhs = self.evaluate(*value)?;
|
||||
let i = self.as_array_index(&idx)?;
|
||||
match arr {
|
||||
Value::Array(vec) => {
|
||||
@@ -222,6 +237,13 @@ impl Interpreter {
|
||||
token: None,
|
||||
});
|
||||
}
|
||||
let val = match op {
|
||||
AssignOp::Equal => rhs,
|
||||
_ => {
|
||||
let current = vec[i].clone();
|
||||
self.apply_assign_op(current, rhs, op)?
|
||||
}
|
||||
};
|
||||
vec[i] = val.clone();
|
||||
Ok(val)
|
||||
}
|
||||
@@ -398,6 +420,32 @@ impl Interpreter {
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_assign_op(&self, left: Value, right: Value, op: AssignOp) -> Result<Value, RuntimeError> {
|
||||
match op {
|
||||
AssignOp::Equal => Ok(right),
|
||||
AssignOp::PlusEqual => {
|
||||
let left_num = self.as_number(&left)?;
|
||||
let right_num = self.as_number(&right)?;
|
||||
Ok(Value::Number(left_num + right_num))
|
||||
}
|
||||
AssignOp::MinusEqual => {
|
||||
let left_num = self.as_number(&left)?;
|
||||
let right_num = self.as_number(&right)?;
|
||||
Ok(Value::Number(left_num - right_num))
|
||||
}
|
||||
AssignOp::StarEqual => {
|
||||
let left_num = self.as_number(&left)?;
|
||||
let right_num = self.as_number(&right)?;
|
||||
Ok(Value::Number(left_num * right_num))
|
||||
}
|
||||
AssignOp::SlashEqual => {
|
||||
let left_num = self.as_number(&left)?;
|
||||
let right_num = self.as_number(&right)?;
|
||||
Ok(Value::Number(left_num / right_num))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn as_number(&self, val: &Value) -> Result<f64, RuntimeError> {
|
||||
if let Value::Number(n) = val {
|
||||
Ok(*n)
|
||||
|
||||
Reference in New Issue
Block a user