[][src]Macro fortraith::forth

macro_rules! forth {
    ({ $EX:ty }) => { ... };
    ({ $EX:ty } return) => { ... };
    ({ $EX:ty } return type $name:ident as $tok:tt $($token:tt)*) => { ... };
    ({ $EX:ty } return type $name:ident $($token:tt)*) => { ... };
    ({ $EX:ty } . $($token:tt)*) => { ... };
    ({ $EX:ty } : $name:ident $tok:tt $($token:tt)*) => { ... };
    ({ $EX:ty } $tok:tt $($token:tt)*) => { ... };
    (@compile { $EX:ty } $name:ident {$(($($cmdl:tt)*))*} ($($cmdr:tt)*) ; $($tbd:tt)*) => { ... };
    (@compile { $EX:ty } $name:ident {$(($($cmdl:tt)*))*} ($($cmdr:tt)*) $new:tt $($tbd:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty}) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} ($($comment:tt)*) $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} + $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} - $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} * $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} % $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} = $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} < $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} if $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} else $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 0 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 1 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 2 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 3 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 4 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 5 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 6 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 7 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 8 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 9 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} 10 $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} true $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} false $($token:tt)*) => { ... };
    (@subs ($($subst:tt)*) {$EX:ty} $tok:tt $($token:tt)*) => { ... };
    ($($token:tt)*) => { ... };
}

Compile forth to trait expressions

Every trait from this crate serves as a word than can be used in the forth program. Macro substitutes common names (+ - * % < = if else true false, numbers from 1 to 10) for corresponding traits to make it easier. Everything inside parentheses ( ) is treated as comments and ignored by the macro.

Additionally the macro provides a few special expressions (note that these cannot be used inside a new word definition):

  • . which is equivalent to drop but it inserts a println statement with the dropped value for convenience. You could call this cheating, but there is no way to print types at compile time known to me.
forth!(
    10 .
);
// prints "10"
  • : $name $($cmds)* ; which defines a new word (trait) named $name that executes commands given after the name
forth!(
    : booltonum if 0 else 1 then ;
    true booltonum
    false booltonum
    +
    return type Out as top
);
assert_eq!(Out::eval(), 1);
  • return which can be used in 3 different ways:
    • return at the end of the program returns the current stack (This can only be used if ., :;, or another return are not used in the program)
    • return type $name anywhere inside the program saves the stack to a type alias $name
    • return type $name as $cmd anywhere inside the program saves the stack after executing $cmd on the stack to type alias $name, but without modifying the actual stack in the program. See top for examples