contingent

I finished implementing the 'contingent' control structure yesterday, which completes the set of Rogue control structures.

Contingents allow you to "bail out early" of a logical test, similar to a 'return' or a try/catch/throw but used for local logic instead of cross-method exceptions.

The syntax is this:

contingent
  # any mix of statements along with:
  necessary (x)  # jump to 'unsatisfied' if x is false
  sufficient (y) # jump to 'satisfied' if y is true
  # fall through to 'satisfied'
satisfied
  # statements
unsatisfied
  # statements
endContingent

Here's an example that prints out which integers between 1 and 100 are prime:

forEach (n in 1..100)
  contingent
    # Only numbers 2+ can be prime
    necessary  (n > 1)

    # 2 is a prime number
    sufficient (n == 2)

    # Any other even number is not prime
    necessary  (n & 1 == 1)

    # Mod the number with odd numbers 3..sqrt(n).
    forEach (divisor in 3..Math.sqrt(n) step 2)
      # Remainders must be non-zero
      necessary (n % divisor)?
    endForEach

  satisfied
    println n + " is prime"

  endContingent
endForEach