Skip to content
Closed
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
73 changes: 59 additions & 14 deletions devel/200_28.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,69 @@
# [200_26] 提取内部桥接 helper,统一 (scheme char) 的 method_or_bust 语义
# [200_28] 迁移 (liii hash-table) 相关的实现到 s7_liii_hash_table.c

## 任务相关的代码文件
- src/s7.c
- src/s7_internal_helpers.h
- src/s7_scheme_char.c
- tests/goldfish/scheme/char-test.scm
- devel/200_26.md
- src/s7_liii_hash_table.h
- src/s7_liii_hash_table.c
- tests/goldfish/liii/hash-table-test.scm
- devel/200_28.md

## 如何测试
```
xmake b goldfish
bin/goldfish tests/goldfish/scheme/char-test.scm
bin/goldfish -m r7rs tests/goldfish/liii/hash-table-test.scm
```

## 2026/02/28 统一 (scheme char) 方法分派错误语义(missing-method / wrong-type-arg)
## 2026/03/05 迁移 hash-table? 函数

### What
为避免 `s7_scheme_char.c` 复制 `method_or_bust` 逻辑导致语义漂移,本次改动将字符模块改为复用 `s7.c` 内部语义:
1. 新增内部头文件 `src/s7_internal_helpers.h`,声明桥接函数:
- `s7i_method_or_bust`
- `s7i_method_or_bust_bool`
2. 在 `src/s7.c` 中新增桥接实现,内部直接调用原有 `method_or_bust`,确保行为与核心实现一致
3. 在 `src/s7_scheme_char.c` 中删除本地 `method_or_bust/method_or_bust_bool`,改为统一调用 `s7i_*` 桥接函数
4. 在 `tests/goldfish/scheme/char-test.scm` 增加回归测试,覆盖 openlet 对象参与字符相关调用时的异常语义
采用方案A:保持 g_is_hash_table 不动,先迁移其他使用公共 API 的 hash-table 函数。

本次改动将 `hash-table?` 函数从 s7.c 迁移到 s7_liii_hash_table.c:
1. 创建 `src/s7_liii_hash_table.h` 头文件,声明 `g_is_hash_table` 函数
2. 创建 `src/s7_liii_hash_table.c` 实现文件,包含 `g_is_hash_table` 函数实现
3. 在 `src/s7.c` 中添加 `#include "s7_liii_hash_table.h"`
4. 在 `src/s7.c` 中注释掉原来的 `g_is_hash_table` 实现,添加注释说明它已迁移
5. 在 `xmake.lua` 中添加 `src/s7_liii_hash_table.c` 到编译文件列表

### 分析

经过分析 s7.c 中的 hash-table 函数,发现:
- 大多数 hash-table 函数(如 `g_hash_table_ref`, `g_hash_table_set`, `g_make_hash_table` 等)都依赖于内部宏(如 `is_hash_table`, `hash_table_entries`, `check_boolean_method` 等)
- 只有 `g_is_hash_table` 可以完全使用公共 API 实现:
- `s7_is_hash_table` - 公共 API,检查是否为 hash-table
- `s7_car` - 公共 API,获取 car
- `s7_t`, `s7_f` - 公共 API,返回 #t 和 #f
- `s7_method` - 公共 API,查找方法
- `s7_make_symbol` - 公共 API,创建符号
- `s7_undefined` - 公共 API,返回 undefined
- `s7_apply_function` - 公共 API,应用函数
- `s7_cons` - 公共 API,创建 cons
- `s7_nil` - 公共 API,返回 nil

### 实现

`s7_liii_hash_table.c` 中的 `g_is_hash_table` 实现:
```c
s7_pointer g_is_hash_table(s7_scheme *sc, s7_pointer args)
{
#define H_is_hash_table "(hash-table? obj) returns #t if obj is a hash-table"
#define Q_is_hash_table sc->pl_bt

s7_pointer p = s7_car(args);
if (s7_is_hash_table(p)) return(s7_t(sc));
{
s7_pointer func = s7_method(sc, p, s7_make_symbol(sc, "hash-table?"));
if (func == s7_undefined(sc)) return(s7_f(sc));
return(s7_apply_function(sc, func, s7_cons(sc, p, s7_nil(sc))));
}
}
```

### 状态
- ✅ 编译通过:`xmake b goldfish`
- ✅ 测试通过:`bin/goldfish -m r7rs tests/goldfish/liii/hash-table-test.scm` (75 correct, 0 failed)

