8 个版本 (4 个重大更改)

0.5.2 2023 年 8 月 26 日
0.5.1 2023 年 8 月 23 日
0.4.0 2023 年 8 月 21 日
0.3.0 2023 年 8 月 18 日
0.1.0 2023 年 6 月 8 日

#1788 in 过程宏

Download history 138/week @ 2024-03-21 6/week @ 2024-03-28 2/week @ 2024-04-04

每月下载量 76 次
用于 spaik

BSD-2-Clause 协议

12KB
240

SPAIK LISP 编程语言

SPAIK 是 Rust 的动态扩展语言。它实现了宏、垃圾回收、迭代器、延续、async/await,并通过一个(希望)易于使用的高级 Rust API 进行封装。

此 README 包含许多示例代码片段,展示了如何使用 SPAIK,而完整的示例可以在 示例 目录中找到,更详细的 API 文档可以在 docs.rs 中找到。

您还可以在浏览器中直接尝试 SPAIK!

基本用法

对于基本用法,您只需要 evalexec 方法(exec 只不过是 eval,但它丢弃了结果以帮助类型推断)。

let mut vm = Spaik::new();
vm.exec(r#"(println "Hello, World!")"#)?;

vm.set("f", |x: i32| x + 2); // Functions are first-class at the API boundary!
assert_eq!(vm.eval("(f 2)"), Ok(4));

// Optional linear-algebra types from glam
vm.exec("(defun funky (x y) (* x (vec3 1 y 3)))")?;
assert_eq!(vm.call("funky", (2, 4)), Ok(glam::vec3(2.0, 8.0, 6.0))); // Call a spaik function

// Define interfaces more formally
defuns!(trait MyInterface {
    fn funky(x: f32, y: f32) -> glam::Vec3;
});
// This panics if the function `funky` does not match the spec
assert_eq!(vm.funky(2.0, 4.0), glam::vec3(2.0, 8.0, 6.0));

加载代码

您可能不想将所有 SPAIK 代码都存储为 Rust 中的嵌入式字符串,因此当然可以从文件系统中加载 SPAIK 脚本。

vm.add_load_path("my-spaik-programs");
vm.load::<Ignore>("stuff")?;
let result: Lambda = vm.load("other-stuff")?;
result.call(&mut vm, (1, 2, 3));

add_load_path 方法将给定的字符串添加到全局 sys/load-path 变量中,这只是一个 SPAIK 向量。您也可以从 SPAIK 中修改它

(eval-when-compile (push sys/load-path "my-dependencies"))
(load dependency)

但请注意,在添加新路径时,我们不得不使用 (eval-when-compile ...),因为 (load ...) 也会在编译期间运行。

将函数导出到 SPAIK

您可以直接使用代码 vm.set("name", func),或者使用便利函数 vm.defun(add_to),它等同于 vm.set("add-to", add_to)

use spaik::prelude::*;

fn add_to(x: i32) -> i32 {
    x + 1
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut vm = Spaik::new();
    println!("Calling from Rust: {}", add_to(2));
    vm.set("other-name-for-add-to", add_to);
    vm.defun(add_to);
    vm.exec(r#"(let ((r (add-to 2))) (println "Calling Rust from SPAIK: {r}"))"#)?;
    Ok(())
}

html

由于在 LISPs 中创建新的语法结构非常容易,您可以使用 SPAIK 作为基本的 html 模板引擎。

(load html)
(html (p :class 'interjection "Interjection!"))
<p class="interjection">Interjection!</p>

内部架构

SPAIK 代码是字节码编译,并在称为 Rodent VM (R8VM) 的自定义虚拟机上运行,该虚拟机使用移动跟踪垃圾收集器。有关其内部结构的更详细信息,请参阅 HACKING.md

依赖项

约 4MB
约 83K SLoC