Commit c9ceaf56 authored by Matthias Simon's avatar Matthias Simon
Browse files

Fix grammar, flesh out some text

parent d57bbcb6
Loading
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -15,6 +15,5 @@ Value, concrete
Value, template
:


Reference
:
+4 −4
Original line number Diff line number Diff line
@@ -162,10 +162,10 @@ x \brem |y| & \text{when } x \geq 0 \\
**Syntactical Structure**

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

**Semantic Description**
+110 −66
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@

A variable is a named memory location to store the value of a given type.

**Syntactic Structure**
**Syntactical Structure**

```ebnf
VarDecl ::= "var" [TypeExpr] Declarator { "," Declarator} [With].
@@ -12,53 +12,43 @@ Declarator ::= name {"[" integer "]"} [":=" Expr].
**Semantic Description**

A _variable declaration_ adds a new variable with given _name_ into its
enclosing scope.
The scoping rules for variables are specified in clause 0.0.
enclosing scope (see [uniqueness of identifiers]).

A variable shall only be declared in scopes where permitted explicitly, i.e.
[statement blocks], [component type definitions], etc.
A variable shall only be declared in scopes where permitted explicitly.

> NOTE: For example, a variable may be declared in component type definition, but
> not at module scope. In which scope a variable can be declared is specified in
> the respective chapters.

Each variable has a static type associated with it.
The type of the variable is specified using a _type expression_
The type of the variable is specified using a _[type expression]_
and shall not change during its [lifetime].

 ```ttcn3
 function f(in integer n) {
     var integer a[n]; // type of a is static during its lifetime.
 }
 f(3)
 f(10)
 ```

> NOTE: How types depending on runtime values or how nested types are
> NOTE: How types that depend on runtime values or on nested types are
> implemented is vendor specific. For example, it is not required to create a
> new type object for every function call as long as TTCN-3 semantics
> are not violated.

The _type expression_ may be omitted if each variable has an _initial value
expression_ with a type that can be inferred statically and unambiguously (see
inference rules for expressions in clause 0.0). The type of the
variable shall be the equal to type of the _initial value expression_.

```ttcn3 test
var int a;
var b := a;               // typeof(b) == typeof(a) and typeof(b) == "int"
var r := {1,2,3};         // typeof(r) == "record of integer"
var i := 0, s := "hello"; // typeof(i) == "integer" and typeof(s) == string
var t1 := integer:?       // typeof(t1) == "template integer"
var t2 := ?; // error: ambigous type
```
The _type expression_ may be omitted if the variable has an _initial value
assignment_ with a type that can be [inferred statically](inference rules)
and unambiguously.

The inferred type of the variable shall be the equal to type of the _initial
value expression_.


The array notion shall not be used when the _type expression_ is omitted.

```ttcn3 example
var a[3] := {1,2,3}; // error: not allowed.
```

<!-- TODO: Discuss if `var template a := (1..10)` is still permitted. The standard becomes simpler if not -->
> NOTE: The syntax how variable templates have been declared has changed since
> this major release:
> `var template a := (1..10)` is now written as inline
> template: `var a := integer:(1..10)`.

> NOTE: This implicit type inference can be implemented as syntax transformation:
> `var a := {1,2,3}` becomes `var typeof({1,2,3}) a := {1,2,3}`, which becomes
> `var record of integer a := {1,2,3}`.
> NOTE: Automatic type inference, sufficient for most use-cases, can be
> implemented as syntax transformation, during semantic checking:
> `var a := {1,2,3}` becomes `var typeof({1,2,3}) a := {1,2,3}`,
> which becomes `var record of integer a := {1,2,3}`.


Every variable that comes into scope shall have an initial value depending on its type:
@@ -67,54 +57,108 @@ Every variable that comes into scope shall have an initial value depending on it
- the initial value of a variable of a verdict type shall be `none`.
- the initial value of any other value type variable shall be [uninitialized].

A variable declaration may also have an explicit _initial value assignment_.

A variable declaration may also have an user-defined _initial value assignment_.
This assignment is semantically equivalent to a separate assignment statement,
as described in [the assignment statement].
as described in the [assignment statement].

The following two examples are semantically equivalent:
> NOTE: type compatibility rules and the expected behaviour, if the evaluation
> fails is also specified in the [assignment statement].

```ttcn3
var integer i := 0;
```
The moment when this assignment is executed depends on the scope the variable
is defined in:

```ttcn3
var integer i;
i := 0
```
- _Initial value assignment_ of variables that are declared in [statement
  blocks] is evaluated at the place of the declaration. This includes variable
  declared as part of an [initialization statement].

If the initial value assignment could not succeed,
the variable keeps its initial value as described earlier:
- _Initial value assignment_ in variables that are declared in scopes that
  allow [use before declaration] (e.g. component type declarations) may be
  deferred to a later moment, but at latest until its first use. See [ordering
  of lanugage elements] for details.

```ttcn3
var float f := 1/0; // value of f stays uninitialized, since the expression `1/0`
                    // failed and the assignment operation did not succeed.
