cl-forth:用CL实现的Forth 2012标准
摘要
CL-Forth 是 Forth 2012 标准的 Common Lisp 实现,支持多种 Lisp 实现和操作系统,并提供独立可执行文件选项。
查看缓存全文
缓存时间: 2026/08/06 20:13
gmpalter/cl-forth
Source: https://github.com/gmpalter/cl-forth
CL-Forth
CL-Forth 是 Forth 2012 标准(https://forth-standard.org)的 Common Lisp 实现。
支持的平台
CL-Forth 在 CCL v1.12.2-82 或更高版本上得到完全支持。
CL-Forth 在 SBCL 2.1.0 或更高版本上得到完全支持。
CL-Forth 在 LispWorks 8.0.1 或更高版本上得到完全支持。
CL-Forth 支持 ECL 26.3.27 或更高版本。但目前,String 词集测试中有两个失败的测试尚未查明原因。
支持的操作系统
CL-Forth 支持 macOS、Linux 和 Windows。
在 macOS 上,已确认可运行于 macOS Ventura 或更高版本。
在 Linux 上,已确认可运行于内核版本为 5.10.162 或更高的发行版。
在 Windows 上,已确认可运行于 Windows 10 或更高版本。
许可证
CL-Forth 依据 MIT 许可证 的条款提供。
使用方法
CL-Forth 使用 ASDF 定义,并依赖于 CFFI(https://github.com/cffi/cffi)和 trivial-gray-streams 库。
要获取 CL-Forth 以及 Forth 2012 测试套件(https://github.com/gerryjackson/forth2012-test-suite.git)的副本,该测试套件已配置为仅运行 CL-Forth 已实现的词集的测试。
bash git clone https://github.com/gmpalter/cl-forth.git --recurse-submodules
QuickLisp(https://www.quicklisp.org/)可能是获取 CFFI 和 trivial-gray-streams 库的最简单方式。请按照 QuickLisp 网页上的说明下载、安装并将 QuickLisp 添加到你的 Lisp 的初始化文件中。要安装这些库,请执行以下表达式。(只需执行一次。)
lisp (ql:quickload '#:cffi) (ql:quickload '#:trivial-gray-streams)
要将 CL-Forth 加载到 Lisp 中
lisp (require '#:asdf) (load "cl-forth.asd") (asdf:load-system '#:cl-forth)
你可以运行 Forth 2012 测试套件(https://github.com/gerryjackson/forth2012-test-suite.git)
lisp (asdf:test-system '#:cl-forth)
要启动 CL-Forth 解释器循环
lisp (forth:run)
CL-Forth 不区分大小写。
构建独立的 CL-Forth
你可以构建一个独立的 CL-Forth 应用程序。
启动 Lisp 并执行以下表达式
lisp (require '#:asdf) (load "cl-forth.asd") (asdf:load-system '#:cl-forth/application) (forth-app:save-application "cl-forth")
这将创建一个名为 cl-forth 的可执行文件。当你运行 cl-forth 时,它将直接启动进入 Forth 解释器循环。
forth ./cl-forth CL-Forth Version 1.3 Running under Clozure Common Lisp Version 1.13 (v1.13) DarwinX8664 1 1 + . 2 OK. : hello-world ." Hello World!" cr ; OK. hello-world Hello World! OK. see hello-world Source code for hello-world: (DEFUN FORTH-WORDS::HELLO-WORLD (FS &REST PARAMETERS) (DECLARE (IGNORABLE PARAMETERS)) (WITH-FORTH-SYSTEM (FS) (TAGBODY (WRITE-STRING "Hello World!") (TERPRI) :EXIT))) OK. bye In this session: 1 definition created 240 bytes of object code generated
该应用程序识别以下命令行参数
‐‐interpret EXPR, ‐i EXPR | 在进入 Forth 解释器循环之前执行 EXPR。EXPR 可能需要加引号以避免被 shell 解释。此参数可多次使用。 |
‐‐transcript PATH | 在文件 PATH 中记录本次会话的带时间戳的转录 |
‐‐help, ‐h | 显示可用的命令行参数并退出 |
‐‐version, ‐V | 显示 CL-Forth 的版本并退出 |
缺失的单词
CL-Forth 未实现可选的 Block 词集。
CL-Forth 未实现可选的 Extended-Character 词集。
CL-Forth 未实现属于 Core 词集的 KEY。
以下属于可选 Facility 和 Facility 扩展词集的单词尚未实现。
AT-XY | KEY? | PAGE | EKEY | EKEY>CHAR |
EKEY>FKEY | EKEY? | EMIT? | K-ALT-MASK | K-CTRL-MASK |
K-DELETE | K-DOWN | K-END | K-F1 | K-F10 |
K-F11 | K-F12 | K-F2 | K-F3 | K-F4 |
K-F5 | K-F6 | K-F7 | K-K8 | K-F9 |
K-HOME | K-INSERT | K-LEFT | K-NEXT | K-PRIOR |
K-RIGHT | K-SHIFT-MASK | K-UP |
外部函数接口
CL-Forth 包含一个外部函数接口(FFI),其大致基于 SwiftForth(https://www.forth.com/swiftforth/)中的 External Library Interface。详见 FFI.md。
优化
CL-Forth 包含一个 实验性 优化器,它试图通过尽可能消除对数据栈的使用来简化 CL-Forth 生成的代码。当某些有效性检查可以被证明是冗余时,还会应用额外的优化来消除这些不必要的检查。(例如,检查传递给 TYPE 的字符数是否为负数。)
优化器由一个布尔标志控制,其地址存储在 OPTIMIZER 变量中。你可以使用 ON 和 OFF 单词来更改此标志的值。
要打开优化器,执行 OPTIMIZER ON;要关闭它,执行 OPTIMIZER OFF。
默认情况下,优化器是关闭的。
在 SBCL 下,Forth 测试套件的运行速度大约提高 33%,生成的目标代码大约减少 25%。
下面是一些优化器对 CL-Forth 生成的代码所产生影响的示例。
`` forth CL-Forth Version 1.4.1 Running under Clozure Common Lisp Version 1.13 (v1.13) DarwinX8664 show-code on OK. variable x variable y variable z OK. optimizer off OK. : test1 x @ y @ 256 + + z ! ; Source code for test1: (DEFUN FORTH-WORDS::TEST1 (FS PARAMETERS) (DECLARE (IGNORABLE PARAMETERS)) (WITH-FORTH-SYSTEM (FS) (TAGBODY (STACK-PUSH DATA-STACK 4503599627370496) (STACK-PUSH DATA-STACK (CELL-SIGNED (MEMORY-CELL MEMORY (STACK-POP DATA-STACK)))) (STACK-PUSH DATA-STACK 4503599627370504) (STACK-PUSH DATA-STACK (CELL-SIGNED (MEMORY-CELL MEMORY (STACK-POP DATA-STACK)))) (STACK-PUSH DATA-STACK 256) (STACK-PUSH DATA-STACK (CELL-SIGNED (+ (CELL-SIGNED (STACK-POP DATA-STACK)) (CELL-SIGNED (STACK-POP DATA-STACK))))) (STACK-PUSH DATA-STACK (CELL-SIGNED (+ (CELL-SIGNED (STACK-POP DATA-STACK)) (CELL-SIGNED (STACK-POP DATA-STACK))))) (STACK-PUSH DATA-STACK 4503599627370512) (SETF (MEMORY-CELL MEMORY (STACK-POP DATA-STACK)) (STACK-POP DATA-STACK)) :EXIT))) OK. optimizer on OK. : test1opt x @ y @ 256 + + z ! ; Source code for test1opt: (DEFUN FORTH-WORDS::TEST1OPT (FS PARAMETERS) (DECLARE (IGNORABLE PARAMETERS)) (WITH-FORTH-SYSTEM (FS) (TAGBODY (SETF (MEMORY-CELL MEMORY 4503599627370512) (CELL-SIGNED (+ (CELL-SIGNED (+ 256 (CELL-SIGNED (MEMORY-CELL MEMORY 4503599627370504)))) (CELL-SIGNED (MEMORY-CELL MEMORY 4503599627370496))))) :EXIT))) OK. optimizer off OK. : test2 x 128 type cr ; Source code for test2: (DEFUN FORTH-WORDS::TEST2 (FS PARAMETERS) (DECLARE (IGNORABLE PARAMETERS)) (WITH-FORTH-SYSTEM (FS) (TAGBODY (STACK-PUSH DATA-STACK 4503599627370496) (STACK-PUSH DATA-STACK 128) (LET ((COUNT (STACK-POP DATA-STACK)) (ADDRESS (STACK-POP DATA-STACK))) (WHEN (MINUSP COUNT) (FORTH-EXCEPTION :INVALID-NUMERIC-ARGUMENT “Count to TYPE can’t be negative”)) (MULTIPLE-VALUE-BIND (FORTH-MEMORY OFFSET) (MEMORY-DECODE-ADDRESS MEMORY ADDRESS COUNT) (WRITE-STRING (FORTH-STRING-TO-NATIVE FORTH-MEMORY OFFSET COUNT)))) (TERPRI) :EXIT))) OK. optimizer on OK. : test2opt x 128 type cr ; Source code for test2opt: (DEFUN FORTH-WORDS::TEST2OPT (FS PARAMETERS) (DECLARE (IGNORABLE PARAMETERS)) (WITH-FORTH-SYSTEM (FS) (TAGBODY (LET ((COUNT 128) (ADDRESS 4503599627370496)) (DECLARE (IGNORABLE COUNT ADDRESS)) (MULTIPLE-VALUE-BIND (FORTH-MEMORY OFFSET) (MEMORY-DECODE-ADDRESS MEMORY 4503599627370496 128) (WRITE-STRING (FORTH-STRING-TO-NATIVE FORTH-MEMORY OFFSET 128)))) (TERPRI) :EXIT))) OK. bye In this session: 7 definitions created 3920 bytes of object code generated 24 bytes of memory
相似文章
Forth 与 Lisp 的迁移之道
本章节选自《Let Over Lambda》,探讨如何使用宏在 Lisp 中实现 Forth 编程语言,强调语法的二元性和元编程技术。旨在向 Lisp 读者教授 Forth 概念,并讨论 Forth 设计背后的哲学。
教孩子们Forth编程
一位程序员分享了他们教初中和高中生Forth编程语言的经验,解释了为什么选择它而不是Python或Scratch,以及他们如何为12节课的课程设计教学大纲。
Slisp: 简单的Lisp编译器 (Linux/amd64)
Slisp 是一个简单的编译器,它读取 Lisp 程序并生成适用于 Linux/AMD64 的独立汇编表示,支持基本原语、闭包和标准库。
Common Lisp 可移植性库状态
Common Lisp 可移植性库的全面状态概览,展示了不同 Common Lisp 实现之间的兼容性百分比。
Hyperpolyglot Lisp:Common Lisp、Racket、Clojure、Emacs Lisp
一份对照参考表,比较Common Lisp、Racket、Clojure和Emacs Lisp的语法与特性。