Control Flow¶
| Statement | Purpose |
|---|---|
if ... end if |
Conditional execution |
if ... else ... end if |
Two-way branching |
if ... else if ... end if |
Multi-way branching |
while ... end while |
Condition-based loops |
for ... to ... end for |
Counted loops (ascending) |
for ... downto ... end for |
Counted loops (descending) |
select ... case ... end select |
Multi-way value matching (no fall-through) |
KSP has no break or continue statements. Use iterator manipulation for early exit.
Conditional Statements¶
if / else / else if¶
if condition
// ...
end if
if condition
// ...
else
// ...
end if
if condition1
// ...
else if condition2
// ...
else
// ...
end ifif ui.option.disp_active = TRUE and ui.disp_timestamp > -1
if lib.get_last_touched() - ui.disp_timestamp > UI.PARAM_DISP_DELAY_MS
set_text(ui.Display, "")
ui.disp_timestamp := -1
end if
end ifif not check_ref(Voice, vo_to_send)
if vo_to_send = self
message('Node ' & ivls.node_name(nenv) & ' tried to play passive input after release!')
else
message('Node ' & ivls.node_name(nenv) & ' tried to play invalid Voice!')
cluster.Dump(Voice, self)
end if
else if self_invalid = TRUE
message('IVLS has been halted at node ' & ivls.node_name(nenv))
Voice.delete(vo_to_send)
else if NodeEnv[nenv].info.path_cancelled = TRUE and not (Voice[vo_to_send].duration > 0)
if vo_input = self
Voice.delete(vo_to_send)
end if
else
if Voice[vo_to_send].stage < ivls.flow_lengths[Voice[vo_to_send].flow] - 1
ivls._fire_new_child(vo_to_send, vo_as_parent)
NodeEnv[nenv].sentVoice := vo_to_send
else
Voice.delete(vo_to_send)
end if
end ifWhile Loop¶
while (condition)
// ...
end whilewhile (Arp.Notes.count[thread] > 0)
if Arp.step_counter[thread] >= Arp.Notes.count[thread]
Arp.step_counter[thread] := 0
end if
declare arp_note := Voice.copy(tpl)
Voice[arp_note].note := Arp.Notes[thread, Arp.step_counter[thread]]
Voice[arp_note].vel := Arp.Velocities[thread, Arp.step_counter[thread]]
Voice[arp_note].duration := STEPTIME * 1000
ivls.play(arp_note)
inc(Arp.step_counter[thread])
ivls.wait_ms.unsafe(STEPTIME)
end whileLinked list traversal:
declare current := FIFO.peek_entry(Runtime[runtime].voiceList)
while(check_ref(Entry, current))
declare next := Entry[current].next
if Voice[Entry[current].data].note = note
keys.KeyBuffer.delete_item(ch, Entry[current].data)
end if
current := next
end whileMultiple exit conditions:
while (path_exhausted = FALSE and user_continue = TRUE and self_invalid = FALSE)
path_exhausted := TRUE
user_continue := FALSE
// ... processing that may set user_continue := TRUE ...
end whileFor Loop¶
Ascending (to)¶
for iterator := start to end_value
// ...
end forfor Voice.i := 0 to num_elements(#array#) - 1
Voice.INIT[Voice.write_idx] := #array#[Voice.i]
inc(Voice.write_idx)
end forNested loops:
for i := 0 to IVLS.MAX_FLOWS - 1
sum := 0
for j := 0 to IVLS.NODES_PER_FLOW - 1
if ivls.flows[i, j] = -1
j := IVLS.NODES_PER_FLOW // early exit
else
inc(sum)
end if
end for
ivls.flow_lengths[i] := sum
end forDescending (downto)¶
for iterator := start downto end_value
// ...
end forfunction search_last(array, value) -> return
return := -1
for srch.i := num_elements(array) - 1 downto 0
if array[srch.i] = value
return := srch.i
srch.i := -1 // early exit
end if
end for
end functionSelect-Case¶
Multi-way value matching. Cases do not fall through.
select expression
case value1
// ...
case value2
// ...
end selectselect Voice[self].delay_type
case ivls.duration_type.MS
ivls.wait_us(Voice[self].delay)
case ivls.duration_type.TICKS
ivls.wait_ticks(Voice[self].delay)
end selectselect json.value.type
case json.type.INT
@value := f'<json.value.int_value>'
case json.type.FLOAT
@value := f'<json.value.float_value>'
case json.type.STRING
@value := f'\"<json.value.str_value>\"'
end selectEarly Exit Patterns (No break/continue)¶
For loop: set iterator past bounds¶
for i := 0 to count - 1
if found_target
i := count // exits ascending loop
end if
end for
for i := max downto 0
if found_target
i := -1 // exits descending loop
end if
end forWhile loop: use flag or condition variable¶
declare done := FALSE
while (done = FALSE)
if exit_condition
done := TRUE
else
// processing
end if
end while