Commit 51bdd586 authored by Matthias Simon's avatar Matthias Simon
Browse files

Add enumerations

parent 1a2c2bb9
Loading
Loading
Loading
Loading
+231 −3
Original line number Diff line number Diff line
@@ -2,8 +2,21 @@

## Booleans

The predefined type `boolean` represents the set of boolean values `true` and `false`.
It provides the following operations:
The predefined type `boolean` is the set of boolean values true and false.

Constant literals `true` and `false` are of type `boolean`.

`true` represents the true value.
`false` represents the false value.

```ttcn3 test="Verify logical equality"
true == true
false == false
true != false
false != true
```

Boolean values provide the following operations:

  - **`not`**: The logical negation.
    The result is `true` if the operand is `false`, and `false` if the operand is `true`.
@@ -12,7 +25,6 @@ It provides the following operations:
  - **`or`**: The logical disjunction.
    The result is `true` if at least one operand is `true`, and `false` otherwise.


```ttcn3 test="Verify logical negation"
not true == false
not false == true
@@ -137,3 +149,219 @@ x \brem |y| & \text{when } x \geq 0 \\
 3 mod 3 == 0
```


### Enumerations

**Syntactical Structure**

```ebnf
NamedEnumType = "type" "enumerated" name "{" Enums "}".
EnumType = "enumerated" "{" Enums "}".
Enums = EnumValue { "," EnumValue } [","].
EnumValue = name [ "(" Expr {"," Expr } [","] ")" ].
```

**Semantic Description**

An enumerated type defines a closed set of enumerated values.

An enumerated value is a constant literal that represents one or more integer
values.

These integer values may be assigned by the user to an enumerated value either
explicitly by specifying one or more integers or integer ranges.

Or, implicitly the following scheme:

> Each enumerated value gets assigned one integer that is not already used by
> another enumerated label, starting with 0 and incrementing by 1.


The use of integer expressions is permitted.

> NOTE: Is is strongly recommended to limit the use of expression and avoid
> side-effects.

```ttcn3 test="Verify enumerated values are assigned as specified"
type enumerated Enum {
    A, // expect: enum2int(A) == 10
    B (1..9, 10+1),
    C, // expect: enum2int(C) == 12
    D, // expect: enum2int(D) == 14
    E, // expect: enum2int(E) == 15
    F (-10..0),
}
```

<-- TODO: Clarify syntax: B(1..9, 11) vs B((1..9),11) -->

If no integer could be assigned an error shall be emitted.

```ttcn3 test="Verify an error is emitted, when no integer could be assigned"
type enumerated Enum {
    A(0..infinity),
    B, // error: all possible integers are assigned to A.
}
```

An enumerated value has exactly one value.
This value must be specified explicitly, if more than one value is possible.
A value that is not part of the enumerated value definition shall be an error.


```ttcn3 test
type enumerated Enum {
    A,
    B(1..10),
}

const Enum e1 := A;      // ok
const Enum e2 := A(0);   // ok
const Enum e3 := A(1);   // error: `1` is invalid for enumerated value A
const Enum e4 := B;      // error: value for B is ambigious
const Enum e5 := B(1);   // ok

const template Enum te1 := B(?) // ok
const template Enum te2 := B(1..3) // ok
```

<!-- TODO: Example 3 on page 66 suggests explicit integers to be an error (`Blue(0)`) --> 

Enumerated values provide the following operations:

  - **Greater (`>`)**:
    The result is `true` if the left underlying integer is greater than the right underlying integer.

  - **Greater-than (`>=`)**:
    The result is `true` if the left underlying integer is greater than
    or equal to the right underlying integer.

  - **Less (`<`)**:
    The result is `true` if the left underlying integer is less than the right underlying integer.

  - **Less-than (`<=`)**:
    The result is `true` if the left underlying integer is less than or equal to the right underlying integer.

```ttcn3 test
type enumerated Enum {
    A(0), B(1..2), C(3)
}

A == A
A != B(1)
A < B(1)
B(1) < B(2)
B(1) != B(2)
B(1) < C
B(1) <= B(1)
```

An enumerated value shall not be converted to the corresponding integer
values implicitly, and vice versa.

```ttcn3 test="Verify enumerated values are not implicitly converted"
type enumerated Enum { A(0) }
var Enum e := 0; // error: no implicit conversion
```

An enumerated value shall be unique within the enumerated type scope.

```ttcn3 test="Verify enumerated values are unique"
type enumerated Enum {
    A,
    A, // error: redefinition of A
}
```


The identifier of an enumerated value shall be unique in its scope-hierarchy
branch (see clause 0.0).

```ttcn3 test="Verify identical identifiers in parallel branches are permitted"
module M {

    // The identifiers `Saturday` and `Sunday` are unique in respect of their
    // scope-hierarchy branch.

    type enumerated Weekdays {
        Monday,
        Tuesday,
        Wednesday,
        Thursday,
        Friday,
        Saturday,
        Sunday,
    }

    type enumerated Weekend {
        Saturday,
        Sunday,
    }
}
```

```ttcn3 test="Verify enumerated labels are not hidden by global symbols"
module M {
    type enumerated Weekend {
        Saturday,
        Sunday, // error: hidden by global constant
    }

    const integer Sunday := 1;
}
```

```ttcn3 test="Verify enumerated labels are not hidden by local symbols"
module M {
    type enumerated Weekend {
        Saturday,
        Sunday, 
    }

    control {
        const integer Sunday := 1;
        var Weekend we; // error: hidden by local constant
    }
}
```

An enumerated value can occur in one of two forms: qualified or unqualified.
The unqualified form is permitted, if the type of the enumerated value can be
determined statically (see type-inference rules 0.0).

```ttcn3 test
    type enumerated Weekdays {
        Monday,
        Tuesday,
        Wednesday,
        Thursday,
        Friday,
        Saturday,
        Sunday,
    }

    type enumerated Weekend {
        Saturday,
        Sunday,
    }

    const Weekend we := Sunday; // ok: type is inferred from const declaration
    const we := Sunday; // error: ambigious type
    const boolean b := Saturday < Sunday // error: ambigious type
```

### `verdicttype`

The prefined type `verdicttype` shall be semantically equivalent to:

```ttcn3
type enumerated verdicttype {
    none   (0),
    pass   (1),
    inconc (2),
    fail   (3),
    error  (4)
}
```