Loading src/05-basic-language-elements.md +117 −79 Original line number Diff line number Diff line Loading @@ -2,114 +2,152 @@ ## General TTCN-3 Modules are used to structure a test suite into composable parts. A module may reuse other modules by importing them. This clause specifies the rules for naming, declaring, and referring to basic TTCN-3 language elements. It defines identifiers and keywords, the scopes and visibility of declarations, declaration ordering, and cyclic definitions. A module defines test components, communication ports, user-defined types, constants, test data templates, behaviour, etc. A TTCN-3 module groups declarations and may import declarations from other modules. Declarations introduce language elements such as types, constants, templates, components, ports, and behaviour. Statements specify behaviour, expressions compute values, and templates specify patterns for matching data. The type-system of TTCN-3 provides a rich set of predefined and user-defined types (i.e. maps, subtypes, etc.); including types specialized for testing (i.e. components, ports, etc.) In this document, the terms _definition_ and _declaration_ are synonymous. A special kind of data structure, called a _template_, provides a pattern matching mechanism for test-data. User-defined behaviour (i.e. functions, test cases, etc.) is specified by the use of program statements, such as `if-else` and `do-while`. Behaviour may also declare local variables and constants. The concept of global variables is not supported in TTCN-3. ## Identifiers and keywords A module control function calls test-cases and controls their execution. An _identifier_ is a sequence of one or more Latin letters, decimal digits, and underscores (`_`). Its first character shall be a letter or underscore. An identifier beginning with an underscore is reserved for tool-specific use. Expressions specify the computation of values for variables, constants, parameters, etc. ```ebnf Identifier ::= ( "A" … "Z" | "a" … "z" | "_" ) { "A" … "Z" | "a" … "z" | "_" | "0" … "9" }. ``` A name introduced by a TTCN-3 declaration shall be a valid identifier and shall satisfy the applicable scope and uniqueness rules below. Finally, meta-information, such as encoding information and user-defined attributes may be associated to most TTCN-3 language elements. A _keyword_ is a word that has special syntactic meaning in a particular context. A keyword shall be used as a name only in a construct that explicitly permits that use. For example, `testcase` introduces a testcase declaration but denotes the currently executing testcase in `testcase.stop`. > NOTE: The terms "definition" and "declaration" are used interchangeable > throughout the present document. A _reserved word_ is an identifier that shall not be used as a general user-defined name. Reserved words include names provided by TTCN-3 for predefined types, values, and operations; they need not have a distinct syntactic role. A reserved word may be used as a field identifier of a structured type where the grammar permits it. ## Scope rules ### General A scope unit is a region that associates a name with a TTCN-3 language element. Scope units may be nested and form a hierarchy with the _root scope_ as the root. The _root scope_ owns the predefined names, such as `integer` or `log`, and the module names. A _module scope_ owns the names of its definitions and imported names. - a name is visible, if there is a path from the name reference to the name definition > NOTE: Scopes are conceptional: This standard does not dictate a specific implementation; > it is left to the vendor how to implement scope rules. > NOTE: A TTCN-3 language element may have a name and a scope unit. For > example, a function has a name at least one scope unit for parameters and > locals. > NOTE: If a language object owns declarations, formal > parameters, type parameters or fields, then it has a scope, too. A _scope unit_ is a region that owns declarations and associates their names with TTCN-3 language elements. Scope units are nested and form a hierarchy rooted at the _root scope_. The root scope owns the predefined names and contains the module scopes. Each module introduces a _module scope_. It owns the declarations in the module definitions part, its module identifier, the identifiers of imported modules, and the names made available by imports. The module control part, component types, structured types, enumerated types, signatures, templates, testcases, functions, altsteps, methods, classes, statement blocks, and alternation blocks introduce nested scope units. Component members belong to their component-type scope, structured fields to their structured-type scope, enumerated values to their enumerated-type scope, signature parameters to their signature scope, and local declarations to their statement-block or alternation-block scope. Inherited members remain members of their declaring component-type or class scope but are also visible in the derived scope according to the applicable inheritance rules. A group declaration does not introduce a scope unit; declarations in a group belong to the surrounding module scope. A declaration is visible at a reference if its scope unit is the reference's scope unit or an enclosing scope unit on the same branch of the scope hierarchy, subject to declaration-order and import rules. Name lookup in a behaviour with a `runs on` clause also includes members of that component type, including inherited members. Name lookup in a component type or class also includes inherited members. Lexical scopes are searched from the innermost outwards before these associated or inherited scopes; any remaining collision shall be resolved as required by the applicable inheritance rules or by qualification. A qualified reference is resolved in the scope denoted by its qualifier. Every reference shall resolve to exactly one declaration. ### Scope of formal parameters The formal parameters of a declaration belong to that declaration's scope unit and are visible in its body. A default value or default template of a formal parameter is resolved in the context enclosing the formal-parameter scope and, where a `runs on` clause is present, may refer to members of that component type. It shall not refer to another formal parameter of the same declaration. ### Uniqueness of identifiers A names shall be a valid TTCN-3 identifier. Names owned by the same scope unit shall be unique, except that imports may make declarations with the same unqualified name available in a module scope. Except for a field identifier of a structured type, a declaration in a nested scope unit shall not reuse a name declared in an enclosing scope unit on the same branch of the scope hierarchy. Consequently, unqualified name resolution does not use shadowing or overloading to choose among declarations. A name shall be owned by exactly one scope unit. If imports make more than one declaration with the same unqualified name visible, that name shall not be referenced unqualified. It shall be qualified by the effective identifier of the imported module. If the module is imported under a different identifier, that identifier, rather than its original identifier, shall be used for qualification. - a name must be unique in its scope - a name reference must not be ambigious. - not shadowing - fields are okay - how about enums? - two execptions: - module definitions because import all and optional prefix - types, objects, ... Field identifiers of a structured type shall be unique within that type. They need not be unique relative to identifiers in enclosing scope units or fields of other structured types. Enumerated values shall be unique within their enumerated type. Within the same module, the identifier of an enumerated value may be reused only as an enumerated value of another enumerated type or as a field identifier of a structured type. ### Ordering of language elements - Generally, the order in which declarations can be made is arbitrary. - Inside a statement block or alternation block, however, a name shall not be used before it has been declared, - additional rules for enumerated types, fields for records and sets and formal parameters. ## Ordering of language elements - in statementblocks: not before declartation - in other scopes (compuents, objects, ...) topological ```ttcn3 module Example { const integer X := f(); const integer Y := 5; function f() return integer { return X; } } ``` Declarations in a module definitions part may occur in any order. A module declaration may therefore refer to another module declaration that occurs later. Within a component type, class, structured type, template, testcase, function, altstep, or method, a declaration outside a statement or alternation block that references another declaration in the same construct shall follow that declaration. ### Cyclic Definitions In a statement block or an alternation block, every declaration shall precede the statements and alternatives that use the declared name. Local variables, local constants, local timers, and other local declarations shall not be used before they are declared. A label is an exception: a `goto` statement may refer to a label that occurs later in the same permitted label scope. Direct and indirect cyclic defintions are not allowed with the exception of the following cases: A reference from a structured-field declaration to another field of the same type shall identify a preceding field declaration. A reference from an enumerated-value declaration to another value of the same enumerated type shall identify a preceding enumerated-value declaration. 0. for recursive type definitions of records (clause 0.0), sets (clause 0.0), unions (clause 0.0) 0. recursive behaviour of functions (clause 0.0), altsteps (clause 0.0) and methods (clause 0.0) 0. cyclic import dependencies (clause 0.0) A reference from the type, array dimensions, or another non-default part of a formal parameter declaration to another formal parameter in the same list shall identify a preceding formal parameter. A default value or default template shall not reference any formal parameter in the same list. ### Group scopes ## Cyclic definitions A group declaration is purely syntactical and does not have its own scope. See clause 0.0 for details. Direct and indirect cyclic definitions are prohibited, except for: ### Control scopes - recursive definitions of structured types where permitted by the applicable type rules; - recursive calls of functions, altsteps, and methods; and - cyclic import dependencies, provided that the imported declarations form only otherwise permitted cyclic definitions. ### Snapshot scopes A cycle shall be determined from references to declared identifiers, including references that cross module boundaries. A cycle of module imports is not by itself prohibited. src/16-declaring-dynamic-behaviour.md +744 −100 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/05-basic-language-elements.md +117 −79 Original line number Diff line number Diff line Loading @@ -2,114 +2,152 @@ ## General TTCN-3 Modules are used to structure a test suite into composable parts. A module may reuse other modules by importing them. This clause specifies the rules for naming, declaring, and referring to basic TTCN-3 language elements. It defines identifiers and keywords, the scopes and visibility of declarations, declaration ordering, and cyclic definitions. A module defines test components, communication ports, user-defined types, constants, test data templates, behaviour, etc. A TTCN-3 module groups declarations and may import declarations from other modules. Declarations introduce language elements such as types, constants, templates, components, ports, and behaviour. Statements specify behaviour, expressions compute values, and templates specify patterns for matching data. The type-system of TTCN-3 provides a rich set of predefined and user-defined types (i.e. maps, subtypes, etc.); including types specialized for testing (i.e. components, ports, etc.) In this document, the terms _definition_ and _declaration_ are synonymous. A special kind of data structure, called a _template_, provides a pattern matching mechanism for test-data. User-defined behaviour (i.e. functions, test cases, etc.) is specified by the use of program statements, such as `if-else` and `do-while`. Behaviour may also declare local variables and constants. The concept of global variables is not supported in TTCN-3. ## Identifiers and keywords A module control function calls test-cases and controls their execution. An _identifier_ is a sequence of one or more Latin letters, decimal digits, and underscores (`_`). Its first character shall be a letter or underscore. An identifier beginning with an underscore is reserved for tool-specific use. Expressions specify the computation of values for variables, constants, parameters, etc. ```ebnf Identifier ::= ( "A" … "Z" | "a" … "z" | "_" ) { "A" … "Z" | "a" … "z" | "_" | "0" … "9" }. ``` A name introduced by a TTCN-3 declaration shall be a valid identifier and shall satisfy the applicable scope and uniqueness rules below. Finally, meta-information, such as encoding information and user-defined attributes may be associated to most TTCN-3 language elements. A _keyword_ is a word that has special syntactic meaning in a particular context. A keyword shall be used as a name only in a construct that explicitly permits that use. For example, `testcase` introduces a testcase declaration but denotes the currently executing testcase in `testcase.stop`. > NOTE: The terms "definition" and "declaration" are used interchangeable > throughout the present document. A _reserved word_ is an identifier that shall not be used as a general user-defined name. Reserved words include names provided by TTCN-3 for predefined types, values, and operations; they need not have a distinct syntactic role. A reserved word may be used as a field identifier of a structured type where the grammar permits it. ## Scope rules ### General A scope unit is a region that associates a name with a TTCN-3 language element. Scope units may be nested and form a hierarchy with the _root scope_ as the root. The _root scope_ owns the predefined names, such as `integer` or `log`, and the module names. A _module scope_ owns the names of its definitions and imported names. - a name is visible, if there is a path from the name reference to the name definition > NOTE: Scopes are conceptional: This standard does not dictate a specific implementation; > it is left to the vendor how to implement scope rules. > NOTE: A TTCN-3 language element may have a name and a scope unit. For > example, a function has a name at least one scope unit for parameters and > locals. > NOTE: If a language object owns declarations, formal > parameters, type parameters or fields, then it has a scope, too. A _scope unit_ is a region that owns declarations and associates their names with TTCN-3 language elements. Scope units are nested and form a hierarchy rooted at the _root scope_. The root scope owns the predefined names and contains the module scopes. Each module introduces a _module scope_. It owns the declarations in the module definitions part, its module identifier, the identifiers of imported modules, and the names made available by imports. The module control part, component types, structured types, enumerated types, signatures, templates, testcases, functions, altsteps, methods, classes, statement blocks, and alternation blocks introduce nested scope units. Component members belong to their component-type scope, structured fields to their structured-type scope, enumerated values to their enumerated-type scope, signature parameters to their signature scope, and local declarations to their statement-block or alternation-block scope. Inherited members remain members of their declaring component-type or class scope but are also visible in the derived scope according to the applicable inheritance rules. A group declaration does not introduce a scope unit; declarations in a group belong to the surrounding module scope. A declaration is visible at a reference if its scope unit is the reference's scope unit or an enclosing scope unit on the same branch of the scope hierarchy, subject to declaration-order and import rules. Name lookup in a behaviour with a `runs on` clause also includes members of that component type, including inherited members. Name lookup in a component type or class also includes inherited members. Lexical scopes are searched from the innermost outwards before these associated or inherited scopes; any remaining collision shall be resolved as required by the applicable inheritance rules or by qualification. A qualified reference is resolved in the scope denoted by its qualifier. Every reference shall resolve to exactly one declaration. ### Scope of formal parameters The formal parameters of a declaration belong to that declaration's scope unit and are visible in its body. A default value or default template of a formal parameter is resolved in the context enclosing the formal-parameter scope and, where a `runs on` clause is present, may refer to members of that component type. It shall not refer to another formal parameter of the same declaration. ### Uniqueness of identifiers A names shall be a valid TTCN-3 identifier. Names owned by the same scope unit shall be unique, except that imports may make declarations with the same unqualified name available in a module scope. Except for a field identifier of a structured type, a declaration in a nested scope unit shall not reuse a name declared in an enclosing scope unit on the same branch of the scope hierarchy. Consequently, unqualified name resolution does not use shadowing or overloading to choose among declarations. A name shall be owned by exactly one scope unit. If imports make more than one declaration with the same unqualified name visible, that name shall not be referenced unqualified. It shall be qualified by the effective identifier of the imported module. If the module is imported under a different identifier, that identifier, rather than its original identifier, shall be used for qualification. - a name must be unique in its scope - a name reference must not be ambigious. - not shadowing - fields are okay - how about enums? - two execptions: - module definitions because import all and optional prefix - types, objects, ... Field identifiers of a structured type shall be unique within that type. They need not be unique relative to identifiers in enclosing scope units or fields of other structured types. Enumerated values shall be unique within their enumerated type. Within the same module, the identifier of an enumerated value may be reused only as an enumerated value of another enumerated type or as a field identifier of a structured type. ### Ordering of language elements - Generally, the order in which declarations can be made is arbitrary. - Inside a statement block or alternation block, however, a name shall not be used before it has been declared, - additional rules for enumerated types, fields for records and sets and formal parameters. ## Ordering of language elements - in statementblocks: not before declartation - in other scopes (compuents, objects, ...) topological ```ttcn3 module Example { const integer X := f(); const integer Y := 5; function f() return integer { return X; } } ``` Declarations in a module definitions part may occur in any order. A module declaration may therefore refer to another module declaration that occurs later. Within a component type, class, structured type, template, testcase, function, altstep, or method, a declaration outside a statement or alternation block that references another declaration in the same construct shall follow that declaration. ### Cyclic Definitions In a statement block or an alternation block, every declaration shall precede the statements and alternatives that use the declared name. Local variables, local constants, local timers, and other local declarations shall not be used before they are declared. A label is an exception: a `goto` statement may refer to a label that occurs later in the same permitted label scope. Direct and indirect cyclic defintions are not allowed with the exception of the following cases: A reference from a structured-field declaration to another field of the same type shall identify a preceding field declaration. A reference from an enumerated-value declaration to another value of the same enumerated type shall identify a preceding enumerated-value declaration. 0. for recursive type definitions of records (clause 0.0), sets (clause 0.0), unions (clause 0.0) 0. recursive behaviour of functions (clause 0.0), altsteps (clause 0.0) and methods (clause 0.0) 0. cyclic import dependencies (clause 0.0) A reference from the type, array dimensions, or another non-default part of a formal parameter declaration to another formal parameter in the same list shall identify a preceding formal parameter. A default value or default template shall not reference any formal parameter in the same list. ### Group scopes ## Cyclic definitions A group declaration is purely syntactical and does not have its own scope. See clause 0.0 for details. Direct and indirect cyclic definitions are prohibited, except for: ### Control scopes - recursive definitions of structured types where permitted by the applicable type rules; - recursive calls of functions, altsteps, and methods; and - cyclic import dependencies, provided that the imported declarations form only otherwise permitted cyclic definitions. ### Snapshot scopes A cycle shall be determined from references to declared identifiers, including references that cross module boundaries. A cycle of module imports is not by itself prohibited.
src/16-declaring-dynamic-behaviour.md +744 −100 File changed.Preview size limit exceeded, changes collapsed. Show changes