#esolang #编译时 #程序 # #插件 #转换 #fractran

nightly fractran_macros

一个编译器插件,可以将Fractran代码在编译时转换为Rust,让您的Fractran程序通过LLVM进行优化,以生成超级快速的本地代码

5 个版本

使用旧的Rust 2015

0.1.5 2015年3月21日
0.1.4 2015年1月26日
0.1.3 2015年1月4日
0.1.1 2014年11月20日
0.1.0 2014年11月14日

#865编程语言

每月 29 次下载

MIT/Apache

15KB
260

fractran_macros

Build Status

一个Rust宏,用于在编译时将嵌入Rust程序中的Fractran程序编译成高效、无分配、仅libcore的代码。

Fractran是一种非常简单的语言;一个程序是一个整数 n 和一系列正分数的列表,通过找到第一个满足 nf 为整数的分数 f,将 n 替换为 nf 并重复(当没有这样的分数时,执行停止)。结果是,这可以实现图灵完备性,人们甚至用Fractran编写了Fractran解释器!(见 examples/fractran.rs。)

1没错;您现在可以在内核中使用Fractran了。

使用方法

fractran 宏接受一系列以逗号分隔的算术表达式,表示分数序列。支持的操作

  • */ 和括号用于分组;无算术溢出或精度损失的风险,
  • +;可能会溢出,
  • 通过 ^ 使用整数幂;无溢出,但优先级不正确,所以 a^b * c 应为 a^(b * c),而不是应该的 (a^b) * c。请使用括号以确保正确性。

此宏返回一个构造函数 fn(&[u32]) -> T,其中 &[u32] 是初始数字(格式如下文所述),而 T 是实现 Iterator<()>fractran_support::Fractran 的类型。调用 next 将执行机器(即找到上述描述的适当分数),当机器停止时返回 None

fractran_support::Fractran 特性提供了 state 方法(用于查看当前数字,以指数形式表示)和用于执行状态机直到其停止的 run 方法。

示例

#![feature(phase)]

#[phase(plugin)] extern crate fractran_macros;

fn main() {
    // takes 2^a 3^b to 3^(a+b)
    let add = fractran!(3/2);
    println!("{}", add(&[12, 34]).run()); // [0, 46]

    // takes 2^a 3^b to 5^(ab)
    let mult = fractran!(455 / 33, 11/13, 1/11, 3/7, 11/2, 1/3);
    println!("{}", mult(&[12, 34]).run()); // [0, 0, 408, 0, ...]
}

请确保 Cargo.toml 中有适当的依赖项

[dependencies.fractran_macros]
git = "https://github.com/huonw/fractran_macros"

表示法

数字根据其质因数的(32位)指数表示。数组 [u32] 的第 i 个条目是第 i 个质数的指数(零索引),例如 2 == [1]3 == [0, 1]9438 == 2 * 3 * 11^2 * 13 == [1, 1, 0, 0, 2, 1]。这种表示法允许实现处理非常大的数字,任何质数的最大指数都小于 232 的数字,因此最小的不可表示的数字是 2232 = 24294967296

这也使得内部实现可以非常高效,只需(静态确定的)数组索引和整数比较 & 加法;不存在越界索引的可能性(因此没有从 unwinding 中获得性能惩罚),也没有除法或余数操作。例如,程序 example/prime.rs 使用康威的质数枚举 FRACTRAN 程序生成质数,它只需 6 秒即可执行 10 亿步(达到 887 的壮丽高度)。

可以使用您最喜欢的质数包(例如,使用来自 slow_primes 的质数迭代器)将此表示法转换为实际数字和从实际数字转换到此表示法。

为什么?

为什么不呢?Esolang-macros 很有趣,算术基本定理也很有趣。

依赖关系

~570KB
~11K SLoC