given expressions

Langur's given expressions are very flexible. I'll start with examples, then give a general idea of what's allowed in a given expression, and then some notes below.

given example 1

given .x, .y, .z { case true: ... # all are true case true, false, null: ... # .x == true and .y == false and .z == null case _, 123, < 7: ... # .y == 123 and .z < 7 case 10 >=, _: ... # 10 >= .x case _, re/abc+/: ... # .y matches regex pattern abc+ default: ... }

given example 2

Using a given on a catch can be convenient....

catch given .err["cat"], .err["msg"] { case "math", _: writeln("math error!") ... default: throw .err # rethrow }

given example 3

val .y = "abcd" given .x { case 100: ... # .x == 100 case 200; len(.y) > 3: ... # .x == 200 and len(.y) > 3 }

given example 4

val .z = "abcd" given <= .x, .y > { case 100: ... # 100 <= .x and .y > 100 case or 200, 300; len(.z) > 3: ... # (200 <= .x or .y > 300) and len(.z) > 3 case 200, 300 >=; or len(.z) > 3: ... # 200 <= .x and 300 >= .y or len(.z) > 3 case ; len(.z) > 3: ... # len(.z) > 3 }

breakdown

The following gives a semi-technical general idea for the use of a given expression.

given [[comparison op] expr1 | expr1 [comparison op] [, ... [comparison op] exprn | [comparison op] exprn]] { case [[logical op] [[comparison op] expr1 | expr1 [comparison op] [, ... [comparison op] exprn | [comparison op] exprn]]] [; [logical op] alt1 [, ... altn]] : ... default: ... }

Multiple expressions may be used to test against (such as given .x, .y, .z ...).

By default, test conditions are compared as rightmost operands of the == operator (the test expressions at the beginning of the given expression being the leftmost operands by default). Alternate default comparison operators may be specified at the beginning or end of each test expression (such as given .x >, != .y, .z ...). An alternate comparison operator may also be specified immediately before or after the test condition (such as case != 100, 5 <=: ...). Comparison operators specified in the case statement take precedence.

A test condition may use an underscore to indicate no-op (no comparison, such as case _, 2: ... to test only the second expression).

A single test condition, with no no-ops, is a special condition meaning to test all the expressions against the condition.

By default, logical and is used between test conditions in a case statement. Alternate logical operators may be specified immediately after the case keyword and/or immediately after the semicolon in a case test.

regex

A variable or a test condition may be a regex, which will match the other against the regex pattern. If both are a regex pattern, they will be treated the same as other test conditions. The value being checked against a regex does not have to be a string, as it will be converted into a string at testing for a match.

alternate expressions

Alternate test conditions (after a semicolon within a case test) allow you to insert other test conditions without having to use an if/else statement.

A given may also have no expressions to test against. In this case, alternate test expressions are used without a semicolon.

fallthrough

A fallthrough is only allowed at the end of a case statement body.

Normally, there is no implicit fallthrough.

A case statement with an empty body has an implicit fallthrough (case alternate).