Loading src/03-terms-and-references.md +0 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,5 @@ Value, concrete Value, template : Reference : src/06-types-and-values.md +4 −4 Original line number Diff line number Diff line Loading @@ -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** Loading src/10-declaring-variables.md +110 −66 Original line number Diff line number Diff line Loading @@ -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]. Loading @@ -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: Loading @@ -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 ``` src/11-declaring-module-parameters.md +1 −1 Original line number Diff line number Diff line Loading @@ -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** Loading src/12-declaring-constants.md +1 −1 Original line number Diff line number Diff line Loading @@ -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
src/03-terms-and-references.md +0 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,5 @@ Value, concrete Value, template : Reference :
src/06-types-and-values.md +4 −4 Original line number Diff line number Diff line Loading @@ -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** Loading
src/10-declaring-variables.md +110 −66 Original line number Diff line number Diff line Loading @@ -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]. Loading @@ -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: Loading @@ -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 ```
src/11-declaring-module-parameters.md +1 −1 Original line number Diff line number Diff line Loading @@ -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** Loading
src/12-declaring-constants.md +1 −1 Original line number Diff line number Diff line Loading @@ -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**