refactor: 用 Value::get/set 简化属性访问,消除直接 borrow/borrow_mut 调用
- Value::set 签名改为接受 &str 并返回 RuntimeError,与 evaluator 对齐 - eval_get/eval_set/eval_index_get/eval_index_set 中统一使用 get/set - 去掉 eval_index_get 和 eval_index_set 中不再使用的 map 绑定 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+13
-15
@@ -90,9 +90,9 @@ impl super::Interpreter {
|
||||
fn eval_get(&mut self, object: Expr, name: String) -> Result<Value, RuntimeError> {
|
||||
let obj = self.evaluate(object)?;
|
||||
match obj {
|
||||
Value::Object(map) => {
|
||||
match map.borrow().get(&name) {
|
||||
Some(val) => Ok(val.clone()),
|
||||
Value::Object(_) => {
|
||||
match obj.get(&name) {
|
||||
Some(val) => Ok(val),
|
||||
None => Err(RuntimeError::RuntimeError {
|
||||
message: format!("Undefined property '{}'", name),
|
||||
token: None,
|
||||
@@ -215,19 +215,18 @@ impl super::Interpreter {
|
||||
let obj = self.evaluate(object)?;
|
||||
let rhs = self.evaluate(value)?;
|
||||
match obj {
|
||||
Value::Object(map) => {
|
||||
Value::Object(_) => {
|
||||
let val = match op {
|
||||
AssignOp::Equal => rhs,
|
||||
_ => {
|
||||
let map_borrow = map.borrow();
|
||||
let current = map_borrow.get(&name).ok_or_else(|| RuntimeError::RuntimeError {
|
||||
let current = obj.get(&name).ok_or_else(|| RuntimeError::RuntimeError {
|
||||
message: format!("Property '{}' does not exist", name),
|
||||
token: None,
|
||||
})?;
|
||||
self.apply_assign_op(current.clone(), rhs, op)?
|
||||
self.apply_assign_op(current, rhs, op)?
|
||||
}
|
||||
};
|
||||
map.borrow_mut().insert(name, val.clone());
|
||||
obj.set(&name, val.clone())?;
|
||||
Ok(val)
|
||||
}
|
||||
_ => Err(RuntimeError::RuntimeError {
|
||||
@@ -241,7 +240,7 @@ impl super::Interpreter {
|
||||
let target = self.evaluate(array)?;
|
||||
let idx_val = self.evaluate(index)?;
|
||||
// Object index access: obj["key"]
|
||||
if let Value::Object(map) = &target {
|
||||
if let Value::Object(_) = &target {
|
||||
let key = match &idx_val {
|
||||
Value::String(s) => s.clone(),
|
||||
_ => return Err(RuntimeError::RuntimeError {
|
||||
@@ -249,7 +248,7 @@ impl super::Interpreter {
|
||||
token: None,
|
||||
}),
|
||||
};
|
||||
return map.borrow().get(&key).cloned().ok_or_else(|| RuntimeError::RuntimeError {
|
||||
return target.get(&key).ok_or_else(|| RuntimeError::RuntimeError {
|
||||
message: format!("Undefined property '{}'", key),
|
||||
token: None,
|
||||
});
|
||||
@@ -282,7 +281,7 @@ impl super::Interpreter {
|
||||
let idx_val = self.evaluate(index)?;
|
||||
let rhs = self.evaluate(value)?;
|
||||
// Object index assignment: obj["key"] = value
|
||||
if let Value::Object(map) = &target {
|
||||
if let Value::Object(_) = &target {
|
||||
let key = match &idx_val {
|
||||
Value::String(s) => s.clone(),
|
||||
_ => return Err(RuntimeError::RuntimeError {
|
||||
@@ -293,15 +292,14 @@ impl super::Interpreter {
|
||||
let val = match op {
|
||||
AssignOp::Equal => rhs,
|
||||
_ => {
|
||||
let map_borrow = map.borrow();
|
||||
let current = map_borrow.get(&key).ok_or_else(|| RuntimeError::RuntimeError {
|
||||
let current = target.get(&key).ok_or_else(|| RuntimeError::RuntimeError {
|
||||
message: format!("Property '{}' does not exist", key),
|
||||
token: None,
|
||||
})?;
|
||||
self.apply_assign_op(current.clone(), rhs, op)?
|
||||
self.apply_assign_op(current, rhs, op)?
|
||||
}
|
||||
};
|
||||
map.borrow_mut().insert(key, val.clone());
|
||||
target.set(&key, val.clone())?;
|
||||
return Ok(val);
|
||||
}
|
||||
let i = self.as_array_index(&idx_val)?;
|
||||
|
||||
@@ -33,6 +33,28 @@ pub enum Signal {
|
||||
Continue, // continue 信号
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn get(&self, key: &str) -> Option<Value> {
|
||||
match self {
|
||||
Value::Object(obj) => obj.borrow().get(key).cloned(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&self, key: &str, val: Value) -> Result<(), crate::error::RuntimeError> {
|
||||
match self {
|
||||
Value::Object(obj) => {
|
||||
obj.borrow_mut().insert(key.to_string(), val);
|
||||
Ok(())
|
||||
},
|
||||
_ => Err(crate::error::RuntimeError::RuntimeError {
|
||||
message: "Only objects have properties".to_string(),
|
||||
token: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Value {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
|
||||
Reference in New Issue
Block a user