Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions devel/0095.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# [0095] 把 scheme_let.c 相关的函数从 (liii base) 迁移到 (scheme let)

## 任务相关的代码文件
- goldfish/scheme/let.scm (新增:(scheme let) 库)
- goldfish/liii/base.scm (修改:移除 20 个 let 相关函数的 export)
- tests/scheme/let-test.scm (新增:(scheme let) 模块概览文档)
- tests/scheme/let/*-test.scm (从 tests/liii/base/ 迁入 20 个测试文件)
- devel/0095.md

相关文档:devel/0092.md

## 如何测试
```bash
xmake b goldfish
bin/gf doc --build-json

# 验证 doc 可访问且归属 (scheme let)
bin/gf doc inlet
bin/gf doc funclet
bin/gf doc "let-set!"
bin/gf doc "symbol->value"
bin/gf doc scheme/let

# 运行迁移的 20 个测试
for f in tests/scheme/let/*-test.scm; do bin/gf $f; done

# 完整测试套件
bin/gf test --all
```

## 2026-08-06 迁移 20 个 let 相关函数到 (scheme let)

### What
1. 新增 `goldfish/scheme/let.scm`,定义 `(scheme let)` 库,导出 20 个
scheme_let.c 实现的 let 相关函数:
`let?` `openlet?` `funclet?`(谓词)
`curlet` `outlet` `rootlet` `owlet` `funclet`(环境获取)
`inlet` `sublet` `varlet` `cutlet` `openlet` `coverlet` `unlet`(环境构造与操作)
`let-ref` `let-set!` `let->list`(绑定访问)
`symbol->value` `symbol->dynamic-value`(符号查找)
2. 从 `goldfish/liii/base.scm` 的 export 列表移除上述 20 个函数
(`defined?` 在 0092 之前就属于 `(liii base)` 的通用工具函数,保留不动)。
3. 将 20 个测试文件从 `tests/liii/base/` 迁移到 `tests/scheme/let/`,
import 由 `(liii base)` 改为 `(scheme let)`。
4. 新增 `tests/scheme/let-test.scm` 模块概览文档,`gf doc scheme/let` 可用。
5. `bin/gf doc --build-json` 重建索引后,20 个函数均归属 `(scheme let)`;
`bin/gf test --all` 共 1493 项全部通过。

### Why
这 20 个函数由 src/s7_scheme_let.c 实现(0092 从 s7.c 拆出),是 S7 的
环境操作 API,放在 `(liii base)` 只是过渡;独立的 `(scheme let)` 库
边界更清晰,与 `(scheme eval)` 等库的风格一致。

### How
- **空 begin 即可导出**:`define-library` 的库体在 `(sublet (unlet))`
环境中求值,s7 内建函数天然可见,export 只需列名字(同 `scheme/cxr.scm`
的先例),无需 import 或重新定义。
- **移除 export 不破坏依赖方**:`(liii case)` 等在库体内使用 `funclet`/
`curlet`/`symbol->value`,库体环境继承自 unlet,与 import 无关;
脚本顶层环境是 rootlet,同样不受影响。gf REPL 预 import `(liii base)`
也不受影响。
- **测试文件即文档**:golddoc 按 `tests/<group>/<library>/<func>-test.scm`
定位文档,`git mv` 到 `tests/scheme/let/` 并改 import 后即完成迁移。
20 changes: 0 additions & 20 deletions goldfish/liii/base.scm
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,6 @@
call-with-output-string
reverse!
format
let?
openlet?
funclet?
curlet
outlet
rootlet
owlet
funclet
inlet
sublet
varlet
cutlet
openlet
coverlet
unlet
let-ref
let-set!
let->list
symbol->value
symbol->dynamic-value
) ;export
(begin

Expand Down
47 changes: 47 additions & 0 deletions goldfish/scheme/let.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
;;
;; Copyright (C) 2026 The Goldfish Scheme Authors
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
;; License for the specific language governing permissions and limitations
;; under the License.
;;

(define-library (scheme let)
(export
;; 谓词
let?
openlet?
funclet?
;; 环境获取
curlet
outlet
rootlet
owlet
funclet
;; 环境构造与操作
inlet
sublet
varlet
cutlet
openlet
coverlet
unlet
;; 绑定访问
let-ref
let-set!
let->list
;; 符号查找
symbol->value
symbol->dynamic-value
) ;export
(begin
) ;begin
) ;define-library
52 changes: 52 additions & 0 deletions tests/scheme/let-test.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
;; (scheme let) 模块函数分类索引
;;
;; `(scheme let)` 提供 S7 风格的环境(let)操作函数。
;; 在 S7/Goldfish 中,环境本身是一等公民对象,可以创建、查询、组合和修改,
;; 适合实现模块系统、沙箱求值、面向对象等需要显式操控环境的场景。
;;
;; ==== 常见用法示例 ====
(import (scheme let))
;; 示例1:创建一个独立环境并访问其中的绑定

(define e (inlet 'x 1 'y 2))
(let-ref e 'x)
;; 示例2:基于现有环境派生新环境(不修改原环境)

(define e2 (sublet e 'z 3))
(let-ref e2 'z)
;; 示例3:在指定环境中求值
(eval '(+ x y) e)
;; ==== 如何查看函数的文档和用例 ====
;; bin/gf doc scheme/let "inlet"
;; bin/gf doc scheme/let "let-ref"
;; ==== 函数分类索引 ====
;; 一、谓词
;; 用于判断对象类型的函数
;; let? - 判断对象是否为 let(环境对象)
;; openlet? - 判断 let 是否为开放环境
;; funclet? - 判断 let 是否为函数的闭包环境
;; 二、环境获取
;; 用于获取已有环境的函数
;; curlet - 返回当前词法环境
;; outlet - 返回环境的外层环境
;; rootlet - 返回根环境
;; owlet - 返回全局(最外层)环境链
;; funclet - 返回函数的闭包环境
;; 三、环境构造与操作
;; 用于创建或修改环境的函数
;; inlet - 创建新的环境
;; sublet - 基于现有环境派生新环境(不改父环境)
;; varlet - 向环境中添加绑定(就地修改)
;; cutlet - 从环境中删除绑定(就地修改)
;; openlet - 将环境标记为开放环境
;; coverlet - 将开放环境恢复为封闭环境
;; unlet - 返回内建函数原始绑定所在的环境
;; 四、绑定访问
;; 用于读写环境中绑定的函数
;; let-ref - 读取环境中符号对应的值
;; let-set! - 修改环境中符号对应的值
;; let->list - 将环境的绑定转换为关联列表
;; 五、符号查找
;; 用于在环境中查找符号绑定的函数
;; symbol->value - 在指定环境中查找符号的值
;; symbol->dynamic-value - 在动态环境中查找符号的值
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))
(import (liii json))


Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(import (liii check))
(import (liii base))
(import (scheme let))


(check-set-mode! 'report-failed)
Expand Down
Loading