mirror of https://github.com/dirtbags/tanks.git
212 lines
4.6 KiB
Plaintext
212 lines
4.6 KiB
Plaintext
The Forf Language


=================




Welcome to Forf! *PUNCH*




Forf is a simple, postfix, stackbased programming language. It was


designed to be used as an extension language for games. Forf programs


run in fixed size memory and can be timeconstrained.




Forf was heavily influenced by the PostScript programming language.






About Stacks


============




Central to the operation of Forf is the notion of a stack. A stack is a


lastinfirstout (LIFO) list, like a stack of dishes. Items can be


"pushed" onto the top of the stack, or "popped" off the top of the stack.


Items may only be pushed or popped, meaning the top stack element is the


only element that can be accessed. To get to the third item down in a


stack, it is necessary to first pop two items off.






Data Types


==========




There are three data types in Forf: Integers, Substacks, and Procedures.






Integers







Integers are stored as the "long" type and have whatever boundaries the


host CPU and C compiler enforce. They may be entered in decimal (12),


octal (014), or hex (0xC), and may be positive or negative.




The following are valid integers:




* 58


* 58


* 0x3A (hex)


* 072 (octal)






Procedures







Data is read one by one from your program and either pushed onto the


data stack (integers and substacks) or evaluated (procedures). When a


procedures is evaluated, it pops zero or more elements off the data


stack, does something with them, and then pushes zero or more elements


back onto the stack.




The "+" procedure, for instance, pops two values, adds them, and pushes


the result. The following data stack:




[bottom] 58 88 5 [top]




When given to the "+" procedure, would yield:




[bottom] 58 93 [top]






Substacks







Substacks are groups of data on the data stack. They are used only by


the "if" and "ifelse" procedures, and are denoted by "{" (start


substack) and "}" (end substack). Substacks may be nested.




The following will result in 58 on the top of the stack:




5 8 < { 50 8 + } { 50 8  } ifelse






Comments







Anything inside parenthesis is ignored by the forf interpreter.








Builtin Procedures


===================




The following procedures are built in to Forf. Since the language was


designed to be extended, your game provides additional procedures.






Unary Operations







These procedures pop one value and push one.




* `x ~` (bitwise invert)


* `x !` (logical not)


* `x abs` (absolute value)






Binary Operations







The following procedures pop two values and push one. They work as in


an RPN calculator, meaning that `8 4 /` yields `2`.




* `y x +` (y + x)


* `y x ` (y  x)


* `y x *` (y * x)


* `y x /` (y / x)


* `y x %` (y modulo x)


* `y x &` (y and x)


* `y x ` (y or x)


* `y x ^` (x xor x)


* `y x <<` (y shifted left by x)


* `y x >>` (y shifted right by x)






Comparison







These procedures pop two numbers and compare them, pushing `1` if the


comparison is true, `0` if false. For instance, `5 3 >` yields `1`.




* `y x >` (y greater than x)


* `y x >=` (y greater than or equal to x)


* `y x <` (y less than x)


* `y x <=` (y less than or equal to x)


* `y x =` (y equal to x)


* `y x <>` (y not equal to x)






Conditional Procedures







* `x { i ... } if` (if x, evaluate i)


* `x { i ... } { e ... } ifelse` (if x, evaluate i, otherwise evaluate e)






Stack Manipulation







* `x pop` (discard x)


* `x dup` (duplicate x)


* `y x exch` (exchange x and y on the stack)






Memory







Your game may provide you with one or more memory slots. These are like


variables in other languages, and may persist across invocations of your


program.




* `y x mset` (store y in slot x)


* `x mget` (retrieve value in slot x)






Examples


========




Compute 58²:




58 58 *




Compute 58³:




58 58 58 * *




Another way to compute 58³:




58 dup dup * *






The ifelse example, which does a comparison and puts 58 on the stack:




5 8 < { 50 8 + } { 50 8  } ifelse




Another way to do that:




50 5 8 < { 8 + } { 8  } ifelse




Yet another way:




50 8 5 8 < { + } {  } ifelse




Is memory slot 3 greater than 100?




3 mget 100 >




Given x, if x² is greater than 100 yield x², otherwise 0:




dup dup * 100 > { dup * } { pop 0 } ifelse




Another way to do the same thing:




dup * dup 100 < { pop 0 } if




Given coordinates (x, y) on the stack, is the distance to (x, y) less


than 88? This compares x²+y² against 88².




dup * exch dup * + 88 88 * <




Perform different actions given some number between 0 and 3:




dup 0 = { action0 } if


dup 1 = { action1 } if


dup 2 = { action2 } if


dup 3 = { action3 } if


pop




