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
69 changes: 69 additions & 0 deletions devel/200_30.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# [200_30] 迁移 (liii hash-table) 相关的实现到 s7_liii_hash_table.c

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

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

## 2026/03/05 迁移 hash-table? 函数

### What
采用方案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