Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/huonw/fractran_macros
A FRACTRAN procedural macro for Rust
https://github.com/huonw/fractran_macros
Last synced: about 1 month ago
JSON representation
A FRACTRAN procedural macro for Rust
- Host: GitHub
- URL: https://github.com/huonw/fractran_macros
- Owner: huonw
- License: apache-2.0
- Created: 2014-08-16T05:35:56.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2015-03-21T12:40:23.000Z (over 9 years ago)
- Last Synced: 2024-09-14T07:27:41.029Z (2 months ago)
- Language: Rust
- Size: 189 KB
- Stars: 6
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# `fractran_macros`
[![Build Status](https://travis-ci.org/huonw/fractran_macros.png)](https://travis-ci.org/huonw/fractran_macros)
A Rust macro for compiling
[FRACTRAN](https://en.wikipedia.org/wiki/FRACTRAN) programs embedded
in a Rust program into efficient, allocation-less,
libcore-only1 code at compile time.FRACTRAN is a very simple language; a program is an integer `n` along
with a list of positive fractions, executed by finding the first
fraction `f` for which `nf` is an integer, replace `n` by `nf` and
repeating (execution halts when there is no such fraction). It turns
out that this is Turing complete, and people have even written
FRACTRAN interpreters in FRACTRAN! (See `examples/fractran.rs`.)1That's right; you can now use FRACTRAN inside a kernel.
## Usage
The `fractran` macro takes a series of comma-separated arithmetic
expressions, representing the sequence of fractions. Supported
operations:- `*`, `/` and parentheses for grouping; no risk of arithmetic
overflow or loss of precision,
- `+`; can overflow,
- integer powers via `^`; no overflow, but precedence is incorrect, so
`a^b * c` is `a^(b * c)`, rather than `(a^b) * c` as it should
be. Use parentheses to ensure correctness.The macro returns a constructor function `fn(&[u32]) -> T`, where
`&[u32]` is the initial number (in the format
[described below](#representation)), and `T` is a type implementing
`Iterator<()>` and `fractran_support::Fractran`. Calling `next` will
step the machine (i.e. finding the appropriate fraction as described
above), returning `None` when the machine has halted.The `fractran_support::Fractran` trait provides the `state` method
(for viewing the current number, in exponent form) and the `run`
method for executing the state machine until it halts.### Example
```rust
#![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, ...]
}
```Remember to ensure the `Cargo.toml` has the appropriate dependencies:
```toml
[dependencies.fractran_macros]
git = "https://github.com/huonw/fractran_macros"
```## Representation
Numbers are represented in terms of the (32-bit) exponents of their
prime factors. The `i`th entry of `[u32]` values is the exponent of
the `i`th prime (zero-indexed), for example `2 == [1]`, `3 == [0, 1]`,
`9438 == 2 * 3 * 11^2 * 13 == [1, 1, 0, 0, 2, 1]`. This representation
allows the implementation to handle very large numbers, anything where
the largest exponent of any prime is less than 232, so the
*smallest* non-representable number is 2232 =
24294967296.This also allows the internal implementation to be highly efficient
with just (statically determined) array indexing and integer
comparisons & additions; there is no possibility of out-of-bounds
indexing (and thus no performance penalty from unwinding), nor is
there any division or remainder operations. As an example, the
`example/prime.rs` program uses Conway's prime enumeration FRACTRAN
program to generate primes, it takes only 6 seconds to do 1 billion
steps (reaching the lofty heights of 887).Converting this representation to and from an actual number can be
achieved with your favourite prime-number crate (e.g. zipping with the
primes iterator from
[`slow_primes`](https://github.com/huonw/slow_primes)).## Why?
Why not? [Esolang-macros](https://github.com/huonw/brainfuck_macros)
are fun, and so is the fundamental theorem of arithmetic.