This is a Rust implementation of my toy stack-based, concatenative programming language Rack. It is heavily inspired by the language Porth created by Tsoding/Rexim. The documented development of the original Porth can be found here.
USAGE:
rackc [OPTIONS] <FILE>
ARGS:
<FILE> Input file
OPTIONS:
-h, --help Print help information
-o, --out <FILE> Output file
-q, --quiet Don't print log information
-r, --run Run the program after successful compilation
-t, --target <TARGET> Target architecture [default: x86_64-linux]
x86_64-linux
*x86_64-fasm
mos_6502-nesulator
* Requires fasm on path (on most package managers)
The file provided will be compiled into x86-64 fasm which will be written to ./out.asm
and can then be compiled to an executable binary with fasm
$ cargo run -- examples/hello.rk -r
hello, world!
Rack code goes inside a function, declared as follows:
fn foo in
// do some stuff
end
You can call it by using the function's name:
fn main in
foo
end
Early return is achieved with ret
keyword.
Push a u64 onto the stack.
42 print
0x2a print
0o52 print
0b101010 print
'*' print
42
42
42
42
42
String literals are pushed to the stack as a count followed by a pointer.
"Hello, world!" print print
4198733
13
Pops from the stack and sends to stdout as u64.
42 print
42
Pops a pointer and count from the stack and prints the string at the pointer to stdout.
"Hello, world!\n" puts
Hello, world!
Bind arbitrary number of stack elements to names
1 2 3
let a b c in
a print
b print
c print
end
1
2
3
Like let
, but the elements remain on the stack.
1 2 3
peek a b c in end
print print print
3
2
1
Drops one element from the stack
42 84 drop print
42
Swaps the two elements at the top of the stack
42 84 swap print print
42
84
Duplicates the element at the top of the stack
42 dup print print
42
42
Pops two elements from the stack, pushes the result of adding them
20 21 + print
42
Pops a
then b
from the stack, pushes the result of b - a
60 18 - print
42
Pops a
then b
from the stack, pushes the result of b / a
10 2 / print
5
Pops a
then b
from the stack, pushes the result of b % a
10 4 % print
2
Pops a
then b
, pushes the result of b / a
then b % a
10 3 divmod
let quotient remainder in
quotient print
remainder print
end
3
1
Pops from stack. If true
, execute <branch>
, else go to end
.
true if
42 print
end
false if
84 print
end
42
While <condition>
is true
, execute branch
.
0 while 1 + dup 6 < do
dup print
end
drop
1
2
3
4
5
Pushes 1
onto the stack.
Pushes 0
onto the stack.
Pops a
and b
from stack, pushes boolean result of a == b
3 3 = print
1
Pops a
and b
from stack, pushes boolean result of a != b
3 3 != print
0
Inverts boolean value on the stack
Pops a
and b
, pushes 1
if both a
and b
are 1
, 0
otherwise.n
Pops a
and b
, pushes 1
if one of a
and b
is 1
, 0
otherwise.
Pops a
then b
, pushes 1
if b < a
, 0
otherwise.
1 2 < if
42 print
end
42
Pops a
then b
, pushes 1
if b > a
, 0
otherwise. See <
.
Reads a single byte from memory at the address stored on the stack.
"hello" @ print
104
Comments are denoted by //
. Must be separated by space. e.g 1 // comment