LispKit 是一个框架,用于为 macOS 和 iOS 应用程序构建基于 Lisp 的扩展和脚本语言。LispKit 完全使用编程语言 Swift 编写。LispKit 基于 R7RS (small) Scheme 标准实现了一个核心语言。它是可扩展的,允许包含用 Swift 编写的新原生库、用 Scheme 编写的新库,以及对核心环境(包括编译器、虚拟机以及核心库)的自定义修改。
NumericalScheme 演示了如何创建一个派生的 LispKit 解释器,该解释器继承了 LispKit 的所有内容(无需代码重复),并定义了一个新的原生库和基于 Scheme 的库。
LispKit 框架的 iOS 版本支持除 (lispkit system call)
之外的所有库。库 (lispkit draw)
在 iOS 和 macOS 上运行一致,但不支持 iOS 上的颜色列表。总的来说,macOS 和 iOS 版本框架之间的差异很小。有趣的是,对于简单的 LispKit 基准测试,iPhone 12 Pro (2020) 似乎始终优于 MacBook Pro 16" (2019)。
LispPad 为 macOS 上的 LispKit 实现了一个简单、轻量级、集成的开发环境,带有基于 Cocoa 的 UI。LispPad 库参考 以 PDF 格式记录了核心 LispPad 和 LispKit 库。在 iOS 上,应用程序 LispPad Go 提供了一个基于 LispKit 的简单 Scheme IDE。LispPad Go 的源代码 在 GitHub 上可用。LispKit 框架本身包含一个更简单的 iOS 命令行工具(见下文)。
LispKit 为以下核心特性提供支持,其中许多特性基于 R7RS
syntax-rules
的卫生宏call/cc
、dynamic-wind
和异常(scheme base)
、(scheme case-lambda)
、(scheme char)
、(scheme complex)
、(scheme cxr)
、(scheme eval)
、(scheme file)
、(scheme inexact)
、(scheme lazy)
、(scheme load)
、(scheme process-context)
、(scheme read)
、(scheme repl)
、(scheme time)
、(scheme write)
、(scheme r5rs)
(scheme bitwise)
、(scheme box)
、(scheme charset)
、(scheme comparator)
、(scheme division)
、(scheme fixnum)
、(scheme flonum)
、(scheme generator)
、(scheme hash-table)
、(scheme ideque)
、(scheme list)
、(scheme mapping)
、(scheme red)
、(scheme rlist)
、(scheme set)
、(scheme sort)
、(scheme stream)
、(scheme text)
、(scheme vector)
(lispkit base)
、(lispkit core)
、(lispkit control)
、(lispkit system)
、(lispkit system call)
、(lispkit system keychain)
、(lispkit system pasteboard)
、(lispkit box)
、(lispkit math)
、(lispkit math matrix)
、(lispkit math util)
、(lispkit math stats)
、(lispkit list)
、(lispkit list set)
、(lispkit hashtable)
、(lispkit dynamic)
、(lispkit type)
、(lispkit vector)
、(lispkit gvector)
、(lispkit bitset)
、(lispkit record)
、(lispkit bytevector)
、(lispkit char)
、(lispkit char-set)
、(lispkit string)
、(lispkit format)
、(lispkit port)
、(lispkit date-time)
、(lispkit draw)
、(lispkit draw turtle)
、(lispkit draw barcode)
、(lispkit draw chart bar)
、(lispkit image)
、(lispkit image process)
、(lispkit vision)
、(lispkit styled-text)
、(lispkit datatype)
、(lispkit object)
、(lispkit enum)
、(lispkit enum r6rs)
、(lispkit regexp)
、(lispkit stream)
、(lispkit thread)
、(lispkit thread channel)
、(lispkit thread future)
、(lispkit thread shared-queue)
、(lispkit url)
、(lispkit graph)
、(lispkit match)
、(lispkit iterate)
、(lispkit log)
、(lispkit debug)
、(lispkit set)
、(lispkit stack)
、(lispkit queue)
、(lispkit heap)
、(lispkit disjoint-set)
、(lispkit wt-tree)
、(lispkit comparator)
、(lispkit combinator)
、(lispkit logic)
、(lispkit prolog)
、(lispkit clos)
、(lispkit test)
、(lispkit prettify)
、(lispkit text-table)
、(lispkit csv)
、(lispkit markdown)
、(lispkit sqlite)
、(lispkit archive tar)
、(lispkit archive zip)
、(lispkit crypto)
、(lispkit json)
、(lispkit json schema)
、(lispkit http)
、(lispkit http server)
、(lispkit http oauth)
、(lispkit serialize)
、(lispkit sxml)
、(lispkit sxml xml)
、(lispkit sxml html)
和 (lispkit pdf)
。LispKit 在以下 R7RS 特性方面不兼容或不完整
syntax-rules
中的字面量不是基于它们的定义而是基于它们的符号标识进行匹配#;
引入的数据注释并不总是像在其他 Scheme 方言中那样工作。以下 SRFI 库已移植到 LispKit 并包含在框架中
=>
在 case 子句中该项目定义了四个不同的目标
LispKit 由以下部分组成
详细信息可以在 LispKit Wiki 中找到。
该项目包含一个名为 LispKit Shell 的命令行工具,用于在终端中执行 LispKit 应用程序。它可用于尝试和实验 LispKit 框架。该命令行工具也可以交互方式用作读取-求值-打印循环。读取-求值-打印循环解析输入的 LispKit 表达式,将其编译为字节码,执行它,并显示结果。
首先,通过 git
克隆 LispKit 仓库。以下命令将创建一个目录 swift-lispkit
。
> git clone https://github.com/objecthub/swift-lispkit.git
Cloning into 'swift-lispkit'...
remote: Enumerating objects: 7020, done.
remote: Counting objects: 100% (365/365), done.
remote: Compressing objects: 100% (349/349), done.
remote: Total 7020 (delta 174), reused 201 (delta 10), pack-reused 6655
Receiving objects: 100% (7020/7020), 11.29 MiB | 5.20 MiB/s, done.
Resolving deltas: 100% (4853/4853), done.
接下来,切换到 Xcode 并通过 scheme LispKitRepl
构建 LispKit 命令行工具
> open LispKit.xcodeproj
可以使用以下方式构建调试二进制文件
> cd swift-lispkit
> swift build -Xswiftc "-D" -Xswiftc "SPM"
Fetching https://github.com/objecthub/swift-markdownkit.git from cache
Fetching https://github.com/objecthub/swift-numberkit.git from cache
Fetching https://github.com/objecthub/swift-sqliteexpress.git from cache
Fetching https://github.com/objecthub/swift-commandlinekit.git from cache
Fetching https://github.com/weichsel/ZIPFoundation.git from cache
Cloning https://github.com/objecthub/swift-sqliteexpress.git
Resolving https://github.com/objecthub/swift-sqliteexpress.git at 1.0.3
Cloning https://github.com/weichsel/ZIPFoundation.git
Resolving https://github.com/weichsel/ZIPFoundation.git at 0.9.12
Cloning https://github.com/objecthub/swift-markdownkit.git
Resolving https://github.com/objecthub/swift-markdownkit.git at 1.0.5
Cloning https://github.com/objecthub/swift-numberkit.git
Resolving https://github.com/objecthub/swift-numberkit.git at 2.3.9
Cloning https://github.com/objecthub/swift-commandlinekit.git
Resolving https://github.com/objecthub/swift-commandlinekit.git at 0.3.3
[180/180] Linking LispKitRepl
现在可以像这样运行调试二进制文件
.build/debug/LispKitRepl -r Sources/LispKit/Resources -d LispKit
可以像这样在 Sources/LispKit/Resources/Examples/Channels.scm
执行 Scheme 程序
.build/debug/LispKitRepl -r Sources/LispKit/Resources -d LispKit Sources/LispKit/Resources/Examples/Channels.scm
为了实验新的 resources 目录(例如,包含新的或修改的 Scheme 库),二进制文件也可以通过 .build/debug/LispKitRepl -d LispKit
运行,假设目录 ~/Documents/LispKit
包含 resources 目录 的副本。
还有一个 Makefile
,它提供了方便的构建规则。例如,可以通过调用 make run
(用于调试 REPL)或 make repl
(用于发布 REPL)来实现构建和运行 REPL。如果应该执行 Scheme 程序而不是运行 REPL,则需要设置 program
变量,例如 make run program=path/to/program.scm
。有关构建二进制文件或执行测试的详细信息,可以在 Makefile 中查找。
在 Xcode 中,将 scheme 切换到目标 LispKitRepl iOS,然后构建并运行项目。默认情况下,这将调用 iOS 模拟器并运行应用程序“LispKitRepl iOS”。该应用程序具有受聊天启发的用户界面,可以在底部的输入框中输入 Scheme 命令,并通过“向上箭头”按钮发送到解释器。然后,解释器将执行该命令并在上面的控制台区域中打印结果。工具栏中有一个带有垃圾桶的按钮,用于重置解释器。此按钮会变成用于取消正在运行的程序的按钮(例如,如果存在无限循环或其他死锁)。
还有一个更高级的 开源 iOS 应用程序,名为 LispPad Go,它为 LispKit 实现了完整的 IDE。LispPad Go 可从 iOS 应用商店 获取。
构建 LispKit 框架的组件需要以下技术。对于构建命令行工具,只需要 Swift Package Manager。对于在 Xcode 中直接编译框架和尝试命令行工具,则不需要 Swift Package Manager。