pscm_cc 功能现状与开发规划
本文档总结 pscm_cc 的现有功能特性,并规划实现驱动 TeXmacs 所需的功能。
pscm_cc 已实现 Scheme 的核心功能,包括:
- ✅ 完整的类型系统(19 种数据类型,包括
MODULE) - ✅ 核心特殊形式(包括
delay/force) - ✅ Continuation 支持
- ✅ 宏系统(支持 dotted pair 参数,包含
macroexpand-1和macroexpand调试工具) - ✅ 模块系统和文件加载(完整的模块定义、使用、导出和文件加载功能)
- ✅ 丰富的内置函数(包括
gcd、lcm)
一、现有功能总结
1.1 核心基础设施 ✅
- 类型系统:统一
SCM类型,支持 19 种数据类型(包括PORT、PROMISE、MODULE) - 解析器:递归下降解析器,支持完整 Scheme 语法
- 求值器:支持尾递归优化,模块化特殊形式处理
- 环境系统:词法作用域,链表结构环境
- 错误报告:源位置跟踪,清晰的错误信息
1.2 数据类型支持 ✅
| 类型 | 状态 | 说明 |
|---|---|---|
NIL | ✅ | 空列表 |
LIST | ✅ | 列表和点对 |
NUM | ✅ | 整数 |
FLOAT | ✅ | 浮点数 |
RATIO | ✅ | 有理数(分数) |
CHAR | ✅ | 字符 |
STR | ✅ | 字符串 |
SYM | ✅ | 符号 |
BOOL | ✅ | 布尔值 |
PROC | ✅ | Scheme 过程 |
FUNC | ✅ | C/C++ 函数 |
CONT | ✅ | Continuation |
MACRO | ✅ | 宏 |
HASH_TABLE | ✅ | 哈希表 |
VECTOR | ✅ | 向量 |
PORT | ✅ | 端口 |
PROMISE | ✅ | Promise(延迟求值) |
MODULE | ✅ | 模块 |
1.3 特殊形式支持 ✅
- 定义:
define,define-macro,lambda,set! - 控制流:
if,cond(支持else和=>),case,and,or,begin - 作用域:
let,let*,letrec(通过宏展开) - 循环:
do,for-each,map - 引用:
quote,quasiquote - 函数应用:
apply - Continuation:
call/cc,call-with-current-continuation - 多值:
call-with-values,values - 动态控制:
dynamic-wind - 延迟求值:
delay,force
1.4 内置函数支持 ✅
类型检查
procedure?, boolean?, null?, pair?, char?, number?
列表操作
car, cdr, cadr, cddr, caddr, cons, list, append, list-head, list-tail, last-pair, set-car!, set-cdr!
数字运算
- 算术:
+,-,*,/,expt,abs,gcd,lcm - 比较:
=,<,>,<=,>=,negative? - 类型提升:整数、浮点数、分数混合运算
字符操作
char?, char->integer, integer->char, char=?, char<?, char>?, char<=?, char>=?, char-upcase, char-downcase
字符串操作
string-length, make-string, string-ref, string-set!, string=?, string<?, string<=?, substring, string-append, string->list, list->string, display, write, newline
相等性判断
eq?, eqv?, equal?
关联列表
assv, assoc, acons, assoc-ref, assoc-set!, assq-set!, assoc-remove!
哈希表
完整的哈希表操作集(创建、设置、获取、删除、遍历)
端口操作
open-input-file, open-output-file, open-input-string, open-output-string, close-input-port, close-output-port, read, read-char, peek-char, write-char, eof-object?, char-ready?, input-port?, output-port?, get-output-string, call-with-input-file, call-with-output-file, call-with-input-string, call-with-output-string
系统操作
exit
延迟求值
delay, force
宏调试工具
macroexpand-1, macroexpand
其他
gensym, not, eval
1.5 C/C++ 函数注册 ✅
scm_define_function:固定参数函数scm_define_generic_function:泛型函数scm_define_vararg_function:可变参数函数
1.6 宏系统 ✅
- 宏定义:
define-macro支持定义宏,支持 dotted pair 参数列表(如(define-macro (foo x y . z) ...)) - 宏展开:正确处理宏参数绑定和展开,包括 rest 参数的绑定
- 宏调试工具:
macroexpand-1 expr:展开宏一次(如果expr是宏调用),类似 Guile 1.8 的macroexpand-1macroexpand expr:递归展开宏直到没有更多宏可展开,类似 Guile 1.8 的macroexpand- 支持在模块环境中查找宏,正确处理用户定义的宏(如重新定义的
letrec)
- Dotted Pair 支持:
- 宏展开时正确保留 dotted pair 结构(
is_dotted标记) expand_macros函数在递归展开列表时保留is_dotted标记quasi函数正确处理 quasiquote 中的 dotted pair,包括unquote-splicing后跟 dotted pair 的情况
- 宏展开时正确保留 dotted pair 结构(
- Quasiquote 集成:宏中使用的
quasiquote正确处理 dotted pair,确保(lambda (x y . z) z)等结构在宏展开后仍保持正确 - Unquote-splicing 修复:修复了
unquote-splicing(,@) 在处理 dotted pair 时的 BUG,现在可以正确展开包含多个元素的列表(如letrec宏中的多个set!表达式) - 测试覆盖:包含 rest 参数宏、dotted pair 参数宏、quasiquote 中 dotted pair 的完整测试
二、缺失功能分析
2.1 端口(Port)系统 ✅
优先级:✅ 已完成
端口系统已完整实现,包括文件端口和字符串端口功能。
已实现功能
- 端口类型:输入端口、输出端口 ✅
- 文件端口:
open-input-file filename→ 输入端口 ✅open-output-file filename→ 输出端口 ✅close-input-port port✅close-output-port port✅
- 字符串端口:
open-input-string string→ 输入端口 ✅open-output-string→ 输出端口 ✅get-output-string port→ 字符串 ✅
- 端口操作:
read port:从端口读取 Scheme 对象 ✅read-char port:读取字符 ✅peek-char port:查看下一个字符 ✅eof-object? obj:判断是否为文件结束对象 ✅char-ready? port:判断字符是否就绪 ✅write-char char port:写入字符 ✅
- 端口谓词:
input-port? port:判断是否为输入端口 ✅output-port? port:判断是否为输出端口 ✅
- 端口包装:
call-with-input-file filename proc✅call-with-output-file filename proc✅call-with-input-string string proc✅call-with-output-string proc✅
2.2 文件加载系统 ✅
优先级:✅ 已完成
已实现功能
parse_file:解析文件为 AST 列表 ✅load filename:加载并执行 Scheme 文件 ✅primitive-load filename:底层加载函数(Guile 兼容)✅- 加载路径管理:
%load-path支持路径搜索 ✅ - 模块集成:加载文件时自动处理
define-module,支持模块文件自动加载 ✅
实现特点
- ✅
load函数调用parse_file并逐个求值 - ✅ 支持相对路径和搜索路径(通过
%load-path) - ✅ 错误处理:文件不存在、解析错误等
2.3 模块系统 ✅
优先级:✅ 已完成
TeXmacs 大量使用模块系统组织代码。
已实现功能
- 模块定义:
define-module name:定义模块 ✅current-module:获取当前模块 ✅
- 模块使用:
use-modules spec ...:使用模块 ✅module-use! module spec:模块操作 ✅
- 模块查询:
resolve-module name:解析模块 ✅module-ref module symbol:获取模块变量 ✅module-bound? module symbol:检查模块绑定 ✅
- 模块导出:
define-public name value:定义并导出 ✅export symbol ...:导出符号 ✅
- 模块接口:
- 模块环境管理:每个模块有独立环境 ✅
- 模块解析:支持模块路径搜索(通过
%load-path)✅
实现特点
- ✅ 添加了
MODULE类型 - ✅ 模块环境管理:每个模块有独立环境
- ✅ 模块解析:支持模块路径搜索
- ✅ 模块查找:支持从模块的
obarray、uses列表和根模块中查找变量
2.4 错误处理机制 ⚠️
优先级:🟡 中
已实现功能
eval_error:错误报告 ✅- 源位置跟踪 ✅
- 调用栈追踪:自动追踪表达式求值路径,错误时显示完整调用栈(最多 20 层)✅
- 增强的错误报告:包含表达式类型、值、源位置和完整求值上下文 ✅
缺失功能
- 异常捕获:
catch tag thunk handler:捕获异常throw key args ...:抛出异常
- 错误对象:
- 错误类型系统
- 错误消息格式化
- 错误恢复:
- 优雅的错误处理(而非直接
exit(1))
- 优雅的错误处理(而非直接
实现要点
- 实现异常系统(可基于 continuation)
- 错误类型定义
- 错误处理流程改进(从
exit(1)改为可恢复的错误处理)
2.5 更多特殊形式 ✅
优先级:✅ 已完成
已实现功能
case expr clause ...:多路分支 ✅and expr ...:逻辑与(短路求值)✅or expr ...:逻辑或(短路求值)✅delay expr:延迟求值(Promise)✅force promise:强制求值 ✅
实现说明
- Promise 类型:添加了
PROMISE类型,支持延迟求值 - 重入处理:
force实现正确处理重入调用(re-entrant force),符合 R5RS 规范 - 测试覆盖:包含基础用法、多次 force、懒序列(stream)和重入 force 的完整测试
2.6 更多内置函数 ⚠️
优先级:🟢 低
已实现功能
- 字符操作:
char=?,char<?,char>?,char<=?,char>=?:字符比较 ✅char-upcase,char-downcase:大小写转换 ✅
- 字符串操作:
string=?,string<?,string<=?:字符串比较 ✅substring,string-append:字符串操作 ✅string->list,list->string:转换 ✅
- 向量操作:
vector->list,list->vector:转换 ✅
- 数字运算:
gcd n1 ...:最大公约数(支持可变参数)✅lcm n1 ...:最小公倍数(支持可变参数)✅
- 系统操作:
exit code:退出程序 ✅
缺失功能
- 系统操作:
transcript-on filename:开始记录transcript-off:停止记录
2.7 Guile API 兼容层 ❌
优先级:🔴 高
TeXmacs 通过 Guile C API 与 Scheme 交互。
缺失功能
- 基本操作:c
SCM scm_cons(SCM car, SCM cdr); SCM scm_car(SCM pair); SCM scm_cdr(SCM pair); SCM scm_list1(SCM obj1); SCM scm_list2(SCM obj1, SCM obj2); SCM scm_list3(SCM obj1, SCM obj2, SCM obj3); - 求值:c
SCM scm_eval(SCM expr, SCM env); SCM scm_eval_string(const char* str); SCM scm_eval_file(const char* filename); - 环境:c
SCM scm_interaction_environment(); SCM scm_current_module(); - 变量操作:c
void scm_define(SCM env, SCM symbol, SCM value); SCM scm_lookup(SCM env, SCM symbol); - 过程调用:c
SCM scm_call(SCM proc, SCM args); SCM scm_apply(SCM proc, SCM args); - 错误处理:c
void scm_error(const char* subr, const char* fmt, ...); SCM scm_catch(SCM tag, SCM* (*thunk)(void*), void* data, SCM* (*handler)(void*, SCM), void* handler_data);
实现要点
- 创建
guile_compat.h和guile_compat.cc - 类型转换:
SCM*↔SCM(void*) - API 映射:将内部实现映射到 Guile API
- 行为一致性:确保与 Guile 1.8 行为一致
2.8 垃圾回收(GC)❌
优先级:🔴 高
当前所有内存都不会释放,存在内存泄漏。
实现方案
- 标记-清除(Mark-and-Sweep):
- 标记所有可达对象
- 清除未标记对象
- 根对象注册:
- 全局环境
- Continuation 栈
- 当前执行上下文
- 对象遍历:
- 递归遍历所有引用
- 标记可达对象
实现要点
- 统一内存分配接口
- 对象标记机制
- GC 触发时机(分配时、手动触发)
- 与 continuation 的兼容性
2.9 性能优化 ⚠️
优先级:🟢 低
当前问题
- 环境查找:O(n) 线性搜索
- 符号比较:使用
memcmp
优化方向
- 环境查找优化:
- 使用哈希表优化环境查找(哈希表已实现)
- 将查找复杂度降至 O(1)
- 符号表优化:
- 符号去重(interning)
- 快速符号比较
- 其他优化:
- 热点代码识别
- 尾调用优化改进