**Patternizer v0.22** - [Math](#math) - [Stack Operations](#stack-operations) - [Boolean Operators](#boolean-operators) - [Comparison](#comparison) - [Logical](#logical) - [Control flow](#control-flow) - [Global Variables](#global-variables) - [Functions](#functions) - [Positioning](#positioning) - [Thickness](#thickness) - [Timeline](#timeline) - [Lua Interop](#lua-interop) - [Preprocessor](#preprocessor) # Math For non-communative operations, the operation is performed on the second popped number using the first (`a b -` is `a - b`). * `0 1 2 3` Any number by itself pushes that number to the stack. Floating point numbers are also accepted. * `+` Pops two numbers, adds them, and pushes the result. * `-` Pops two numbers, subtracts them, and pushes the result. * `*` Pops two numbers, multiplies them, and pushes the result. * `/` Pops two numbers, divides them, and pushes the result. * `%` Pops two numbers, takes the modulus of them, and pushes the result. * `floor` Pops a number and pushes the floor of that number. * `ceil` Pops a number and pushes the ceiling of that number. * `abs` Pops a number and pushes the absolute value of that number. * `sgn` Pops a number and pushes -1 if the number is negative, 1 if the number is positive and 0 if the number equals 0. * `rnd` Pops two numbers and picks a random integer within their range. Both inputs must be integers. The number popped first is the upper bound and the second is the lower bound. # Stack Operations Before and after snapshots of the stack are shown as `( ) --> ( )`. * `drop` Discards the top value of the stack. `( a b ) --> ( a )` **Duplicators** * `dup` Duplicates the top value of the stack. `( a ) --> ( a a )` * `over` Duplicates the value under the value on top of the stack. `( a b ) --> ( a b a )` * `raise` Duplicates a value from a certain depth in the stack. `( a b c 0 ) --> ( a b c c )` `( a b c 1 ) --> ( a b c b )` `( a b c 2 ) --> ( a b c a )` * `clone` Duplicates the entire stack. `( a b c ) --> ( a b c a b c )` **Arrangement** * `swap` Swaps the top two values of the stack. `( a b ) --> ( b a )` * `exch` Swaps the value on top of the stack with another from a certain depth in the stack. `( a b c 0 ) --> ( a b c )` `( a b c 1 ) --> ( a c b )` `( a b c 2 ) --> ( c b a )` * `roll` > **Note:** This function is rather cumbersome and its use is discouraged. Consider using the `raise` and `exch` function instead. Pops two numbers: The first value popped is the number of times to roll the stack and the second is the depth. A negative depth value will start indexing from the bottom of the stack. A negative roll value will roll the stack in the opposite direction. If the depth parameter is 0 or 1, or if the times parameter is 0, nothing happens. `( a b c d 4 1 ) --> ( b c d a )` `( a b c d 3 1 ) --> ( a c d b )` `( a b c d 3 -1 ) --> ( a d b c )` `( a b c d -1 1 ) --> ( b c d a )` # Boolean Operators Boolean operators pop two numbers (except for `not` which pops one) and push 1 if true, 0 if false. Any number that is not 0 is considered as true. ## Comparison * `==` Equality. * `!=` Inequality. * `>` Greater than. * `>=` Greater than or equal to. * `<` Less than. * `<=` Less than or equal to. ## Logical * `or` Logical or. * `and` Logical and. * `not` Logical not. # Control flow * ` while end` Pops a value. If it's false, skip to the instruction after `end`, otherwise enter the loop and repeat. * ` for end` Peeks the top value. If it is false, drop it, and jump to the instruction after `end`. If it's true, decrement the value by 1 enter the loop. * ` if end` Pops a value. If it's true, `` is run. * ` if else end` Pops a value. If it's true, `` is run, otherwise `` is run. * `endif` Used to close as many if statements as in a row as possible. Can be used to shorten long if else chains. Stops closing statements once `while`, `for`, or nothing else is found. Must close at least one if or else statement. > **Warning:** Using `endif` means all or nothing. If an if-else chain is within another if statement, `endif` will close that outer if statement too! * `return` Stops the program. The stack is the output. # Global Variables * `$sides` Pushes the side count. Constant after initialization. Initialized to `Patternizer.sides:get()`. The default is the current side count. * `$hsides` Pushes `$sides` divided by 2 (unrounded). * `$th` Pushes `THICKNESS` to the stack. * `$idealth` Pushes the ideal thickness to the stack. Constant after initialization. Depends on the speed and difficulty multipliers. * `$idealdl` Pushes the ideal delay to the stack. Constant after initialization. Depends on the speed and difficulty multipliers. * `$sperpr` Pushes the seconds per player rotation (constant). * `$abs` Pushes the absolute pivot to the stack. Initialized to a random side [0, `$sides`). * `$rel` Pushes the relative pivot to the stack. Initialized to 0. Ranges from [0, `$sides`). * `$rof` Pushes the relative offset to the stack. Initialized to 0. Ranges from [-`$hsides`, `$hsides`). * `$mirror` Pushes the mirror value to the stack. Initialized to 1 or -1. * `$tolerance` Pushes the tolerance to the stack. Initialized to `Patternizer.tolerance:get()`. The default is 4. # Functions ## Positioning * `a` Pushes the absolute position. (Identical to `$abs`.) * `r` Pushes the true relative position. * `>>` Used to shift a pivot location that has been pushed to the stack. Pops two values. The first is the amount to shift and the second is the pivot. Rotates pivot by the amount while taking into account mirroring and number of sides. Acts in the clockwise direction. * `<<` Same as above but acts anticlockwise. * `rmv` Pops the top value of the stack and moves the relative pivot (`$rel`) by that amount. Also updates the relative offset (`$rof`) with the signed rotational side distance between the new position and old position. (This is not necessarily equal to the argument passed to `rmv`.) * `amv` Pops the the stack and moves the relative pivot (`$rel`) to the absolute position (`$abs`) shifted clockwise by the value popped. The relative offset is still updated as usual. ## Thickness * `i` Converts units of ideal thickness to absolute thickness. * `spath` Pushes the short path thickness. Derived from the relative offset (`$rof`). * `lpath` Pushes the long path thickness. Derived from the relative offset (`$rof`). * `th2s` Converts an absolute thickness value to seconds. * `s2th` Converts a seconds value to absolute thickness. ## Timeline * `t:` Creates a ring with P-String ``. Pops the top two numbers on the stack. The first number is the starting side; the second is the absolute thickness. The tolerance value is added to the thickness. This instruction does not add a wait event to the timeline. * `T:` Same as `t:` but does not add the tolerance value to the thickness. * `p:` Same as `t:` but also delays the timeline by the amount of time it takes for the wall to travel its full thickness. (This delay ignores the tolerance value.) Generally the default choice for generating patterns. * `P:` Same as `p:` but does not add the tolerance value to the thickness. * `sleep` Pops a duration in seconds and adds a wait event to the timeline. * `thsleep` Pops a thickness value and waits the coresponding amount of seconds. * `rsleep` Waits the amount of time it would take for the player to rotate a certain number of revolutions. * `call:` > **WARNING:** This function is depreciated. Use `#()` instead. Creates a function event for the first character after the colon. First, a number is popped to indicate how many arguments the function should recieve. Then that many numbers are popped and saved for later use with the function call. Arguments are passed to the function in the reverse order in which they were popped i.e. the first popped number is the last argument of the called function and vice versa. # Lua Interop * `()` Calls a Lua ``. Any numbers pushed to the stack while evaluating instructions contained within `` are passed as arguments to `` in the order in which they were pushed. Values returned by `` must be numbers and are pushed to the stack. * `#()` Adds a Lua function call event to the timeline. Any numbers pushed to the stack while evaluating instructions contained within `` are passed as arguments to `` in the order in which they were pushed. This statement always returns nothing. > **Note:** Linked functions (functions assocoated with characters that are used in P-Strings) can be called with `()''` or `#()''` where `` is a single character to be called. # Preprocessor > **Note:** Only a subset of the instructions above are allowed to be used in these statements: > - All [Math](#math) instructions > - All [Boolean](#boolean-operators) operators > - The [variables](#global-variables) `$sides` and `$hsides` * `#restrict` If the returned value of this statement is true, the pattern can be spawned. * `"#abs"` The returned value of this statement is used for the absolute pivot. * `"#mirror"` If the returned value of this statement equals -1, the pattern is mirrored. * `"#tolerance"` The returned value of this statement is used for the tolerance value.