Switch ExpressionsΒΆ
The switch
-expression in Minilang provides an alternative to an if
-expression with multiple elseif
branches when a single value is tested for the first match.
For example:
1fun test(X) do
2 if X = 1 then
3 "one"
4 elseif 2 <= X <= 3 then
5 "few"
6 elseif 4 <= X <= 7 then
7 "several"
8 else
9 "many"
10 end
11end
12
13fun test2(X) do
14 switch X: integer
15 case 1 do
16 "one"
17 case 2, 3 do
18 "few"
19 case 4 .. 7 do
20 "several"
21 else
22 "many"
23 end
24end
There are a few differences, a switch
-expression needs a switch provider, in this case integer
. The provider of a switch determines how Minilang treats the switch values to find a matching branch. A switch
-expression also allows multiple values per-branch, and overall is faster than the corresponding if
-expression. Note that the values in each branch are evaluated at compile time so can't refer to local variables.
Given a switch
-expression with provider P
, the compiler uses the method compiler::switch(P, Cases...)
to implement the switch
-expression. Here Cases
is a list of lists, one list per case
containing the case values. The implementation of compiler::switch
for P
must return another function, which takes a value and return an integer index (starting at 0
) corresponding to the chosen branch.
This design allows support for new kinds of switch
-expressions to be added later, either to the language or by specific applications. Currently the following switch providers are available:
type
Case values must be types (or
nil
). A case value matches if the switch value is of the same type or a sub-type.integer
,real
Case values must be numbers or numeric ranges. A case value matches if the switch value is equal to it (for numbers) or contained in it (for ranges).
string
Case values must be strings or regular expressions. A case value matches if the switch value is equal to it (for strings) or matches it (for regular expressions).
- Any
enum
type Case values must be values of the enum type or strings corresponding to values of the enum. A case value matches if the switch value is equal to it.
- Any
flags
type Flag values must be values of the flags type, strings corresponding to values of the enum, or tuples of the previous. A case value matches if the switch value contains at least the same flags, it may have extra flags.
- Any function or macro
Any function or macro can be used as a switch provider as long as it accepts a list of lists and returns another function as described above.