### 后续工作
由于大多数 hash-table 函数都依赖于 s7.c 内部宏,无法仅使用公共 API 实现。如需进一步迁移,需要:
1. 在 `s7_internal_helpers.h` 中添加更多桥接函数,暴露必要的内部功能
2. 或者将内部宏转换为可在 s7_liii_hash_table.c 中使用的辅助函数
12 changes: 5 additions & 7 deletions src/s7.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@
#include "s7_scheme_char.h"
#include "s7_liii_bitwise.h"
#include "s7_liii_string.h"
#include "s7_liii_hash_table.h"

/* there is also apparently __STDC_NO_COMPLEX__ */
#if WITH_CLANG_PP
Expand Down Expand Up @@ -42488,13 +42489,7 @@ static hash_entry_t *make_hash_entry(s7_scheme *sc, s7_pointer key, s7_pointer v
/* -------------------------------- hash-table? -------------------------------- */
bool s7_is_hash_table(s7_pointer p) {return(is_hash_table(p));}

static s7_pointer g_is_hash_table(s7_scheme *sc, s7_pointer args)
{
#define H_is_hash_table "(hash-table? obj) returns #t if obj is a hash-table"
#define Q_is_hash_table sc->pl_bt
check_boolean_method(sc, is_hash_table, sc->is_hash_table_symbol, args);
}

/* g_is_hash_table is now defined in s7_liii_hash_table.c */

/* -------------------------------- hash-table-entries -------------------------------- */
static s7_pointer g_hash_table_entries(s7_scheme *sc, s7_pointer args)
Expand Down Expand Up @@ -97355,6 +97350,9 @@ static void init_rootlet(s7_scheme *sc)
sc->is_complex_vector_symbol = bool_defun("complex-vector?", is_complex_vector, 0, T_COMPLEX_VECTOR, mark_simple_vector, true);
sc->is_int_vector_symbol = bool_defun("int-vector?", is_int_vector, 0, T_INT_VECTOR, mark_simple_vector, true);
sc->is_byte_vector_symbol = bool_defun("byte-vector?", is_byte_vector, 0, T_BYTE_VECTOR, mark_simple_vector, true);

#define H_is_hash_table "(hash-table? obj) returns #t if obj is a hash-table"
#define Q_is_hash_table sc->pl_bt
sc->is_hash_table_symbol = bool_defun("hash-table?", is_hash_table, 0, T_HASH_TABLE, mark_vector_1, false);
sc->is_continuation_symbol = bool_defun("continuation?", is_continuation, 0, T_CONTINUATION, mark_vector_1, false);
sc->is_procedure_symbol = bool_defun("procedure?", is_procedure, 0, T_FREE, mark_vector_1, false);
Expand Down
23 changes: 23 additions & 0 deletions src/s7_liii_hash_table.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* s7_liii_hash_table.c - hash-table utility implementations for s7 Scheme interpreter
*
* derived from s7, a Scheme interpreter
* SPDX-License-Identifier: 0BSD
*
* Bill Schottstaedt, bil@ccmu.stanford.edu
*/

#include "s7_liii_hash_table.h"

s7_pointer g_is_hash_table(s7_scheme *sc, s7_pointer args)
{
#define H_is_hash_table "(hash-table? obj) returns #t if obj is a hash-table"
#define Q_is_hash_table sc->pl_bt

s7_pointer p = s7_car(args);
if (s7_is_hash_table(p)) return(s7_t(sc));
{
s7_pointer func = s7_method(sc, p, s7_make_symbol(sc, "hash-table?"));
if (func == s7_undefined(sc)) return(s7_f(sc));
return(s7_apply_function(sc, func, s7_cons(sc, p, s7_nil(sc))));
}
}
24 changes: 24 additions & 0 deletions src/s7_liii_hash_table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* s7_liii_hash_table.h - hash-table utility declarations for s7 Scheme interpreter
*
* derived from s7, a Scheme interpreter
* SPDX-License-Identifier: 0BSD
*
* Bill Schottstaedt, bil@ccrma.stanford.edu
*/

#ifndef S7_LIII_HASH_TABLE_H
#define S7_LIII_HASH_TABLE_H

#include "s7.h"

#ifdef __cplusplus
extern "C" {
#endif

s7_pointer g_is_hash_table(s7_scheme *sc, s7_pointer args);

#ifdef __cplusplus
}
#endif

#endif /* S7_LIII_HASH_TABLE_H */
1 change: 1 addition & 0 deletions xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ target ("goldfish") do
add_files ("src/s7_scheme_char.c", {languages = "c11"})
add_files ("src/s7_liii_bitwise.c", {languages = "c11"})
add_files ("src/s7_liii_string.c", {languages = "c11"})
add_files ("src/s7_liii_hash_table.c", {languages = "c11"})
add_files ("src/s7_scheme_inexact.c", {languages = "c11"})
add_files ("src/s7_scheme_base.c", {languages = "c11"})
add_packages("tbox")
Expand Down