```
A variable may be declared as array by using the [array short-hand notation].

The expression of the _initial value assignment_ in variables that are declared
in [statement blocks] is evaluated at the place of the declaration. This
includes variable declared as part of [an initialization statement].
Multiple variables may be declared using a single variable declaration.
In this case the _type expression_ specifies the type for all variables.
If the _type expression_ is ommited all variable shall have an _initial value
assignment_.

The expression of the _initial value assignment_ in variables that are declared
in scopes that allow [use before declaration] (e.g. inside component type
declarations) may be deferred to a later moment, but at least until its first use.
A variable is _[addressable]_. That means it may be used as [call by
reference] parameter or on the right hand side of an [assignment statement].

The current value of a variable is read from memory, when the variable name is
used in an [expression].

> NOTE: Optimisation (loop-unrolling, extreaction, macros, ...)
> NOTE: Vendor-specific optimizations are permitted. For example if a variable
> has a constant or deterministic initial value a tool may evaluate the
> expression during compile time or even replace the variable with a macro,
> when possible.

**Examples**

 ```ttcn3 example = "static type during lifetime"
 function f(in integer n) {
     var integer a[n]; // the type of a has a different length resitriction
                       // every call, but it static during its lifetime.
 }

- evaluation order
 control {
     f(3)
     f(10)
 }
 ```

- addressing/references
- it is recommended to at least throw a warning or even error when non-deterministic functions are used
```ttcn3 example = "ambigous type"
var t := ? // error: ambigous type
```

```ttcn3 example = "inferred template type"
var t := integer:? // expect: typeof(t) == "template integer"
```

> NOTE: It is left 
```ttcn3 example = "inferred record of integer"
var a := {1,2,3} // expect: typeof(a) == "record of integer"
```

```ttcn3 example = "parametric inferrence"
var s  := substr("hello", 0, 1);   // expect: typeof(s)  == "string"
var bs := substr('1100101', 0, 1); // expect: typeof(bs) == "bitstring"
```

- shorthand array-notation
```ttcn3 example = "inferred type is equal"
var int a;  // expect: typeof(a) == "int"
var b := a; // expect: typeof(b) == "int"
```
```ttcn3 example = "array notation is prohibited"
var a[3] := {1,2,3}; // error: not allowed.
```
```ttcn3 example = "initial values"
var default d;     // expect: d == null
var verdicttype v; // expect: v == none
var integer i;     // expect: isbound(i) == false
```
```ttcn3 example
var integer i := 0, a[3] := {1,2,3};
var float f := 1/0; // value of f stays uninitialized, since the expression `1/0`
                    // failed and the assignment operation did not succeed.
```
```ttcn3 example = "array notation"
var integer a[10][2];
  // expect: typeof(a) = "record length(10) of record length(2) of integer"
```
```ttcn3 example = "multiple variable"
var integer i := 0, j := i, a[3] := {1,2,3}
  // expect: typeof(i) == "integer" and i == 0
  // expect: typeof(j) == "integer" and j == 0
  // expect: typeof(a) == "record of integer"
```
- shorthand timers
- multiple variable declarations

```
var integer i, j := 0
  // expect: typeof(i) == "integer" and not isbound(i)
  // expect: typeof(j) == "integer" and j == 0
```

```ttcn3 example = "missing type expression or missing initial value assignment"
var i, j := 0 // error: incomplete variable declaration for i
```
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ A module parameter is a variable that can be assigned a value only once per test
**Syntactic Structure**

```ebnf
ModuleparDecl = "modulepar" [TypeExpr] Declarator { "," Declarator} [With].
ModuleparDecl ::= "modulepar" [TypeExpr] Declarator { "," Declarator} [With].
```

**Semantic Description**
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ A constant is a variable that can be assigned a value only once per test executi
**Syntactic Structure**

```ebnf
ConstDecl = "const" [TypeExpr] Declarator { "," Declarator} [With].
ConstDecl ::= "const" [TypeExpr] Declarator { "," Declarator} [With].
```

**Semantic Description**
Loading