Need help with fortraith?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

Ashymad
172 Stars 5 Forks MIT License 23 Commits 0 Opened issues

Description

Forth for Rust's trait system

Services available

!
?

Need anything else?

Contributors list

# 465,410
C
Shell
Arch Li...
reposit...
22 commits

fortraith

Docs.rs Crates.io Build Status

Compile-time compiler that compiles Forth to compile-time trait expressions.

What?

Rust's trait system is Turing complete. This crate uses the principles from trait-eval to implement necessary traits for forth evaluation and provides a

forth!
macro that transpiles forth's syntax to trait expressions.

Show me!

Here's a simple factorial implementation, the only non-standard word here is

pred
which is a decrement operator, equivalent to
1 -
:
rust
forth!(
    : factorial (n -- n) 1 swap fact0 ;
    : fact0 (n n -- n) dup 1 = if drop else dup rot * swap pred fact0 then ;
    5 factorial .
);
This prints
120
. As you can see not only can you define functions easily, but even conditional recursion is possible! Now check out how it looks compiled to trait expressions (courtesy of
cargo expand
):
rust
pub trait factorial {
   type Result;
}
impl factorial for Node
where
    Self: one,
    ::Result: swap,
    <::Result as swap>::Result: fact0,
{
    type Result = <<::Result as swap>::Result as fact0>::Result;
}
pub trait fact0 {
    type Result;
}
impl  fact0 for Node 
where
    Self: dup,
    ::Result: one,
    <::Result as one>::Result: eq,
    <<::Result as one>::Result as eq>::Result: iff,
    <<<::Result as one>::Result as eq>::Result as iff>::Result: drop,
    <<<<::Result as one>::Result as eq>::Result as iff>::Result as drop>::Result: elsef,
    <<<<<::Result as one>::Result as eq>::Result as iff>::Result as drop>::Result as elsef>::Result: dup,
    <<<<<<::Result as one>::Result as eq>::Result as iff>::Result as drop>::Result as elsef>::Result as dup>::Result: rot,
    <<<<<<<::Result as one>::Result as eq>::Result as iff>::Result as drop>::Result as elsef>::Result as dup>::Result as rot>::Result: mult,
    <<<<<<<<::Result as one>::Result as eq>::Result as iff>::Result as drop>::Result as elsef>::Result as dup>::Result as rot>::Result as mult>::Result: swap,
    <<<<<<<<<::Result as one>::Result as eq>::Result as iff>::Result as drop>::Result as elsef>::Result as dup>::Result as rot>::Result as mult>::Result as swap>::Result: pred,
    <<<<<<<<<<::Result as one>::Result as eq>::Result as iff>::Result as drop>::Result as elsef>::Result as dup>::Result as rot>::Result as mult>::Result as swap>::Result as pred>::Result: fact0,
    <<<<<<<<<<<::Result as one>::Result as eq>::Result as iff>::Result as drop>::Result as elsef>::Result as dup>::Result as rot>::Result as mult>::Result as swap>::Result as pred>::Result as fact0>::Result: then
{
    type Result = <<<<<<<<<<<<::Result as one>::Result as eq>::Result as iff>::Result as drop>::Result as elsef>::Result as dup>::Result as rot>::Result as mult>::Result as swap>::Result as pred>::Result as fact0>::Result as then>::Result;
}
println!("{}", <<::Result as factorial>::Result as top>::Result::eval());
Yeah, writing that manually would be no fun.

What can I do with it?

Quite a bit is actually supported as you can see above. Every operation from

trait-eval
is re-exported to work on the stack (except
if
which is done differently), and a few additional stack operations are provided. See docs for the details.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.