VM_RPN
is a GBVM instruction that initiates a Reverse Polish Notation (RPN) calculation block. It allows you to perform complex arithmetic and logical operations using a stack-based approach.
Purpose:
RPN is a mathematical notation where every operator follows all of its operands. For example, to express 3 + 4
, you would write 3 4 +
. This notation is particularly well-suited for stack-based virtual machines like the GBVM because it eliminates the need for parentheses and simplifies parsing. VM_RPN
is essential for:
When VM_RPN
is executed, the GBVM enters a special RPN evaluation mode. Subsequent instructions within this block (like .R_INT8
, .R_REF_IND
, .R_OPERATOR
, .R_REF_MEM_SET
) manipulate values on the RPN stack. The final result of the RPN expression is typically left on the VM’s main stack.
Syntax:
VM_RPN
; RPN operations here
VM_STOP ; Or VM_SET_INT16, etc., to end the RPN block
VM_RPN
itself takes no arguments. The operations within the RPN block implicitly act on the stack.
Usage Example: Calculating Damage with Multiple Factors
Imagine a damage calculation: (PLAYER_ATTACK + WEAPON_BONUS) - ENEMY_DEFENSE
. All these values are stored in variables.
; In your combat script:
; Variables
VAR_PLAYER_ATTACK:
.R_INT16 10
VAR_WEAPON_BONUS:
.R_INT16 5
VAR_ENEMY_DEFENSE:
.R_INT16 8
VAR_FINAL_DAMAGE:
.R_INT16 0 ; To store the result
; Calculate (PLAYER_ATTACK + WEAPON_BONUS) - ENEMY_DEFENSE
VM_PUSH_REFERENCE VAR_FINAL_DAMAGE ; Push reference for where to store the result
VM_RPN
.R_REF_MEM .R_INT16, VAR_PLAYER_ATTACK ; Push value of Player Attack (10)
.R_REF_MEM .R_INT16, VAR_WEAPON_BONUS ; Push value of Weapon Bonus (5)
.R_OPERATOR + ; Add them (10 + 5 = 15). Stack: [15]
.R_REF_MEM .R_INT16, VAR_ENEMY_DEFENSE ; Push value of Enemy Defense (8). Stack: [15, 8]
.R_OPERATOR - ; Subtract (15 - 8 = 7). Stack: [7]
.R_INT16 ; Specify result as 16-bit integer
.R_REF_SET_IND ; Store the result (7) into VAR_FINAL_DAMAGE
VM_STOP
; Now VAR_FINAL_DAMAGE will contain 7.
; ... continue script with damage application ...
In this example:
VM_PUSH_REFERENCE VAR_FINAL_DAMAGE
prepares the stack for storing the final result.VM_RPN
begins the RPN calculation.10
, then 5
)..R_OPERATOR +
pops 5
and 10
, adds them, and pushes 15
.8
is pushed onto the stack..R_OPERATOR -
pops 8
and 15
, subtracts, and pushes 7
..R_INT16
ensures the type is correct..R_REF_SET_IND
uses the VAR_FINAL_DAMAGE
reference (pushed earlier) and the 7
(result of RPN) to store 7
into VAR_FINAL_DAMAGE
.Analogy to other programming languages:
RPN is like using a scientific calculator where you enter numbers first and then the operation. In traditional programming, you write (A + B) - C
. In RPN, it’s A B + C -
. While it might seem unusual at first, it’s a very efficient way for a stack-based machine to process expressions.