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> {
|
fn eval_get(&mut self, object: Expr, name: String) -> Result<Value, RuntimeError> {
|
||||||
let obj = self.evaluate(object)?;
|
let obj = self.evaluate(object)?;
|
||||||
match obj {
|
match obj {
|
||||||
Value::Object(map) => {
|
Value::Object(_) => {
|
||||||
match map.borrow().get(&name) {
|
match obj.get(&name) {
|
||||||
Some(val) => Ok(val.clone()),
|
Some(val) => Ok(val),
|
||||||
None => Err(RuntimeError::RuntimeError {
|
None => Err(RuntimeError::RuntimeError {
|
||||||
message: format!("Undefined property '{}'", name),
|
message: format!("Undefined property '{}'", name),
|
||||||
token: None,
|
token: None,
|
||||||
@@ -215,19 +215,18 @@ impl super::Interpreter {
|
|||||||
let obj = self.evaluate(object)?;
|
let obj = self.evaluate(object)?;
|
||||||
let rhs = self.evaluate(value)?;
|
let rhs = self.evaluate(value)?;
|
||||||
match obj {
|
match obj {
|
||||||
Value::Object(map) => {
|
Value::Object(_) => {
|
||||||
let val = match op {
|
let val = match op {
|
||||||
AssignOp::Equal => rhs,
|
AssignOp::Equal => rhs,
|
||||||
_ => {
|
_ => {
|
||||||
let map_borrow = map.borrow();
|
let current = obj.get(&name).ok_or_else(|| RuntimeError::RuntimeError {
|
||||||
let current = map_borrow.get(&name).ok_or_else(|| RuntimeError::RuntimeError {
|
|
||||||
message: format!("Property '{}' does not exist", name),
|
message: format!("Property '{}' does not exist", name),
|
||||||
token: None,
|
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)
|
Ok(val)
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::RuntimeError {
|
_ => Err(RuntimeError::RuntimeError {
|
||||||
@@ -241,7 +240,7 @@ impl super::Interpreter {
|
|||||||
let target = self.evaluate(array)?;
|
let target = self.evaluate(array)?;
|
||||||
let idx_val = self.evaluate(index)?;
|
let idx_val = self.evaluate(index)?;
|
||||||
// Object index access: obj["key"]
|
// Object index access: obj["key"]
|
||||||
if let Value::Object(map) = &target {
|
if let Value::Object(_) = &target {
|
||||||
let key = match &idx_val {
|
let key = match &idx_val {
|
||||||
Value::String(s) => s.clone(),
|
Value::String(s) => s.clone(),
|
||||||
_ => return Err(RuntimeError::RuntimeError {
|
_ => return Err(RuntimeError::RuntimeError {
|
||||||
@@ -249,7 +248,7 @@ impl super::Interpreter {
|
|||||||
token: None,
|
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),
|
message: format!("Undefined property '{}'", key),
|
||||||
token: None,
|
token: None,
|
||||||
});
|
});
|
||||||
@@ -282,7 +281,7 @@ impl super::Interpreter {
|
|||||||
let idx_val = self.evaluate(index)?;
|
let idx_val = self.evaluate(index)?;
|
||||||
let rhs = self.evaluate(value)?;
|
let rhs = self.evaluate(value)?;
|
||||||
// Object index assignment: obj["key"] = value
|
// Object index assignment: obj["key"] = value
|
||||||
if let Value::Object(map) = &target {
|
if let Value::Object(_) = &target {
|
||||||
let key = match &idx_val {
|
let key = match &idx_val {
|
||||||
Value::String(s) => s.clone(),
|
Value::String(s) => s.clone(),
|
||||||
_ => return Err(RuntimeError::RuntimeError {
|
_ => return Err(RuntimeError::RuntimeError {
|
||||||
@@ -293,15 +292,14 @@ impl super::Interpreter {
|
|||||||
let val = match op {
|
let val = match op {
|
||||||
AssignOp::Equal => rhs,
|
AssignOp::Equal => rhs,
|
||||||
_ => {
|
_ => {
|
||||||
let map_borrow = map.borrow();
|
let current = target.get(&key).ok_or_else(|| RuntimeError::RuntimeError {
|
||||||
let current = map_borrow.get(&key).ok_or_else(|| RuntimeError::RuntimeError {
|
|
||||||
message: format!("Property '{}' does not exist", key),
|
message: format!("Property '{}' does not exist", key),
|
||||||
token: None,
|
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);
|
return Ok(val);
|
||||||
}
|
}
|
||||||
let i = self.as_array_index(&idx_val)?;
|
let i = self.as_array_index(&idx_val)?;
|
||||||
|
|||||||
@@ -33,6 +33,28 @@ pub enum Signal {
|
|||||||
Continue, // continue 信号
|
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 {
|
impl std::fmt::Debug for Value {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
Reference in New Issue
Block a user