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.
: $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