Conditions & Loops
OcaltQL has no ELSE keyword. Fallback logic uses OR. Chained conditions use OR IF. Compound conditions use AND and OR inline between full condition phrases. Loops use WHILE and LOOP.
IF
The condition follows IF. The body is wrapped in OPEN and CLOSE. If the condition is false, execution falls to the OR block if one is present.
IF ?a IS EQUAL TO ?b
OPEN
EMIT "Equal"
CLOSE
IF ?a IS GREATER THAN 10
OPEN
EMIT "Big"
CLOSE
OR
OPEN
EMIT "Small"
CLOSE
IF ?a IS EQUAL TO 1
OPEN
EMIT "One"
CLOSE
OR IF ?a IS EQUAL TO 2
OPEN
EMIT "Two"
CLOSE
OR IF ?a IS EQUAL TO 3
OPEN
EMIT "Three"
CLOSE
OR
OPEN
EMIT "Other"
CLOSE
Comparison Operators
All comparison operators are multi-word natural language phrases. IS and ARE are interchangeable — ARE is used conventionally with arrays and objects.
IF ?a IS EQUAL TO ?b
AFTER IF ?a IS IDENTICAL TO ?b
AFTER IF ?a IS GREATER THAN 10
AFTER IF ?a IS LESS THAN 10
AFTER IF ?a IS GREATER THAN OR EQUAL TO 10
AFTER IF ?a IS LESS THAN OR EQUAL TO 10
AFTER IF ?a IS NOT EQUAL TO ?b
AFTER IF ?a IS NOT IDENTICAL TO ?b
AFTER IF ?text CONTAINS "hello"
AFTER IF ?var IS SET
AFTER IF ?var IS EMPTY
AFTER IF ?var IS NOT EMPTY
AFTER IF ?var IS NULL
AFTER IF ?var IS NOT NULL
Compound Conditions
AND and OR connect full condition phrases inline inside an IF or WHILE. These are not chain keywords here — they are logical operators between conditions. Chaining is virtually unlimited.
AND and OR between two full condition phrases inside an IF are logical operators. AND and OR between two statements outside a condition are chain keywords. The parser distinguishes by position.&& / || — AND binds tighter than OR. IF ?a IS ... AND ?b IS ... OR ?c IS ... evaluates as (?a IS ... AND ?b IS ...) OR (?c IS ...). Evaluation is left to right and short-circuits — an AND chain stops at the first false condition, an OR chain stops at the first true one; conditions after that point are not evaluated.IF ?a IS GREATER THAN 10 AND ?b IS EQUAL TO ?somevalue
OPEN
EMIT "Both true"
CLOSE
IF ?a IS GREATER THAN 10 OR ?b IS EQUAL TO ?somevalue
OPEN
EMIT "At least one true"
CLOSE
IF ?a IS IDENTICAL TO "this" AND ?a IS NOT EQUAL TO ?x OR ?b IS GREATER THAN 44
(* Groups as: (?a IS IDENTICAL TO "this" AND ?a IS NOT EQUAL TO ?x) OR ?b IS GREATER THAN 44 *)
OPEN
EMIT "Complex condition met"
CLOSE
IF ?a IS GREATER THAN OR EQUAL TO 10 AND ?b IS LESS THAN OR EQUAL TO 20
(* The "OR" inside "GREATER THAN OR EQUAL TO" and "LESS THAN OR EQUAL TO" is part of the
operator phrase itself, not a logical connector. This is a single AND:
(?a >= 10) AND (?b <= 20) *)
OPEN
EMIT "In range"
CLOSE
IF ?x IS GREATER THAN 0 AND ?x IS LESS THAN 100 OR ?y IS EQUAL TO "special" AND ?z IS SET OR ?flag IS EMPTY
(* Groups as: (?x > 0 AND ?x < 100) OR (?y IS EQUAL TO "special" AND ?z IS SET) OR (?flag IS EMPTY) *)
OPEN
EMIT "Very complex condition"
CLOSE
Array & Object Conditions — ARE and SOME
IF ?arr ARE checks that every item in the array or object matches the condition. IF SOME ?arr ARE checks that at least one item matches. Both work with objects as well — checking property values.
IF ?arr ARE EQUAL TO "target"
OPEN
EMIT "All match"
CLOSE
IF SOME ?arr ARE EQUAL TO "target"
OPEN
EMIT "Found at least one"
CLOSE
IF SOME ?arr ARE GREATER THAN 10 AND SOME ?arr ARE LESS THAN 100
OPEN
EMIT "Has values in range"
CLOSE
IF ?arr ARE EQUAL TO "ok" OR ?obj ARE EMPTY
OPEN
EMIT "Either all ok or object empty"
CLOSE
IF SOME ?obj ARE EQUAL TO "admin"
OPEN
EMIT "At least one admin role"
CLOSE
IF SOME ?arr ARE EQUAL TO "error" AND ?status IS EQUAL TO "active" OR SOME ?obj ARE NULL
OPEN
EMIT "Complex match"
CLOSE
WHILE SOME ?arr ARE GREATER THAN 0
OPEN
EMIT "Still has positives"
CLOSE
!THIS — Runtime Context
!THIS() accesses the current execution context from inside a nest. It is only valid inside an OPEN...CLOSE block.
!THIS('state')— alwaystrueinside a nest, because the nest only executes when the condition passed!THIS('some')— an array of all matching keys or indices from aSOMEcheck. Additive acrossANDandORcompoundSOMEconditions — may contain duplicates if a key matched multiple conditions. Empty array in theORblock when no match was found.
IF ?a IS GREATER THAN 10
OPEN
EMIT !THIS('state')
(* Output: true — we are inside the nest because the condition was true *)
CLOSE
IF SOME ?arr ARE EQUAL TO "target"
OPEN
EMIT !THIS('some')(0) (* first matching index *)
AFTER COUNT !THIS('some') SET ?total
AFTER EMIT ?total (* how many matched *)
CLOSE
(* Keys from both conditions combined, may have duplicates *)
IF SOME ?arr ARE GREATER THAN 10 AND SOME ?arr ARE LESS THAN 100
OPEN
EMIT !THIS('some')
CLOSE
(* All keys that matched either condition *)
IF SOME ?arr ARE EQUAL TO "error" OR SOME ?arr ARE EQUAL TO "warn"
OPEN
EMIT !THIS('some')
CLOSE
IF SOME ?arr ARE EQUAL TO "zulu"
OPEN
EMIT "Found"
CLOSE
OR
OPEN
EMIT !THIS('some') (* empty array — no matches *)
CLOSE
IF SOME ?obj ARE EQUAL TO "admin"
OPEN
EMIT "Admin keys: " & [JOIN !THIS('some') WITH ", "]
CLOSE
WHILE
WHILE repeats the body for as long as the condition remains true. The condition is evaluated before each iteration. Compound conditions work identically to IF.
NUMBER 0 SET ?i
AFTER WHILE ?i IS LESS THAN 5
OPEN
EMIT ?i
AFTER CALCULATE ?i + 1 SET ?i
CLOSE
NUMBER 0 SET ?i
AFTER NUMBER 10 SET ?limit
AFTER WHILE ?i IS LESS THAN ?limit AND ?i IS NOT EQUAL TO 3
OPEN
EMIT ?i
AFTER CALCULATE ?i + 1 SET ?i
CLOSE
LOOP
LOOP iterates over a numeric range. SET ?i is the loop variable, available inside the body. An optional STEP controls the increment. Negative steps count downward.
LOOP 1 TO 5 SET ?i
OPEN
EMIT ?i
CLOSE
LOOP 0 TO 10 STEP 2 SET ?i
OPEN
EMIT ?i
CLOSE
LOOP 10 TO 1 STEP -1 SET ?i
OPEN
EMIT ?i
CLOSE
BREAK and CONTINUE
BREAK exits the current loop immediately. CONTINUE skips the remainder of the current iteration and moves to the next. Both are only valid inside a loop body.
LOOP 1 TO 10 SET ?i
OPEN
IF ?i IS EQUAL TO 5
OPEN
BREAK
CLOSE
AFTER EMIT ?i
CLOSE
(* Output: 1 2 3 4 — stops before 5 *)
LOOP 1 TO 10 SET ?i
OPEN
IF ?i IS EQUAL TO 5
OPEN
CONTINUE
CLOSE
AFTER EMIT ?i
CLOSE
(* Output: 1 2 3 4 6 7 8 9 10 — skips 5 *)
OR as the fallback block and OR IF for chained conditions. The runtime constructs the equivalent Rust if / else if / else at execution level.