mirror of https://github.com/odrling/Aegisub
233 lines
6.6 KiB
Plaintext
233 lines
6.6 KiB
Plaintext
Documentation for the RPN expression engine in OverLua
|
|
======================================================
|
|
|
|
For some graphics processing operationg, OverLua provides an RPN (Reverse
|
|
Polish Notation) to do fast calculations. This expression engine is designed
|
|
primarily to have very fast execution and be multithreading-safe in the
|
|
runtime.
|
|
|
|
The language is meant to support multi-variable calculations, so apart from
|
|
the usual arithmetic operators there is also an assignment operator. Finally
|
|
there is a limited number of temporary registers.
|
|
|
|
There is no explicit Lua interface to the expression engine, rather it is
|
|
implicitly used by some image processing functions. In those cases, a
|
|
program is passed as a string to the image processing function.
|
|
|
|
|
|
Stack machine execution model
|
|
-----------------------------
|
|
|
|
The expression evaluator is implemented as a stack machine with a number
|
|
of registers. Some of these registers are used for input and/or output
|
|
values and some are freely usable for temporary storage.
|
|
|
|
The stack holds numbers in 'double' precision, this is the only data type
|
|
supported by the machine. There are no practical limits on stack depth.
|
|
|
|
The registers also hold numbers in 'double' precision. Depending on the
|
|
function using the expression evaluator, different input/output registers
|
|
will be available. The input/output registers will usually be single-letter
|
|
names using uppercase letters. There are always exactly ten temporary
|
|
registers available, named "t0" to "t9", ie. lowercase "t" followed by
|
|
a digit. The contents of the temporary registers are undefined at the start
|
|
of program execution.
|
|
|
|
|
|
The program consists of a number of instructions executed sequentially. There
|
|
are three basic types of instructions:
|
|
- push
|
|
- call
|
|
- store
|
|
|
|
A 'push' instruction pushes a single number to the top of the stack. The
|
|
source of the number can either be a constant or a register.
|
|
|
|
A 'call' instruction pops some numbers from the stack, performs an operation
|
|
on them and pushes a single number back onto the stack. This includes basic
|
|
arithmetic operations such as addition, mulitiplication, but also functions
|
|
such as sinus, rounding and logarithms. How many numbers are popped from the
|
|
stack depends on the function.
|
|
|
|
The 'store' instruction pops one number from the stack and stores it into
|
|
a register, overwriting the previous number in the register.
|
|
|
|
|
|
After every instruction in the program has been executed, any remaining numbers
|
|
on the stack are discarded, and the numbers in the output registers are passed
|
|
to the function using the expression evaluator.
|
|
|
|
|
|
If a program operation attempt to pop a number from the stack when the stack
|
|
is empty, the machine halts with an error state, and the result of the program
|
|
is undefined.
|
|
|
|
|
|
Expression syntax
|
|
-----------------
|
|
|
|
The syntax used to specify programs is very straightforward.
|
|
|
|
The program consists of a number of tokens separated by whitespace. Each token
|
|
translates into one instruction.
|
|
|
|
|
|
A token can be a number. This translates into a 'push' instruction, pushing
|
|
that number as a constant. The format for numbers is the same as in C.
|
|
|
|
Examples: "1", "-5", "3.14", ".5" "2.998e8"
|
|
|
|
|
|
A token can be a register name. This translates into a 'push' instruction,
|
|
pushing the number in the register.
|
|
|
|
Examples: "X", "Y", "t0", "t6"
|
|
|
|
|
|
A token can be a basic arithmetic operator. These translate into 'call'
|
|
instructions. Each of these represent a function that pops two numbers,
|
|
performs the calculation and pushes the result.
|
|
|
|
The basic arithmetic operators are: + - * / ^
|
|
|
|
Examples:
|
|
Suppose the two previous instructions were "A B" where A and B are registers.
|
|
This means that now the stack contains B at the top and A just below.
|
|
Operator "+" will then calculate "A + B". Operator "-" will calculate "A - B".
|
|
Operator "*" will calculate "A * B". Operator "/" will calculate "A / B".
|
|
Operator "^" will calculate "A ^ B", ie. A raised to the power of B.
|
|
|
|
The result of illegal operations is undefined. It will most likely result in
|
|
an invalid number being pushed onto the stack, and operating on that number
|
|
will cause the error to propagate.
|
|
|
|
|
|
A token matching the name of a defined function will translate into a 'call'
|
|
instruction for the given function. A number of standard functions are always
|
|
available, see below for details.
|
|
|
|
|
|
An equal sign followed by the name of a register translated into a 'store'
|
|
instruction, that will pop the number at the top of the stack and store it
|
|
into the named register. There must not be any whitespace between the equal
|
|
sign and the register name.
|
|
|
|
Examples: "=X", "=t0"
|
|
|
|
|
|
Standard function library
|
|
-------------------------
|
|
|
|
The following functions are always available in the machine.
|
|
|
|
|
|
~ (tilde character)
|
|
Takes one argument, produces one result.
|
|
Unary minus. (Negate the argument.)
|
|
|
|
abs
|
|
Takes one argument, produces one result.
|
|
Return the absolute value.
|
|
|
|
floor
|
|
Takes one argument, produces one result.
|
|
Round towards negative infinity.
|
|
|
|
ceil
|
|
Takes one argument, produces one result.
|
|
Round towards positive infinity.
|
|
|
|
|
|
log
|
|
Takes one argument, produces one result.
|
|
Natural (base e) logarithm.
|
|
|
|
exp
|
|
Takes one argument, produces one result.
|
|
Natural exponentiation. (e to the power of x.)
|
|
|
|
sqrt
|
|
Takes one argument, produces one result.
|
|
Square root.
|
|
|
|
e
|
|
Takes no arguments, produces one result.
|
|
Push the value of e.
|
|
|
|
|
|
min
|
|
Takes two arguments, produces one result.
|
|
Return the smallest of the arguments.
|
|
|
|
max
|
|
Takes two arguments, produces one result.
|
|
Return the largest of the arguments.
|
|
|
|
|
|
pi
|
|
Takes no arguments, produces one result.
|
|
Push the value of pi.
|
|
|
|
sin
|
|
Takes one argument, produces one result.
|
|
Sinus function. Argument in radians.
|
|
|
|
cos
|
|
Takes one argument, produces one result.
|
|
Cosine function. Argument in radians.
|
|
|
|
tan
|
|
Takes one argument, produces one result.
|
|
Tangent function. Argument in radians.
|
|
|
|
asin
|
|
Takes one argument, produces one result.
|
|
Arc sinus function.
|
|
|
|
acos
|
|
Takes one argument, produces one result.
|
|
Arc cosine function.
|
|
|
|
atan
|
|
Takes one argument, produces one result.
|
|
Arc tangent function.
|
|
|
|
|
|
mod
|
|
Takes two arguments, produces one result.
|
|
Modulo operation.
|
|
|
|
|
|
rand
|
|
Takes no arguments, produces one result.
|
|
Return a random value in range 0..1.
|
|
|
|
|
|
ifgtz
|
|
Takes three arguments, produces one result.
|
|
If the first argument is greater than zero, return the second argument,
|
|
else return the third argument.
|
|
|
|
ifeqz
|
|
Takes three arguments, produces one result.
|
|
If the first argument is equal to zero, return the second argument,
|
|
else return the third argument.
|
|
|
|
|
|
Sample programs
|
|
---------------
|
|
|
|
For raster.pixel_value_map:
|
|
|
|
"rand =t0 t0 =R t0 =G t0 =B"
|
|
Create a field of random gray-values.
|
|
|
|
"0 =R 1 G - =G"
|
|
Zero out the red channel and invert the green channel.
|
|
|
|
|
|
For raster.pixel_coord_map:
|
|
|
|
"X .5 rand - + =X Y .5 rand - + =Y"
|
|
Create some jitter in the pixels.
|