From 54ee19fa42e50540fd83a501de63c25f18fbd9aa Mon Sep 17 00:00:00 2001 From: Da Shen Date: Sun, 2 Nov 2025 14:50:42 +0800 Subject: [PATCH 1/6] wip --- tests/goldfish/liii/lang-test.scm | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/tests/goldfish/liii/lang-test.scm b/tests/goldfish/liii/lang-test.scm index 8e2d00c0..018dba75 100644 --- a/tests/goldfish/liii/lang-test.scm +++ b/tests/goldfish/liii/lang-test.scm @@ -25,26 +25,6 @@ (define == class=?) (check-set-mode! 'report-failed) -(define-object string-utils - (define (@concat x y) - (string-append x y)) - ) - -(check (string-utils :concat "a" "b") => "ab") - -(define-object object1 - (define x 0) - (define (@concat x y) - (string-append x y)) - ) - -(define-object object2 - (define y 0) - (define (@return-object1) object1) - ) - -(check ((object2 :return-object1) :concat "a" "b") => "ab") - ;; Test define-class (可变类) (let () (define-class person -- Gitee From 14ed57a2b3fe80da60d142d3f21db76ff4a1c8ee Mon Sep 17 00:00:00 2001 From: Da Shen Date: Sun, 2 Nov 2025 14:56:25 +0800 Subject: [PATCH 2/6] wip --- devel/209_5.md | 29 ++++++++++ tests/goldfish/liii/lang-test.scm | 32 ----------- tests/goldfish/liii/oop-test.scm | 91 +++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 32 deletions(-) create mode 100644 devel/209_5.md diff --git a/devel/209_5.md b/devel/209_5.md new file mode 100644 index 00000000..36484f09 --- /dev/null +++ b/devel/209_5.md @@ -0,0 +1,29 @@ +# [209_5] 为 define-class 新增文档 + +## 任务相关的代码文件 +- goldfish/liii/oop.scm +- tests/goldfish/liii/oop-test.scm + +## 如何测试 +``` +xmake config --yes +xmake b goldfish +bin/goldfish tools/lint.scm goldfish/liii/oop.scm +bin/goldfish tools/lint.scm tests/goldfish/liii/oop-test.scm +bin/goldfish -m r7rs tests/goldfish/liii/oop-test.scm +``` + +## 2025/11/02 define-class 文档撰写 +### What +撰写 `(liii oop)` 模块中 `define-class` 宏的文档,包括语法说明、参数说明、使用示例和注意事项。 + +1. 分析 `define-class` 宏的实现逻辑和功能 +2. 编写详细的宏文档说明 +3. 提供丰富的使用示例 +4. 说明宏的行为特性和限制 + +### Why +`define-class` 宏是 `(liii oop)` 模块中的重要宏之一,用于创建具有私有字段和自动生成 getter/setter 的类。通过完善文档,帮助开发者更好地理解和使用该宏来构建面向对象的代码结构。 + +### How +通过分析源代码实现和现有测试用例,理解宏的参数处理、字段定义机制、自动生成的 getter/setter 功能,编写全面准确的文档说明。 \ No newline at end of file diff --git a/tests/goldfish/liii/lang-test.scm b/tests/goldfish/liii/lang-test.scm index 018dba75..35cd90ee 100644 --- a/tests/goldfish/liii/lang-test.scm +++ b/tests/goldfish/liii/lang-test.scm @@ -25,38 +25,6 @@ (define == class=?) (check-set-mode! 'report-failed) -;; Test define-class (可变类) -(let () - (define-class person - ((name string? "") - (age integer? 0)) - - (define (@apply name) - (let1 r (person) - (r :set-name! name) - (r :set-age! 10) - r))) - - ;; 测试@apply - (define p1 (person)) - (define p2 (person "Bob")) - - ;; 测试setter和getter - (p1 :set-name! "Alice") - (p1 :set-age! 25) - (check (p1 :get-name) => "Alice") - (check (p1 :get-age) => 25) - (check (p2 :get-name) => "Bob") - (check (p2 :get-age) => 10) - - (check-true (person :is-type-of p1)) - (check-true (person :is-type-of p2)) - - ;; 测试类型检查 - (check-catch 'type-error (p1 :set-name! 123)) - (check-catch 'type-error (p1 :set-age! "invalid")) - ) - (check-false (case-class? (lambda (x) x))) (check-false (case-class? +)) (check-false (case-class? identity)) diff --git a/tests/goldfish/liii/oop-test.scm b/tests/goldfish/liii/oop-test.scm index 370f4493..c7c2d34a 100644 --- a/tests/goldfish/liii/oop-test.scm +++ b/tests/goldfish/liii/oop-test.scm @@ -453,5 +453,96 @@ define-object 是 (liii oop) 模块中用于创建对象的宏,它创建一个 (check-catch 'value-error (string-utils)) +#| +define-class +定义一个具有私有字段和自动生成 getter/setter 的类。 + +语法 +----- +(define-class class-name ((field-name type-predicate [default-value]) ...) method-definition ...) + +参数 +----- +class-name : symbol +要定义的类名称,必须是一个符号。 + +field-name : symbol +私有字段的名称。 + +type-predicate : procedure +字段的类型断言函数,用于验证字段值的类型。 + +default-value : any (可选) +字段的默认值,如果未提供则使用空列表。 + +method-definition : any +类的方法定义,可以是静态方法、实例方法或内部方法。 + +返回值 +----- +返回 #t,表示类定义成功。 + +描述 +----- +define-class 是 (liii oop) 模块中用于创建类的宏,它基于 define-case-class 构建, +提供了自动生成私有字段的 getter 和 setter 方法的功能。 + +该宏会自动为每个私有字段生成: +- 字段定义:使用默认值初始化字段 +- Getter 方法:格式为 `:get-fieldname`,返回字段值 +- Setter 方法:格式为 `:set-fieldname!`,设置字段值(带类型检查) + +生成的 getter 和 setter 方法通过消息传递机制调用,例如: +- `(instance :get-name)` 获取 name 字段的值 +- `(instance :set-name! "Alice")` 设置 name 字段的值 + +特点 +----- +- 自动为私有字段生成 getter 和 setter 方法 +- 支持类型检查和默认值 +- 基于 define-case-class 构建,继承其所有特性 +- 支持静态方法(@前缀)、实例方法(%前缀)和内部方法 +- 类型验证在运行时进行 + +注意事项 +----- +- 类名称必须是符号 +- 字段类型断言函数必须是一个过程 +- setter 方法会进行类型检查,类型不匹配会抛出 type-error +- 默认值在类定义时计算,如果涉及变量引用会捕获当前环境 +- 支持任意数量的私有字段和方法定义 +|# +(let () + (define-class person + ((name string? "") + (age integer? 0)) + + (define (@apply name) + (let1 r (person) + (r :set-name! name) + (r :set-age! 10) + r))) + + ;; 测试@apply + (define p1 (person)) + (define p2 (person "Bob")) + + ;; 测试setter和getter + (p1 :set-name! "Alice") + (p1 :set-age! 25) + (check (p1 :get-name) => "Alice") + (check (p1 :get-age) => 25) + (check (p2 :get-name) => "Bob") + (check (p2 :get-age) => 10) + + (check-true (person :is-type-of p1)) + (check-true (person :is-type-of p2)) + + ;; 测试类型检查 + (check-catch 'type-error (p1 :set-name! 123)) + (check-catch 'type-error (p1 :set-age! "invalid")) + ) + + (check-report) -- Gitee From d97dfe5f9883d01c969cc07abc23d1d79cf230ad Mon Sep 17 00:00:00 2001 From: Da Shen Date: Sun, 2 Nov 2025 15:03:19 +0800 Subject: [PATCH 3/6] =?UTF-8?q?[209=5F5]=20=E4=B8=BA=20define-class=20?= =?UTF-8?q?=E5=92=8C=20define-case-class=20=E6=B7=BB=E5=8A=A0=20is-type-of?= =?UTF-8?q?=20=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- tests/goldfish/liii/oop-test.scm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/goldfish/liii/oop-test.scm b/tests/goldfish/liii/oop-test.scm index c7c2d34a..aefbd1d6 100644 --- a/tests/goldfish/liii/oop-test.scm +++ b/tests/goldfish/liii/oop-test.scm @@ -205,6 +205,7 @@ procedure - 方法分发: 支持静态方法和实例方法 - 相等性比较: 自动实现 `:equals` 方法 - 字符串表示: 自动实现 `:to-string` 方法 +- 类型检查: 自动生成 `:is-type-of` 静态方法 注意事项 ---- @@ -503,6 +504,7 @@ define-class 是 (liii oop) 模块中用于创建类的宏,它基于 define-ca - 基于 define-case-class 构建,继承其所有特性 - 支持静态方法(@前缀)、实例方法(%前缀)和内部方法 - 类型验证在运行时进行 +- 自动生成 `:is-type-of` 静态方法用于类型检查 注意事项 ----- -- Gitee From 6b97367522da46d2b7206945d8434dbd65ecfed0 Mon Sep 17 00:00:00 2001 From: Da Shen Date: Sun, 2 Nov 2025 15:12:18 +0800 Subject: [PATCH 4/6] =?UTF-8?q?[209=5F5]=20=E4=B8=BA=20case-class=3F=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=B7=BB=E5=8A=A0=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- tests/goldfish/liii/oop-test.scm | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tests/goldfish/liii/oop-test.scm b/tests/goldfish/liii/oop-test.scm index aefbd1d6..a0977ade 100644 --- a/tests/goldfish/liii/oop-test.scm +++ b/tests/goldfish/liii/oop-test.scm @@ -545,6 +545,59 @@ define-class 是 (liii oop) 模块中用于创建类的宏,它基于 define-ca (check-catch 'type-error (p1 :set-age! "invalid")) ) +#| +case-class? +判断一个对象是否为案例类(case class)实例。 + +语法 +----- +(case-class? obj) + +参数 +----- +obj : any +待检查的对象,可以是任何 Goldfish Scheme 值。 + +返回值 +----- +boolean +如果对象是案例类实例则返回 #t,否则返回 #f。 + +描述 +----- +case-class? 是 (liii oop) 模块中用于类型检查的函数,它判断给定的对象是否是通过 +`define-case-class` 或 `define-class` 宏创建的案例类实例。 + +该函数通过分析对象的源代码结构来识别案例类,具体检查: +- 对象是否为过程 +- 过程源代码是否具有特定的结构 +- 过程体中是否包含案例类特有的消息分发模式 +- 是否包含 `:is-instance-of` 和 `:equals` 方法 + +特点 +----- +- 运行时类型检查:在运行时动态判断对象类型 +- 结构识别:通过源代码结构识别案例类 +- 通用性:适用于所有通过 define-case-class 和 define-class 创建的对象 +- 精确性:能够准确区分案例类实例和普通过程 + +注意事项 +----- +- 只能识别通过 define-case-class 和 define-class 创建的案例类 +- 对于其他类型的对象(包括普通过程、数字、字符串等)返回 #f +- 依赖于过程源代码的结构,不适用于编译后优化的代码 +- 是底层类型检查函数,通常使用 `:is-type-of` 方法进行类型检查更直观 +|# +(check-false (case-class? (lambda (x) x))) +(check-false (case-class? +)) +(check-false (case-class? identity)) + +(let ((bob (person "Bob" 21))) + (check-true (case-class? bob)) + (check-false (case-class? +)) + (check-false (case-class? 42)) + ) + (check-report) -- Gitee From 3a57e3c287b5d350c590074a38cce4e1ebe34913 Mon Sep 17 00:00:00 2001 From: Da Shen Date: Sun, 2 Nov 2025 15:12:27 +0800 Subject: [PATCH 5/6] wip --- tests/goldfish/liii/lang-test.scm | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/goldfish/liii/lang-test.scm b/tests/goldfish/liii/lang-test.scm index 35cd90ee..6ee0a26f 100644 --- a/tests/goldfish/liii/lang-test.scm +++ b/tests/goldfish/liii/lang-test.scm @@ -25,16 +25,6 @@ (define == class=?) (check-set-mode! 'report-failed) -(check-false (case-class? (lambda (x) x))) -(check-false (case-class? +)) -(check-false (case-class? identity)) - -(let ((bob (person "Bob" 21))) - (check-true (case-class? bob)) - (check-false (case-class? +)) - (check-false (case-class? 42)) - ) - (check (class=? (list 1 2) (list 1 2)) => #t) (check (class=? (box 10) 10) => #t) (check (class=? 10 (box 10)) => #t) -- Gitee From b5261480b425b95a8826a5416ecabe827572ee68 Mon Sep 17 00:00:00 2001 From: Da Shen Date: Sun, 2 Nov 2025 15:16:02 +0800 Subject: [PATCH 6/6] wip --- tests/goldfish/liii/lang-test.scm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/goldfish/liii/lang-test.scm b/tests/goldfish/liii/lang-test.scm index 6ee0a26f..9f9cdc8a 100644 --- a/tests/goldfish/liii/lang-test.scm +++ b/tests/goldfish/liii/lang-test.scm @@ -25,6 +25,10 @@ (define == class=?) (check-set-mode! 'report-failed) +(define-case-class person + ((name string? "Bob") + (age integer?))) + (check (class=? (list 1 2) (list 1 2)) => #t) (check (class=? (box 10) 10) => #t) (check (class=? 10 (box 10)) => #t) -- Gitee