Skip to content

Operators

Arithmetic Operators

Operator Description Types
+ Addition Integer, Real
- Subtraction / Unary negation Integer, Real
* Multiplication Integer, Real
/ Division (integer truncates toward zero) Integer, Real
mod Modulo (remainder) Integer
declare result := 10 + 5          { 15 }
declare ~precise := 17.0 / 5.0    { 3.4 }
declare int_div := 17 / 5         { 3, truncated }
declare remainder := 17 mod 5     { 2 }
function TO_MB_ENC(x) -> y
    y := int(float(x * 4) / 1024.0 / 1024.0 * 1000.0)
end function

function math.mod_loop(in, loop_size) -> return
    return := (in + loop_size) mod loop_size
end function

Comparison Operators

Operator Description
= Equal to
# Not equal to
< Less than
> Greater than
<= Less than or equal to
>= Greater than or equal to

KSP uses # for not-equal (not != or <>).

define BOOL.TRUE := (bool_validator = bool_validator)
define BOOL.FALSE := (bool_validator # bool_validator)

if keymap.key_flows[keymap.selected_map, EVENT_NOTE] # -1
    { flow is assigned }
end if

define Voice.validate.runtime(#v#) := (#v# >= -1)

Logical Operators

Operator Description
and Logical AND
or Logical OR
not Logical NOT
if MIDI_CHANNEL >= 0 and cluster.legal = TRUE and ivls.critical_disable = FALSE ...
  and keymap.key_flows[keymap.selected_map, EVENT_NOTE] # -1
    { process note event }
end if

if not check_ref(Voice, self)
    { voice reference is invalid }
end if

if (ivls.no_dev_mode_ui = FALSE and lib.is_dev_mode() = TRUE) or ivls.script_force_ui = TRUE
    { show UI }
end if

Bitwise Operators

Operator Description
.and. Bitwise AND
.or. Bitwise OR
.not. Bitwise NOT (complement)
.xor. Bitwise XOR
sh_left(value, bits) Left bit shift
sh_right(value, bits) Right bit shift
declare masked := value .and. 0xFF           { keep lower 8 bits }
declare flags := FLAG_A .or. FLAG_B          { combine flags }
declare inverted := .not. value              { one's complement }
declare toggled := value .xor. mask          { toggle bits }
declare doubled := sh_left(value, 1)         { value * 2 }
declare halved := sh_right(value, 1)         { value / 2 }

IVLS Bitwise Examples

function math.set_nth_bit(B, N, val)
    B := BOOL.CHOOSE(val, ...
                    sh_left(1, N) .or. B, ...
                    (math.ALLMASK - sh_left(1, N)) .and. B ...
                )
end function

function UI.is_ctrl_held(bitmask) -> return
    return := (bitmask .and. UI.CTRL_KEY) = UI.CTRL_KEY
end function

define CONDITION.IS_BITMASK_COMMON(A, B) := (A .and. B > 0)

Branchless Techniques

function math.max(a, b) -> return
    return := a * (1 + sh_right(a - b, 31)) - b * sh_right(a - b, 31)
end function

function math.is_greater(a, b) -> return
    return := -sh_right(b - a, 31)
end function

Uses the sign bit (bit 31) for branchless conditionals.


String Operator

Concatenation (&)

declare @message := "Value: " & value
declare @full_path := @base_path & filename & ".nka"

function TO_MB(x) -> str
    str := (TO_MB_ENC(x) / 1000 & '.' & (TO_MB_ENC(x) mod 1000))
end function

Assignment Operator

:=

declare velocity := 100
volume := -6000
@name := "Piano"

Define Append (+=)

Compile-time list extension (not runtime):

define Voice.ADD_MEMBERS += Stl.Modulation.MEMBERS
define CLUSTER_TABLE += Voice

Special Functions

Function Description
in_range(val, min, max) Returns 1 if min <= val <= max
abs(x) Absolute value
real(x) / float(x) Integer to float
int(x) Float to integer (truncates)
define Voice.validate.note(#v#) := (in_range(#v#, 0, 127))
define float(#x#) := real(#x#)

function math.range(a, b) -> return
    return := abs(a - b)
end function

Operator Precedence

Priority Operators Description
1 () Parentheses
2 .not., not, - (unary) Unary
3 *, /, mod Multiplicative
4 +, - Additive
5 sh_left, sh_right Bit shifts
6 .and. Bitwise AND
7 .xor. Bitwise XOR
8 .or. Bitwise OR
9 <, >, <=, >=, =, # Comparison
10 and Logical AND
11 or Logical OR
12 & String concatenation
13 := Assignment

Use parentheses to make precedence explicit:

result := ((a + b) * c) / d
flag := ((value .and. mask) = mask) and (status # 0)

Bitmask Patterns

{ Set a bit }
flags := flags .or. sh_left(1, bit_position)

{ Clear a bit }
flags := flags .and. .not. sh_left(1, bit_position)

{ Toggle a bit }
flags := flags .xor. sh_left(1, bit_position)

{ Check if bit is set }
is_set := (flags .and. sh_left(1, bit_position)) > 0