Grobots are programmed in a simple stackbased language derived from Forth. This imitates RoboWar, but the language itself is much closer to Forth. These stackbased languages are good for this sort of application because they are very easy to implement, and easier to learn and use than other similarly lowlevel languages.
The Grobots language doesn't have a name yet; I will call it Grobocode here for lack of a better name. If you are used to RoboTalk, you will find it pleasantly powerful. If you are used to Forth, you will find it annoyingly underpowered. If you don't know any stackbased languages, you will just find it weird.
Like all Forth dialects, keeps intermediate results of calculations on a stack: operands are pushed onto the stack, and operators take their arguments from the stack. Expressions are written in postfix order  the operator comes after all its arguments. This may be unfamiliar, but fortunately it doesn't take long to get used to. What in a conventional language would be:
gamma = 1 / sqrt(1  (v / c)^2)
is in Grobots:
1 v c / square  sqrt reciprocal gamma!
Here's how it works. Start with an empty stack, and execute the first instruction,
1
, which pushes a value on the stack.
stack:1
Thenv
, which pushes the value of that variable: stack:1 201285
Thenc
: stack:1 201285 299780
/
takes the top two arguments and leaves their quotient: stack:1 0.6714
square
takes one argument stack:1 0.45

stack:0.55
sqrt
stack:0.7416
reciprocal
stack:1.35
gamma!
stores the value into the variable of that name. (empty stack)
Try clicking on a robot and opening the Debugger window. Then pause the simulation and give the Step Brain command to slowly advance the brain. Watch the stack change.
There are instructions to operate on the stack, so you can do fancier things like using a result more than once, or shuffling things to be in the right order:
fibonacci: ;n  f_n
dup 1 <= if drop 1 return then
dup 1  fibonacci swap 2  fibonacci +
return
See if you can understand how that works. (You'll need to look up a lot of the operators, and this may be confusing to trace since it's recursive.) n  f_n
is a stack diagram, saying the newly defined fibonacci operator takes one argument (n) and returns one result (f_n).
The most confusing errors are stack underflow and overflow. Underflow means means you tried to remove more values from the stack than were actually there. For example, 2 +
will probably underflow, because +
needs two arguments. Overflow means you kept leaving values on the stack, so they piled higher and higher until the interpreter gave up.
Grobocode runs on a twostack machine, like traditional Forth. There is a return stack, which is only used for return addresses, and a data stack, used for arguments and return values of operators.
The only data type is a 32bit fixedpoint number, with 12 bits of fraction (and 1 of sign and 19 of integer). The range is about +/ 524,288, and the precision 1/4096 (.00024). Integer values may be used as addresses.
Grobocode syntax is a sequence of words separated by white space. There are several kinds of words; suffixes are sometimes used to indicate which kind. Each word (except compiletime words and label declarations) compiles to one instruction.
Kind of word  Suffix 

Primitive call  none 
Read variable (including constants, vector variables, and hardware variables)  none 
Write variable  !

Read label (put its address on the stack)  &

Call label  ^ (optional)

Declare label  :

Immediate number  none 
Semicolon makes a comment to the end of the line. This works everywhere, not just in code.
Variables and constants are defined somewhat clumsily by leaving the language and using reader tags. #var name initialvalue
defines a variable, #vector name initialx initialy
defines a vector variable, and #const name value
defines a constant.
Hardware access words are not included here, but are listed on the hardware page.
Word  Stack diagram  Comments 

nop    Does nothing, of course. Used for padding in jump tables. 
Stack manipulation  
drop  a   Discard the top item on the stack. 
2drop  a b   Discard the top two items. 
nip  a b  b  Discard the second item on the stack. 
rdrop  R: a   Discard the top item on the return stack. 
dropn  x_{n} ... x_{2} x_{1} n   remove n items from the stack. 
swap  a b  b a  Exchange the top two items. 
2swap  a b c d  c d a b  Exchange the top two pairs of items. 
rot  a b c  b c a  
rrot  a b c  c a b  
dup  a  a a  These all duplicate items that are on the stack. 
2dup  a b  a b a b  
tuck  a b  b a b  
over  a b  a b a  
2over  a b c d  a b c d a b  
stack   height  Return the number of items that were on the stack. 
stacklimit   limit  Return the maximum number of items that can be on the stack. 
pick  x_{n} ... x_{2} x_{1} n  x_{n} ... x_{2} x_{1} x_{n}  copy the nth item to the top of the stack. 
>r  a  R:  a  Move an item to or from the return stack. The item must be a valid address, so these instructions are not very useful. 
r>   a R: a   
Branches  
jump  address   Continue execution from address. 
call  address  R:  pc  Push the address of the next instruction on the return stack, and continue execution from address. 
return  R: address   Remove address from the return stack and continue from it. 
ifg  flag address   Jump to address if flag is nonzero. 
nifg  flag address   Jump to address if flag is zero. 
ifeg  flag addr1 addr2   Jump to addr1 if flag is nonzero or to addr2 if it is zero. 
ifc  flag address  [R:  pc]  Call address if flag is nonzero. 
ifec  flag addr1 addr2  R:  pc  
nifc  flag address  [R:  pc]  Call address if flag is zero. 
ifr  flag  [R: address ]  Returns (to the top address on the return stack) if flag is nonzero. 
nifr  flag  [R: address ]  Returns if flag is zero. 
Arithmetic etc.  
+  a b  a+b  
  a b  ab  
negate  a  a  
*  a b  a*b  
/  a b  a/b  
reciprocal  a  1/a  
mod  a b  r  
rem  a b  r  
square  a  a^2  square: dup * return

