Rust 类型系统中的 Lisp
Lisp in the Rust Type System

原始链接: https://github.com/playX18/lisp-in-types/

本项目完全使用 Rust 的类型系统实现了一个 Lisp 解释器。通过利用 trait,它能够在编译期完成表达式求值。 **核心特性与限制:** * **编译期执行:** 表达式在编译阶段求值,结果通过类型级断言进行验证。 * **作用域与控制:** 支持全局和词法环境(通过 `let`)、递归函数,以及用于高级流程控制的 `call/ec`(逃逸续延)。 * **手动配置:** 必须使用 `defkey!` 宏显式声明符号。 * **局限性:** * **数值限制:** 整数限制在 [0, 8192] 范围内。虽然可以通过 `build.rs` 进行扩展,但这样做需要增加 Rust 的栈大小。 * **缺失功能:** 不支持 `defmacro` 或运行时 `eval` 功能。 * **实验性质:** 该系统尚未经过广泛测试。 简而言之,本项目通过在构建过程中使用 Rust 的 trait 系统来执行复杂的 Lisp 程序(如所提供的阶乘和续延示例),展示了 Rust 类型系统的图灵完备性。

抱歉。
相关文章

原文

Lisp in Rust trait system.

  • Each symbol must be manually declared via defkey!() macro
  • Numbers cannot be negative
  • Numbers are only in range of 0..8192, you can modify build.rs to generate more natural numbers but then you have to run with RUST_MIN_STACK increased.
  • No (defmacro ...)
  • No eval
  • I have not tested it extensively.
  • Recursive functions
  • Global and lexical environments (via let bindings)
  • Function calls
  • apply properly working
  • call/ec
    type DefFac = expr!(defun SymFac (SymN) (if (= SymN 0) 1 (* SymN (SymFac (- SymN 1)))));

    type Global2 = <DefFac as EvalForm<Global1, Lex0>>::GlobalOut;
    type Fac5 = EvalValue<expr!((SymFac 5)), Global2, Lex0>;
    assert_same::<Fac5, N120>();

    println!("(fac 5) => {:?}", <Fac5 as ToRtValue>::to_rt());
    // call/ec demo (escape continuation, explicit tag):
    // (call/ec cc (lambda (k) (+ 1 (k 5)))) => 5
    defkey!(SymCC, N10);
    defkey!(SymK, N11);
    type CallECExpr = expr!((call/ec SymCC (lambda (SymK) (+ 1 (SymK 5)))));
    type CallECResult = EvalValue<CallECExpr, Global1, Lex0>;
    assert_same::<CallECResult, N5>();
    println!(
        "(call/ec cc (lambda (k) (+ 1 (k 5)))) => {:?}",
        <CallECResult as ToRtValue>::to_rt()
    );
联系我们 contact @ memedata.com