Need help with fortraith?

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

172 Stars 5 Forks MIT License 23 Commits 0 Opened issues

Forth for Rust's trait system

Readme

fortraith

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

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.

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

predwhich 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.

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

trait-evalis re-exported to work on the stack (except

ifwhich is done differently), and a few additional stack operations are provided. See docs for the details.