sqrt  a  s  square root 
exponent  b x  b^x  
isinteger  a  flag  
floor  a  n  Rounds down. 
ceiling  a  n  Rounds up. 
round  a  n  Rounds to nearest. 
min  a b  ab  Returns the lesser (closer to negative infinity) of the arguments. 
max  a b  ab  Returns the greater (closer to positive infinity) of the arguments. 
abs  a  b  b = a 
signum  a  b  b = 1 if a positive, 1 if negative, 0 otherwise. 
reorient  a  b  Ensures an angle is in (pi, pi]. 
sin  a  sina  
cos  a  cosa  
tan  a  tana  
arcsin  sina  a  
arccos  cosa  a  
arctan  tana  a  
arctan2  x y  a  
random  min max  value  Returns a random real value evenly distributed between the two bounds (inclusive). 
randomangle   angle  Returns a random value evenly distributed in (pi, pi]. 
randomint  min max  value  Returns a random integer evenly distributed between the two bounds (inclusive). The bounds need not be integers, but the result will be; 1.5 2.5 randomint returns 2.

randombool  probability  boolean  Returns a boolean, which will be 1 with the given probability. 
pi   pi  
2pi   2pi  
pi/2   pi/2  
e   e  2.7182818284 
epsilon   epsilon  Returns the smallest difference representable. 
infinity   inf  Returns the largest positive value representable. (Negative infinity is actually infinity negate epsilon  .)

Vector operations  
recttopolar  x y  magnitude angle  Convert a vector from rectangular to polar form. 
polartorect  magnitude angle  x y  Convert a vector from polar to rectangular form. 
v+  x1 y1 x2 y2  x1+x2 y1+y2  Adds two vectors in rectangular form. 
v  x1 y1 x2 y2  x1x2 y1y2  Subtracts two vectors in rectangular form. 
vnegate  x y  x y  Negates a vector. 
vs*  x y s  x*s y*s  Vectorscalar multiply. 
vs/  x y s  x/s y/s  Vectorscalar divide. 
norm  x y  p  Returns x square y square + sqrt , the Pythagorean sum.

angle  x y  angle  Returns arctan2(y, x). 
dot  x1 y1 x2 y2  v  Dot product. v = x1 x2 * y1 y2 * +

project  x1 y1 x2 y2  x3 y3  Returns the projection of the first vector onto the second. 
cross  x1 y1 x2 y2  v  Twodimensional cross product, sort of. v = x1 y2 * y1 x2 *  . This is the zcomponent of the equivalent threedimensional cross product.

unitize  x y  x' y'  Returns a vector of magnitude 1 in the same direction. 
dist  x1 y1 x2 y2  d  Distance (norm of difference) operator. 
inrange  x1 y1 x2 y2 r flag  whether the two vectors differ by less than r. 
Comparisons and Boolean operations  
=  a b  flag  
<>  a b  flag  
<  a b  flag  
>  a b  flag  
<=  a b  flag  
>=  a b  flag  
not  f1  f2  f2 is zero if f1 was nonzero, and one otherwise. 
and  f1 f2  f3  f3 is one if both f1 and f2 were nonzero, and zero otherwise. 
or  f1 f2  f3  f3 is zero if both f1 and f2 were zero, and one otherwise. 
xor  f1 f2  f3  f3 is one if exactly one of f1 or f2 was nonzero, and zero otherwise. 
nand  f1 f2  f3  f3 is zero if both f1 and f2 were nonzero, and one otherwise. 
nor  f1 f2  f3  f3 is one if both f1 and f2 were zero, and zero otherwise. 
ifev  flag a b  ab  Value conditional: returns a if flag was nonzero, and b otherwise. 
Miscellaneous  
print  value   Remove and display one item, for debugging purposes. 
vprint  x y   Remove and display a vector. 
beep    Beep, for debugging purposes. 
pause    Pauses the simulation. For debugging. 
stop    Permanently stops execution of this brain. 
sync    Waits until the next frame to continue execution. Useful for waiting for hardware to work, or for synchronizing to do something all in one frame. 
store  x addr   Writes a value to local memory. 
load  addr  x  Reads local memory. 
vstore  x y addr   A convenience, to store two values. 
vload  addr  x y 
Some words execute at compile time, for convenience in writing common control structures. There are conditionals and loops so far.
Structure  Meaning  Expansion 

test if body then
 execute body if test is true  test label& nifg body label:

test if body1 else body2 then
 execute body1 if test is true, body2 otherwise  test skip& nifg body1 done& jump

nif ...
 If, with sense reversed  test label& ifg ...

test1 if test2 andif body1 else body2 then
 if test1 is true, then if test2 is true, then execute body1...  test skip& nifg test2 skip& nifg body1 done& jump

test1 if body1 else test2 if body2 celse test3 if body3 celse body4 then
 Makes ifelsifelsifelse constructs shorter (no need to write then then then ).
 test1 skip1& nifg body1 done& jump

do code forever
 infinite loop  repeat: code repeat& jump

do test while code loop
 Execute test and code until test is true (until ) or false (while ). Note that the endtest is in the middle of the loop.
 repeat: test done& nifg

do test until code loop
 repeat: test done& ifg
 
do code test whileloop
 optimized versions of while loop and until loop , saving two instructions
 repeat: code test repeat& ifg

do code test untilloop
 repeat: code test repeat& nifg

Grobots by Devon Schudy (dschudy@yahoo.com) and Warren Schudy (wschudy@wpi.edu)