///|
pub(all) struct RuntimeEnvironment {
  values : Map[String, RuntimeValue]
  // 跟踪哪些变量是可变的
  mutable_vars : Map[String, Bool]
  parent : RuntimeEnvironment?
} derive(ToJson)

///|
pub fn RuntimeEnvironment::new(
  parent? : RuntimeEnvironment,
  values? : Map[String, RuntimeValue],
) -> RuntimeEnvironment {
  if parent is Some(parent) {
    { values: values.unwrap_or({}), mutable_vars: {}, parent: Some(parent) }
  } else {
    { values: values.unwrap_or({}), mutable_vars: {}, parent: None }
  }
}

///|
/// 深拷贝环境 - 完全复制所有内容
pub fn RuntimeEnvironment::copy(
  self : RuntimeEnvironment,
) -> RuntimeEnvironment {
  let values = {}
  let mutable_vars = {}
  self.values.each(fn(key, value) { values.set(key, value) })
  self.mutable_vars.each(fn(key, is_mutable) {
    mutable_vars.set(key, is_mutable)
  })
  let parent = match self.parent {
    Some(parent) => Some(parent.copy())
    None => None
  }
  { values, mutable_vars, parent }
}

///|
/// 为闭包创建捕获环境 - 实现正确的变量捕获语义
pub fn RuntimeEnvironment::create_closure_env(
  self : RuntimeEnvironment,
) -> RuntimeEnvironment {
  let values = {}
  let mutable_vars = {}

  // 只捕获不可变变量的值,可变变量通过父环境引用
  self.values.each(fn(key, value) {
    let is_mutable = self.mutable_vars.get(key).unwrap_or(false)
    if !is_mutable {
      // 不可变变量:捕获当前值
      values.set(key, value)
      mutable_vars.set(key, false)
    }
    // 可变变量不在闭包环境中捕获,通过parent引用访问
  })

  // 设置父环境为当前环境,这样可变变量可以通过父环境访问
  // 继承父环境的全局状态(如类型定义、方法等)
  { values, mutable_vars, parent: Some(self) }
}

///|
/// 处理函数声明体,创建Lambda函数
pub fn ClosureInterpreter::top_func_def_to_closure(
  self : ClosureInterpreter,
  pkg : RuntimePackage,
  func : @syntax.Impl,
  name? : String,
) -> (String?, RuntimeValue) {
  if func
    is TopFuncDef(
      fun_decl~,
      decl_body=DeclBody(expr=body),
      where_clause=_,
      loc~
    ) {
    let func = @syntax.Func::{
      parameters: fun_decl.decl_params.unwrap_or(@list.new()),
      params_loc: loc,
      body,
      return_type: fun_decl.return_type,
      error_type: fun_decl.error_type,
      kind: Arrow,
      is_async: fun_decl.is_async,
      loc,
    }
    let type_name = match fun_decl {
      { type_name: Some({ name: Ident(name~), .. }), .. } => Some(name)
      { type_name: Some({ name: Dot(id~, ..), .. }), .. } => Some(id)
      {
        decl_params: Some(
          More(
            Positional(
              binder={ name: "self", .. },
              ty=Some(Name(constr_id={ id: Ident(name~), .. }, ..))
            ),
            ..
          )
        ),
        ..,
      } => Some(name)
      _ => None
    }
    (type_name, Fn(self.create_function(func, pkg, name?)))
  } else {
    (None, Unit)
  }
}