Datatype Editor/en: Unterschied zwischen den Versionen

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen
 
(48 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 2: Zeile 2:
[[Datatype Element | Datatypes]] are attached to pins and environment variables, and usually presented by name in a datatype definition pull-down menu.
[[Datatype Element | Datatypes]] are attached to pins and environment variables, and usually presented by name in a datatype definition pull-down menu.
There are both builtin (hardwired) and user defined data types in expecco.
There are both builtin (hardwired) and user defined data types in expecco.
User defined datatypes are shown in those pull-down lists at the bottom of the menu.
User defined datatypes are shown in those pull-down lists in a separate submenu of the type menu.


This editor is used to define new [[Datatype Element | datatypes]]; builtin types cannot be modified.
This editor is used to define new [[Datatype Element | datatypes]].<br>Builtin types cannot be modified.

==Type Kinds==
The ''kind'' specifies the kind of type and '''how''' it is defined. For example, there are vector types, enum types, struct types etc. These are described in more detail below.


There are multiple '''conceptional''' ways to define a new datatype:
There are multiple '''conceptional''' ways to define a new datatype:
* by enumerating its elements (i.e. a set of values)
* as a subtype of an existing type (enum, range types)
* as a subtype of an existing type (enum, range types)
* by combining elements of existing types (tuple, array, structure or union types)
* by combining elements of existing types (tuple, array, structure or union types)
Zeile 20: Zeile 24:


To define a type, first create a new datatype tree item, then choose an appropriate representation in the editor's "''Type-Kind''" list. A template showing the syntax of this type will be shown.
To define a type, first create a new datatype tree item, then choose an appropriate representation in the editor's "''Type-Kind''" list. A template showing the syntax of this type will be shown.

Change the template and press "''Accept''" to install the type. The second tab in the editor labeled "''Type Description''" shows the type's definition in expecco's internal type description language, which is usually only of interest to validate a type's correctness if an alien format was used to import a type definition. This format is described [[ #Formal BNF Description of the Expecco Type Syntax | below ]].
Change the template and press "''Accept''" to install the type. The second tab in the editor labeled "''Type Description''" shows the type's definition in expecco's internal type description language, which is usually only of interest to validate a type's correctness if an alien format was used to import a type definition. This format is described [[ #Formal BNF Description of the Expecco Type Syntax | below ]].




[[Datei:typeEditor1.png|800px|Datatype Editor]]
[[Datei:typeEditor1.png|600px|Datatype Editor]]


==Type Kinds (Semantic)==
==Type Kinds (Semantic)==
Zeile 59: Zeile 64:
</PRE>
</PRE>
The last example uses quotes around the element names, as these contain a special (non-alphanumeric) character.
The last example uses quotes around the element names, as these contain a special (non-alphanumeric) character.
===== Enum in Input Dialogs =====

When used as a freeze value or environment variable value, a combo list presenting only the valid enum elements is shown. By default, the values are sorted alphabetically in one single list. If your type consists of a large number of values, you may want to specify a grouping scheme. For example, the last of the above examples could be presented as either a single list with 5 items, or as a 2-item list ('foo' and 'bar') with submenus for each prefix.
When used as a freeze value or environment variable value, a combo list presenting only the valid enum elements is shown. By default, the values are sorted alphabetically in one single list. If your type consists of a large number of values, you may want to specify a grouping scheme.
[[Datei:Datatype enumOrder.png|mini]]

For example, the last of the above examples could be presented as either a single list with 5 items, or as a 2-item list ('foo' and 'bar') with submenus for each prefix. The menu/combolist grouping is specified in the datatype editor (at the bottom right of the editor).
===== Numeric Value of an Enum =====
Enum values can have an associated integer value, which is useful, if the type is actually a mapping of a corresponding C or Java type.<br>For this, add an "<code>= <integerValue></code>" after the element's name to the above definition. I.e.:
Enum values can have an associated integer value, which is useful, if the type is actually a mapping of a corresponding C or Java type.<br>For this, add an "<code>= <integerValue></code>" after the element's name to the above definition. I.e.:
<PRE>
<PRE>
Zeile 72: Zeile 79:
the next value from the previous enum element.
the next value from the previous enum element.


Be aware that the enum-values are always string-like objects (actually: instances of Smalltalk's <code>Symbol</code> class. Thus, although the elements look like integers in a definition like "<code>(1 | 2 | 3)</code>", they are actually string like. Consider using a subrange or subset type, as described below, if you need integer values.
Be aware that the enum-values are always string-like objects (actually: instances of Smalltalk's <code>Symbol</code> class). Thus, although the elements look like integers in a definition like "<code>(1 | 2 | 3)</code>", they are actually string like with an associated integer. Consider using a subrange or subset type, as described below, if you need integer values.


===== Enum Definition pasted from a C-Header File =====
New in 18.2:<br>
New in 18.2:<br>
In addition to the above definition format, enum types can also be defined as a list of C-define directives.
In addition to the above definition format, enum types can also be defined as a list of C-define directives.
Zeile 103: Zeile 111:


[[Datei:point_right.png|20px]] Notice the dollar prefix, which designates a character constant.
[[Datei:point_right.png|20px]] Notice the dollar prefix, which designates a character constant.

===Pattern Types===
(new with expecco 21.2)<br>
A constraint subset of <code>String</code> values. Constraint may be that the string matches
a glob or regex pattern, and/or that its size (number of characters) is within some limits.

For example, a type for strings not longer than 10 characters could be defined as:
<PRE>
String( maxLength: 10 )
</PRE>

A type for a string which starts with a letter can be defined as ([https://en.wikipedia.org/wiki/Glob_(programming) GLOB] pattern):
<PRE>
String( match: '[a-z]*')
</PRE>

or alternatively, using a [https://en.wikipedia.org/wiki/Regular_expression Regex] (instead of a GLOB pattern) as:
<PRE>
String( regex: '[a-z].*')
</PRE>

The constraint can be one of:
* minLength: <n>
:the string must consist of at least <n> characters
* maxLength: <n>
:may not be longer than <n> characters
* match: '<glob pattern>'
: the strings must match the [https://en.wikipedia.org/wiki/Glob_(programming) GLOB] pattern
* regex: '<pattern>'
: must match the [https://en.wikipedia.org/wiki/Regular_expression Regex] pattern

[[Datei:point_right.png|20px]] Be aware of the difference between GLOB and Regex patterns.


===Array Types===
===Array Types===
Zeile 180: Zeile 220:
==== Getters ====
==== Getters ====
In elementary code blocks, field values of an instance are accessed via getter calls which are named like the field.
In elementary code blocks, field values of an instance are accessed via getter calls which are named like the field.
<br>For example, given an instance of the above named "<code>c</code>", the ''lastName'' field can be fetched with "<code>c lastName</code>" (in Smalltalk) or "<code>c.lastName</code>" (in JavaScript).
<br>For example, given an instance of the above named "<code>c</code>", the "''lastName''" field can be fetched in Smalltalk code with any of:
c lastName "/ calling the getter
<br>Or alternatively, using the dictionary protocol as "<code>c at:'lastName'</code>" (Smalltalk) or "<code>c['lastName']</code>" (JavaScript).
c at:'lastName' "/ using collection protocol
c['lastName'] "/ using collection protocol
or in JavaScript code with:
c.lastName() // calling the getter
c.lastName // (virtual) slot access
c['lastName'] // using collection protocol
c["lastName"] // using collection protocol


==== Setters ====
==== Setters ====
Elementary code can change a field's value via setter calls.
Elementary code can change a field's value via setter calls.
<br>For the above example, these would be "<code>c lastName:<I>newValue</i></code>" (Smalltalk)
<br>For the above example, these would be in Smalltalk:
and "<code>c.lastName(<I>newValue</I>)</code>" (JavaScript).
c lastName:<I>newValue</i>
<br>Also the dictionary protocol can be used: "<code>c at:'lastName' put:<I>newValue</I></code>" or "<code>c['lastName'] = <I>newValue</I></code>"
c at:'lastName' put:<I>newValue</i>
c['lastName'] := <I>newValue</i>
and in JavaScript:
c.lastName(<I>newValue</I>)
c['lastName'] := <I>newValue</i>


==== Generating Action Blocks to Access Fields ====
==== Generating Action Blocks to Access Fields and Create Instances ====
[[Datei:CompoundCreateActions.png|mini]]
The tree-item menu of a compound type contains entries to generate field-setter, field getter and creation actions.
[[Datei:CompoundCreateActions2.png|mini]]
The tree-item menu of a compound type contains entries to generate field-setter, field getter and creation actions (under "''Refactoring''" - "''Generate''").
&nbsp;

&nbsp;

&nbsp;

&nbsp;

After that, you'll find actions to create an instance, to extract fields and to set fields.

These are elementary actions, which use the above listed getter/setter calls. They can of course be further modified if additional checks or processing is needed.


===Union Types===
===Union Types===
Zeile 218: Zeile 282:


==== Constraint Datatype Type ====
==== Constraint Datatype Type ====
Starting with expecco 2.8, a datatype type can be constraint to a subset of types, by defining it as:
A datatype type can be constraint to a subset of types, by defining it as:
datatype ( <constraint> )
datatype ( <constraint> )
where constraint a selector from one of:
where <constraint> is either the name of another type:
* isArrayType - for types which have integer-indexable slots
* <compatTypeName> - constraint to types which are compatible with a type named <compatTypeName>
or a selector from one of:
* isCTypeType - for C-defined types
* isCEnumType - for C enum types (18.1 aka 2.12)
* <code>isArrayType</code> - for types which have integer-indexable slots
* isCStructType - for C-defined struct types (18.1)
* <code>isCTypeType</code> - for C-defined types
* isCUnionType - for C-defined union types (18.1)
* <code>isCEnumType</code> - for C enum types
* <code>isCStructType</code> - for C-defined struct types
* isCollectionPrimaryType - for subtypes of Collection (i.e. Dictionary, Set, OrderedCollection etc.)
* isCompoundType - for compound types
* <code>isCUnionType</code> - for C-defined union types
* <code>isCollectionPrimaryType</code> - for subtypes of Collection (i.e. Dictionary, Set, OrderedCollection etc.)
* isEnumType - for enum types
* <code>isCompoundType</code> - for compound types
* isNumberPrimaryType - for subtypes of Number (i.e. Float, Integer, Fraction, FixedPoint)
* isPrimaryType - for any primary type
* <code>isEnumType</code> - for enum types
* isStreamPrimaryType - for subtypes of Stream
* <code>isNumberPrimaryType</code> - for subtypes of Number (i.e. Float, Integer, Fraction, FixedPoint)
* isTupleType - for any tuple type
* <code>isPrimaryType</code> - for any primary type
* <code>isStreamPrimaryType</code> - for subtypes of Stream
* isUnionType - for any union type
* <code>isTupleType</code> - for any tuple type
* isUserDefinedDatatype - for all user defined types
* isWellKnownDatatype - for all builtin (i.e. not user defined) type
* <code>isUnionType</code> - for any union type
* <code>isUserDefinedDatatype</code> - for all user defined types (i.e. those in the current suite)
* <code>isWellKnownDatatype</code> - for all builtin (i.e. not user defined) types. These types will always be present, whereas user defined types are those defined in the current suite


or a selector plus string argument from one of (expecco vsn >= 18.1):
or a selector plus string argument from one of:
* nameMatches: 'globPattern'
* <code>nameMatches:</code> ''globPattern''
* nameMatchesRegex: 'regexPattern'
* <code>nameMatchesRegex:</code> ''regexPattern''


Constrained datatypes should be used by the StandardLibraries only, and are used to limit the input values of some instance creation actions.
Constrained datatypes should be used by the StandardLibraries only, and are used to limit the input values of some instance creation actions.
Zeile 250: Zeile 316:
datatype ( isCStructType ) -- a type representing all known C struct types
datatype ( isCStructType ) -- a type representing all known C struct types
datatype ( nameMatches: 'DPU*' ) -- a type representing all types which match this name
datatype ( nameMatches: 'DPU*' ) -- a type representing all types which match this name

Notice that the freeze value of a datatype-typed pin (and also values flowing in and out of such pins) are data types; not values (although datatypes are also objects/values in the technical sense).


==== Monitor Types ====
==== Monitor Types ====
Zeile 259: Zeile 327:
==== Port Types ====
==== Port Types ====
These are not yet used but present for future TTCN3 support.
These are not yet used but present for future TTCN3 support.

==Type Popup-Menu Organisation==
In addition to the definition of the type, the editor provides control on
where and how the type will be presented in type popup menus and pull down lists.
===Group===
If you attach a group name to the type, it will be grouped into a such-named submenu below a pin's or variable's datatype popup menu.

===Enum Freeze-Value Menu Organisation===
When freezing an enum-typed pin or choosing an enum variable's default value,
by default the elements are presented in one list. This list may get long and you may want to organize them into a hierarchical set of submenus and/or control how they are sorted.

For example, if the enum elements represent commands to a controller, they might be named after commands, like "power_on", "power_off", "power_low", "turn_left", "turn_right" etc.
<br>In this case, you may want to organize the freeze menu into two submenus, one for all "power_XXX" values, another for all "turn_XXX"values etc.

The editor's "''Freeze Menu Organization''" at the lower right gives you a number of options to organize your menus and how to sort the elements. Use that, if you have more than (say) 10 or 15 elements in an enum. Click on the "''Test''" button to see how the menu will be shown later.
=====Sort Order=====
By default, elements will be presented in the order of the type definition.
<br>The choices are:
* normal - use the default sort order
* sortAlphabetical - sort by name
* sortNatural - numeric suffixes are sorted by value (i.e. 'a10' comes after 'a2')
* sortByValue - sort by the associated value; not the symbolic name
=====Hierarchical Menu=====
The other options control where the symbolic names are split and grouped into submenus.


==Type Representation (Syntax)==
==Type Representation (Syntax)==
Zeile 270: Zeile 362:


type ::= <nonArrayType> | <arrayType>
type ::= <nonArrayType> | <arrayType>

arrayType ::= <nonArrayType> '[' ']'
arrayType ::= <nonArrayType> '[' ']'

nonArrayType ::= <tupleType> | <unionType> | <compoundType>
nonArrayType ::= <tupleType> | <unionType> | <compoundType>
| <enumType> | <rangeType>
| <enumType> | <rangeType> | <patternType>
| <primaryType> | <simpleType> | <specialType>
| <primaryType> | <simpleType> | <specialType>

tupleType ::= '[' <elementType1> [','] <elementType2> .. <elementTypeN> ']'
tupleType ::= '[' <elementType1> [','] <elementType2> .. <elementTypeN> ']'
elementType ::= <type>
elementType ::= <type>

unionType ::= '(' <alternativeType1> '|' <alternativeType2 > '|' .. <alternativeTypeN> ')'
unionType ::= '(' <alternativeType1> '|' <alternativeType2 > '|' .. <alternativeTypeN> ')'
alternativeType ::= <type>
alternativeType ::= <type>

enumType ::= 'enum' '(' <enumValue1> '|' <enumValue2> '|' ... <enumValueN> ')'
enumType ::= 'enum' '(' <enumValue1> '|' <enumValue2> '|' ... <enumValueN> ')'
enumValue ::= ( <identifier> | <quoted-string> | <dquoted-string> ) [ '=' <integer-constant> ]
enumValue ::= ( <identifier> | <quoted-string> | <dquoted-string> ) [ '=' <integer-constant> ]

rangeType ::= 'range' '(' <baseType> ':' <minValue> '..' <maxValue> ')'
rangeType ::= 'range' '(' <baseType> ':' <minValue> '..' <maxValue> ')'
minValue ::= <constant>
minValue ::= <constant>
maxValue ::= <constant>
maxValue ::= <constant>

subsetType ::= 'subset' '(' <baseType> ':' <range1> [',' <range2>]... ')'
subsetType ::= 'subset' '(' <baseType> ':' <range1> [',' <range2>]... ')'
range ::= <minValue> '..' <maxValue> | <constant>
range ::= <minValue> '..' <maxValue> | <constant>

patternType ::= 'String' '(' <patternConstraint> [ ',' <patternConstraint> ]... ')'
patternConstraint ::= 'match:' <stringConstant>
| 'regex:' <stringConstant>
| 'minLength:' <integerConstant>
| 'maxLength:' <stringConstant>
compoundType ::= '{' <fieldSpec1> <fieldSpec2> ... <fieldSpecN> '}'
compoundType ::= '{' <fieldSpec1> <fieldSpec2> ... <fieldSpecN> '}'

fieldSpec ::= <fieldIdentifier> ':' <fieldType> [ '=' <defaultValue> ] [';']
fieldSpec ::= <fieldIdentifier> ':' <fieldType> [ '=' <defaultValue> ] [';']
fieldType ::= <type>
fieldType ::= <type>

primaryType ::= '<' <BuiltIn-Classname> '>'
primaryType ::= '<' <BuiltIn-Classname> '>'
BuiltIn-Classname ::= <identifier>
BuiltIn-Classname ::= <identifier>

simpleType ::= <anyType> | <templateType> | <constraintTemplateType> | <namedType>
simpleType ::= <anyType> | <templateType> | <constraintTemplateType> | <namedType>

anyType ::= '*'
anyType ::= '*'

templateType ::= '#' <templateIdentifier>
templateType ::= '#' <templateIdentifier>
constraintTemplateType ::= '#' <templateIdentifier> <setOfConstraintTypes>
constraintTemplateType ::= '#' <templateIdentifier> <setOfConstraintTypes>
setOfConstraintTypes ::= <unionType>
setOfConstraintTypes ::= <unionType>

<namedType> ::= 'any' | 'struct' | <typeName_in_project> | <Smalltalk-Classname>
<namedType> ::= 'any' | 'struct' | <typeName_in_project> | <Smalltalk-Classname>
typeName_in_project ::= <identifier>
typeName_in_project ::= <identifier>

specialType ::= <monitorType> | <portType> | <datatypeType> | <performerType>
specialType ::= <monitorType> | <portType> | <datatypeType> | <performerType>

monitorType ::= 'monitor' '(' <baseType>')'
monitorType ::= 'monitor' '(' <baseType>')'

portType ::= 'port' '(' <baseType>')'
portType ::= 'port' '(' <baseType>')'

datatypeType ::= 'datatype' [ '(' <constraint> ')' ]
datatypeType ::= 'datatype' [ '(' <constraint> ')' ]

constraint ::= 'isUserDefinedType' | 'isWellKnownType' |
constraint ::= <primaryTypeName> |
'isUserDefinedType' | 'isWellKnownType' |
'isPrimaryType' |
'isPrimaryType' |
'isNumberPrimaryType' | 'isCollectionPrimaryType' | 'isStreamPrimaryType'
'isNumberPrimaryType' | 'isCollectionPrimaryType' | 'isStreamPrimaryType'
'isArrayType' | 'isCTypeType'
'isArrayType' | 'isCTypeType'
'isCompoundType' | 'isEnumType' | 'isTupleType' | 'isUnionType'
'isCompoundType' | 'isEnumType' | 'isTupleType' | 'isUnionType'

performerType ::= 'performer' [ '(' interfaceSpec ')' ]
performerType ::= 'performer' [ '(' interfaceSpec ')' ]

interfaceSpec ::= <identifier> |
interfaceSpec ::= <identifier> |
'"' id-string '"'' |
'"' id-string '"'' |
Zeile 334: Zeile 433:


Notes:<br>
Notes:<br>
The separating commas in the tuple- and compound definitions are optional (vsn 2.1).
The separating commas in the tuple- and compound definitions are optional.
<br>The "struct" named type is only supported by vsn 2.1 and newer.
<br>Constraint datatypes are only supported in vsn 2.8 and newer.
<br>This format is used if you select "Defined" type in the editor. It is also expected if you select "Define..." in one of the type menus (Pin-Type, Veriable-Type, Skill-Type).
<br>This format is used if you select "Defined" type in the editor. It is also expected if you select "Define..." in one of the type menus (Pin-Type, Veriable-Type, Skill-Type).
Support for this representation is part of the base expecco system.
Support for this representation is part of the base expecco system.
Zeile 350: Zeile 447:


A typical C language definition looks like:
A typical C language definition looks like:
/* C: */

struct {
struct {
int i1;
int i1;
Zeile 357: Zeile 454:
char c[20];
char c[20];
};
};
Notice, that the definition must begin with a "/* C: */" comment.


For more details, please refer to the [[ Datatype_Element/en#CTypes | Datatype - CTypes document ]].
For more details, please refer to the [[ Datatype_Element/en#CTypes | Datatype - CTypes document ]].


===Enum Type Definition from C-define Directives===
===Enum Type Definition from C-define Directives===
Starting with expecco 18.2, an enum type can also be defined from a list of C-#define directives. These can be conveniently copy-pasted from a C-header file.
An enum type can also be defined from a list of C-#define directives. These can be conveniently copy-pasted from a C-header file.
For this, choose "''Enum (from C-defines)''", and paste the defines into the text area.
For this, choose "''Enum (from C-defines)''", and paste the defines into the text area.
Support for this representation is part of the base expecco system.
Support for this representation is part of the base expecco system.
Zeile 403: Zeile 501:
This is only available as plugin. Please read the corresponding plugin documentation for details.
This is only available as plugin. Please read the corresponding plugin documentation for details.


==See Also==
[[Datatype Element/en|Datatype Element]]


<!-- {{Languages}} -->
<!-- {{Languages}} -->
[[Category:Editors]] with more detail on primitive types and C-data types
[[Category:Languages]]

Aktuelle Version vom 11. März 2022, 08:18 Uhr

Introduction[Bearbeiten]

Datatypes are attached to pins and environment variables, and usually presented by name in a datatype definition pull-down menu. There are both builtin (hardwired) and user defined data types in expecco. User defined datatypes are shown in those pull-down lists in a separate submenu of the type menu.

This editor is used to define new datatypes.
Builtin types cannot be modified.

Type Kinds[Bearbeiten]

The kind specifies the kind of type and how it is defined. For example, there are vector types, enum types, struct types etc. These are described in more detail below.

There are multiple conceptional ways to define a new datatype:

  • by enumerating its elements (i.e. a set of values)
  • as a subtype of an existing type (enum, range types)
  • by combining elements of existing types (tuple, array, structure or union types)
  • by explicit definition as a class or data structure (C-type, ST/X-class type)

Also, there are various syntactical representations, in which a type may be presented or imported:

  • expecco type definition syntax
  • XML / XSD / DTD / IDL
  • C language struct syntax
  • COBOL Copybook, Sun RPC IDL, COM-IDL, ASN.1

The set of options available in the editor depends on the expecco version (basic, pro, enterprise) and the set of available plugins (SWIFT, ASN.1, etc.), as some import formats are provided by additional plugins.

To define a type, first create a new datatype tree item, then choose an appropriate representation in the editor's "Type-Kind" list. A template showing the syntax of this type will be shown.

Change the template and press "Accept" to install the type. The second tab in the editor labeled "Type Description" shows the type's definition in expecco's internal type description language, which is usually only of interest to validate a type's correctness if an alien format was used to import a type definition. This format is described below .


Datatype Editor

Type Kinds (Semantic)[Bearbeiten]

Primary Types[Bearbeiten]

These are builtin types (classes) of the underlying Smalltalk execution framework. For example, "String", "Array", "Set", "Btree", "Dictionary" or "Number" to name a few. There are thousands of classes available, but you will usually get along happily with only a few - if at all. However, you might need to know some, when referring to a framework inside expecco's underlying Smalltalk environment. For example, there are packages and classes to support protocols like FTP, HTTP, etc. or to process data, parse special file formats or provide cryptographic operations. Also, some expecco plugins and extensions come bundled with additional useful classes.

The most common primary types are shortly listed in the "Datatype documentation" . For more details, please refer to the Smalltalk documentation, especially the "Basic Classes Introduction" and the "Online Class Documentation" (containing full lists and documentation of all classes). You can also open a class browser (found in "Extras" → "Tools").

A number of primary types is available directly via the datatype menus, and there is no need to define them as a user type. These predefined primary types include "Integer", "Number", "String", "Boolean" along with a few other often used types. All other primary types can be defined as a user defined type in a textual type definition, where the class name is written in angle brackets, as in:

    <String>

or:

    <Socket>

Enumeration Types[Bearbeiten]

A single symbolic value from a list of enumerated symbolic values. Unless quoted in single quotes, these names must consist of letters or digits or underline characters, and should start with a non-digit (to avoid confusion).

Typical examples are:

    enum( red | green | blue)

or:

    enum( male | female)

or:

    enum( 'foo-a' | 'foo-b' | 'foo-c' | 'bar-a' | 'bar-b' )

The last example uses quotes around the element names, as these contain a special (non-alphanumeric) character.

Enum in Input Dialogs[Bearbeiten]

When used as a freeze value or environment variable value, a combo list presenting only the valid enum elements is shown. By default, the values are sorted alphabetically in one single list. If your type consists of a large number of values, you may want to specify a grouping scheme.

Datatype enumOrder.png

For example, the last of the above examples could be presented as either a single list with 5 items, or as a 2-item list ('foo' and 'bar') with submenus for each prefix. The menu/combolist grouping is specified in the datatype editor (at the bottom right of the editor).

Numeric Value of an Enum[Bearbeiten]

Enum values can have an associated integer value, which is useful, if the type is actually a mapping of a corresponding C or Java type.
For this, add an "= <integerValue>" after the element's name to the above definition. I.e.:

enum ( foo | bar = 20 | baz | bla = 30 )

Will assign integer values to the enum elements. If asked via "<type> integerValueOf: x", it will return the following integer values: 0 (for x = 'foo'), 20 (for x = 'bar'), 21 for (x = 'baz') and 30 (for x = 'bla')

Without explicit integer value, elements get auto-incremented values, starting with 0 (zero) or the next value from the previous enum element.

Be aware that the enum-values are always string-like objects (actually: instances of Smalltalk's Symbol class). Thus, although the elements look like integers in a definition like "(1 | 2 | 3)", they are actually string like with an associated integer. Consider using a subrange or subset type, as described below, if you need integer values.

Enum Definition pasted from a C-Header File[Bearbeiten]

New in 18.2:
In addition to the above definition format, enum types can also be defined as a list of C-define directives. This makes it easier, to copy-paste a list of values from a C-header file. The format is described below.

Range Types[Bearbeiten]

A subrange of Integer, Character or Enum values. Used to limit the set of valid elements, given a previously defined or buitin base type. For example, a byte could be defined as:

    range( <Integer> : 0 .. 255 )

and the set of lowercase letters can be defined as:

    range( <Character> : $a .. $z )

Point right.png Notice the dollar prefix, which designates a character constant.

Subset Types[Bearbeiten]

A subset of Integer, Character or Enum values. This is similar to a subrange, but allows for multiple ranges or individual elements to be listed.

For example, the set of alphanumeric characters plus underline could be defined as:

    subset( <Character> : $a .. %z , $A .. $Z , $_ , $0 .. $9 )

A type which can take character values limited to the set of English vowels could be defined as:

    subset( <Character> : $A , $E , $I , $O , $U , $a , $e , $i , $o , $u )

Point right.png Notice the dollar prefix, which designates a character constant.

Pattern Types[Bearbeiten]

(new with expecco 21.2)
A constraint subset of String values. Constraint may be that the string matches a glob or regex pattern, and/or that its size (number of characters) is within some limits.

For example, a type for strings not longer than 10 characters could be defined as:

    String( maxLength: 10 )

A type for a string which starts with a letter can be defined as (GLOB pattern):

    String( match: '[a-z]*')

or alternatively, using a Regex (instead of a GLOB pattern) as:

    String( regex: '[a-z].*')

The constraint can be one of:

  • minLength: <n>
the string must consist of at least <n> characters
  • maxLength: <n>
may not be longer than <n> characters
  • match: '<glob pattern>'
the strings must match the GLOB pattern
  • regex: '<pattern>'
must match the Regex pattern

Point right.png Be aware of the difference between GLOB and Regex patterns.

Array Types[Bearbeiten]

Are defined as a homogeneous collection of elements, which are all of the same baseType. The number of elements is variable among instances. The elements are accessible by a numeric index which is 1 based (both for Smalltalk and JavaScript elementary blocks). The standard library also provides 0-based indexing blocks, which is sometimes more convenient for C/Java programmers.
For compatibility to other JavaScript systems, a few builtin functions behave differently, depending on the language context inside an elementary block's code; most notably, these are the indexOf/lastIndexOf functions.

In a textual definition, array types consist of a basetype followed by "[]", as in:

    <String>[]    -- an array of Strings

or:

    <Number>[]    -- an array of Numbers

Tuple Types[Bearbeiten]

Are defined as a non-homogeneous, fixed size vector of elements. Each element has a predefined type. The types may be different among elements, but all instances of the tuple type have the same number of elements and the same type of element at corresponding positions.

The elements are accessible by index (1..). Tuples are similar to compound types as described below. The difference is that tuples address the elements by index, whereas compounds address them by name. Tuples are also similar to array types, however, the number of elements is fixed in a tuple, whereas arrays can have an arbitrary number of elements, and the element types may be different, whereas in an array, all elements are of the same type.

In a textual description, a tuple is defined by listing the individual element types in parentheses. For example, a tuple which might represent a 3D coordinate, could be defined as:

    [ <Number> , <Number> , <Number> ]

or, a tuple which associates a name with an age and gender might be:

    [ <String> , <Integer> , enum(M | F) ]

For the last example, it would probably be better to use a compound, which names the slots.

Point right.png Notice, in previous versions of expecco, tuple types could also be defined in parenthesis "(...)", as opposed to brackets "[...]". This is still supported in future versions, but not recommended for new type definitions (read the documentation on union types for an explanation). No ambiguity exists if the definition starts with 'tuple', as in:

    tuple( <Number> , <Number> , <Number> )

Class Types[Bearbeiten]

A user defined class. Includes the instance's private slots (also called "instance variables"), and a set of operations (usually called "methods" or "virtual functions"). All of this information is stored with the test suite. Instance slots are accessible by getter/setter method invocations. Class types are defined by entering the class definition in a programming language (either expecco's JavaScript dialect or Smalltalk).

Private class definitions allow for almost any functionality to be defined, but require some programming skills. For an introduction to programming, please refer to the "Online Documentation", the "Beginners Introduction & Tutorial", and the "Smalltalk Tutorial",.

Compound Types[Bearbeiten]

A collection of named slots. Is similar to a Class Type without operations (actually, that is how the system represents them internally). The elements are accessible by name or keyed access, using the name as key (i.e. like a dictionary/hashtable).

In a textual definition, list the names and types of the individual elements in braces; for example, a person record might be defined as:

    {
        firstame : String
        lastName : String
        age      : Integer
        gender   : enum(M | F)
    }

Field definitions may optionally be terminated by a ";" (semicolon) character to make the definition more readable. I.e. the following defines the same type as the above:

    {
        firstame : String;
        lastName : String;
        age      : Integer;
        gender   : enum(M | F);
    }

Also, for backward compatibility, a terminating "," (comma) character is allowed, but no longer recommended.

Compound type definitions can also be imported from various other formats, such as DTD, XML, C-header files etc.

Getters[Bearbeiten]

In elementary code blocks, field values of an instance are accessed via getter calls which are named like the field.
For example, given an instance of the above named "c", the "lastName" field can be fetched in Smalltalk code with any of:

c lastName        "/ calling the getter
c at:'lastName'   "/ using collection protocol
c['lastName']     "/ using collection protocol

or in JavaScript code with:

c.lastName()      // calling the getter
c.lastName        // (virtual) slot access
c['lastName']     // using collection protocol
c["lastName"]     // using collection protocol

Setters[Bearbeiten]

Elementary code can change a field's value via setter calls.
For the above example, these would be in Smalltalk:

c lastName:newValue
c at:'lastName' put:newValue
c['lastName'] := newValue

and in JavaScript:

c.lastName(newValue)
c['lastName'] := newValue

Generating Action Blocks to Access Fields and Create Instances[Bearbeiten]

CompoundCreateActions.png
CompoundCreateActions2.png

The tree-item menu of a compound type contains entries to generate field-setter, field getter and creation actions (under "Refactoring" - "Generate").  

 

 

 

After that, you'll find actions to create an instance, to extract fields and to set fields.

These are elementary actions, which use the above listed getter/setter calls. They can of course be further modified if additional checks or processing is needed.

Union Types[Bearbeiten]

The instance can be an instance from a number of other types. In a textual definition, list the possible element types, separated by a vetical bar, as in:

    ( <Filename> | <String> | <URL> )

or, alternatively:

   union ( <Filename> | <String> | <URL> )

there is no explicit discriminator stored with the value. However, due to the run-time type information, it is possible in an elementary block to determine the type of value passed in, via the class or isXXX or isKindOf: protocols.

Point right.png Notice that for a single element union type (eg. "( String )") the interpretation was ambiguous in previous expecco versions, as it could also be interpreted as a tuple with a single String element. Therefore, the syntax for tuple types was changed to use square brackets, but still supporting the previous regular parentheses syntax. There is no ambiguity when more than one element is present; however, for single element types, the datatype parser will (currently) read this as a single-type union type.

To avoid this ambiguity, the old parenthesis-syntax should no longer be used for tuples (prefixing with 'union' also solves this).

Additional Special Types[Bearbeiten]

Datatype Type[Bearbeiten]

Instances are datatypes known to the project. Datatype-types are typically used as input pin type of collection-instantiation blocks. As a freeze value, the list of known types is presented in a combolist. In a textual definition, the keyword "datatype" is used:

datatype

Constraint Datatype Type[Bearbeiten]

A datatype type can be constraint to a subset of types, by defining it as:

datatype ( <constraint> )

where <constraint> is either the name of another type:

  • <compatTypeName> - constraint to types which are compatible with a type named <compatTypeName>

or a selector from one of:

  • isArrayType - for types which have integer-indexable slots
  • isCTypeType - for C-defined types
  • isCEnumType - for C enum types
  • isCStructType - for C-defined struct types
  • isCUnionType - for C-defined union types
  • isCollectionPrimaryType - for subtypes of Collection (i.e. Dictionary, Set, OrderedCollection etc.)
  • isCompoundType - for compound types
  • isEnumType - for enum types
  • isNumberPrimaryType - for subtypes of Number (i.e. Float, Integer, Fraction, FixedPoint)
  • isPrimaryType - for any primary type
  • isStreamPrimaryType - for subtypes of Stream
  • isTupleType - for any tuple type
  • isUnionType - for any union type
  • isUserDefinedDatatype - for all user defined types (i.e. those in the current suite)
  • isWellKnownDatatype - for all builtin (i.e. not user defined) types. These types will always be present, whereas user defined types are those defined in the current suite

or a selector plus string argument from one of:

  • nameMatches: globPattern
  • nameMatchesRegex: regexPattern

Constrained datatypes should be used by the StandardLibraries only, and are used to limit the input values of some instance creation actions. For example, the "New Collection" action has an input pin, which defines the type of collection to be created. This pin has the type: "datatype( isCollectionPrimaryType )".

Examples:

datatype ( Integer ) -- a type whose instances are all datatypes which are compatible with the Integer class
datatype ( isCTypeType ) -- a type whose instances are all known C-types
datatype ( isCStructType ) -- a type representing all known C struct types
datatype ( nameMatches: 'DPU*' ) -- a type representing all types which match this name

Notice that the freeze value of a datatype-typed pin (and also values flowing in and out of such pins) are data types; not values (although datatypes are also objects/values in the technical sense).

Monitor Types[Bearbeiten]

A monitor is a special builtin object which observes an object and sends out change notifications to interested stakeholders when it changes its contents. Monitors are used to allow external QA systems (such as expecco ALM) to monitor and display changing expecco variables in real time.

Resource, Skill, Library and ActivityLog Types[Bearbeiten]

Represent instances of resources and skills. These are builtin types used by expecco itself.

Port Types[Bearbeiten]

These are not yet used but present for future TTCN3 support.

Type Popup-Menu Organisation[Bearbeiten]

In addition to the definition of the type, the editor provides control on where and how the type will be presented in type popup menus and pull down lists.

Group[Bearbeiten]

If you attach a group name to the type, it will be grouped into a such-named submenu below a pin's or variable's datatype popup menu.

Enum Freeze-Value Menu Organisation[Bearbeiten]

When freezing an enum-typed pin or choosing an enum variable's default value, by default the elements are presented in one list. This list may get long and you may want to organize them into a hierarchical set of submenus and/or control how they are sorted.

For example, if the enum elements represent commands to a controller, they might be named after commands, like "power_on", "power_off", "power_low", "turn_left", "turn_right" etc.
In this case, you may want to organize the freeze menu into two submenus, one for all "power_XXX" values, another for all "turn_XXX"values etc.

The editor's "Freeze Menu Organization" at the lower right gives you a number of options to organize your menus and how to sort the elements. Use that, if you have more than (say) 10 or 15 elements in an enum. Click on the "Test" button to see how the menu will be shown later.

Sort Order[Bearbeiten]

By default, elements will be presented in the order of the type definition.
The choices are:

  • normal - use the default sort order
  • sortAlphabetical - sort by name
  • sortNatural - numeric suffixes are sorted by value (i.e. 'a10' comes after 'a2')
  • sortByValue - sort by the associated value; not the symbolic name
Hierarchical Menu[Bearbeiten]

The other options control where the symbolic names are split and grouped into submenus.

Type Representation (Syntax)[Bearbeiten]

Various textual representations are possible; some are already built into the base expecco system, others are addons and present if certain plugins are installed.

Formal BNF Description of the Expecco Type Syntax[Bearbeiten]

Expecco provides its own native type-description language, with an easy to understand and use syntax:


type ::= <nonArrayType> | <arrayType>

arrayType ::= <nonArrayType> '[' ']'

nonArrayType ::= <tupleType> | <unionType> | <compoundType> 
                             | <enumType> | <rangeType> | <patternType>  
                             | <primaryType> | <simpleType> | <specialType>

tupleType ::= '[' <elementType1> [','] <elementType2> .. <elementTypeN> ']'
elementType ::= <type>

unionType ::= '(' <alternativeType1> '|' <alternativeType2 > '|' .. <alternativeTypeN> ')'
alternativeType ::= <type>

enumType ::= 'enum' '(' <enumValue1> '|' <enumValue2> '|' ... <enumValueN> ')'
enumValue ::= ( <identifier> | <quoted-string> | <dquoted-string> ) [ '=' <integer-constant> ]

rangeType ::= 'range' '(' <baseType> ':' <minValue> '..' <maxValue> ')'
minValue ::= <constant>
maxValue ::= <constant>

subsetType ::= 'subset' '(' <baseType> ':' <range1> [',' <range2>]... ')'
range ::= <minValue> '..' <maxValue> | <constant>

patternType ::= 'String' '(' <patternConstraint> [ ',' <patternConstraint> ]... ')'
patternConstraint ::= 'match:' <stringConstant>
                      | 'regex:' <stringConstant>
                      | 'minLength:' <integerConstant>
                      | 'maxLength:' <stringConstant>

compoundType ::= '{' <fieldSpec1> <fieldSpec2> ... <fieldSpecN> '}'

fieldSpec ::= <fieldIdentifier> ':' <fieldType> [ '=' <defaultValue> ] [';']
fieldType ::= <type>

primaryType ::= '<' <BuiltIn-Classname> '>'
BuiltIn-Classname ::= <identifier>

simpleType ::= <anyType> | <templateType> | <constraintTemplateType> | <namedType>

anyType ::= '*'

templateType ::= '#' <templateIdentifier>
 
constraintTemplateType ::= '#' <templateIdentifier> <setOfConstraintTypes>
setOfConstraintTypes ::= <unionType>

<namedType> ::= 'any' | 'struct' | <typeName_in_project> | <Smalltalk-Classname>
typeName_in_project ::= <identifier>

specialType ::= <monitorType> | <portType> | <datatypeType> | <performerType>

monitorType ::= 'monitor' '(' <baseType>')'

portType ::= 'port' '(' <baseType>')'

datatypeType ::= 'datatype' [ '(' <constraint> ')' ]

constraint ::= <primaryTypeName> |
               'isUserDefinedType' | 'isWellKnownType' | 
               'isPrimaryType' | 
               'isNumberPrimaryType' | 'isCollectionPrimaryType' | 'isStreamPrimaryType'
               'isArrayType' | 'isCTypeType'
               'isCompoundType' | 'isEnumType' | 'isTupleType' | 'isUnionType'

performerType ::= 'performer' [ '(' interfaceSpec ')' ]

interfaceSpec ::= <identifier> |
               '"' id-string '" |
               'interface:' uuid

Notes:
The separating commas in the tuple- and compound definitions are optional.
This format is used if you select "Defined" type in the editor. It is also expected if you select "Define..." in one of the type menus (Pin-Type, Veriable-Type, Skill-Type). Support for this representation is part of the base expecco system.

DTD Type Definition[Bearbeiten]

A DTD definition can also be used to specify a compound type. For this, choose "Compound (DTD-Defined)", and paste the DTD into the text area. Support for this representation is part of the base expecco system.

C Language Type Definition[Bearbeiten]

A C language code fragment can also be used to specify a compound or union type. For this, choose "CType (C-Defined)", and paste the C type definition into the text area. Instances of this type are especially useful when calling external DLL functions. Support for this representation is part of the base expecco system.

A typical C language definition looks like:

/* C: */
struct {
    int i1;
    float f1;
    double d1;
    char c[20];
};

Notice, that the definition must begin with a "/* C: */" comment.

For more details, please refer to the Datatype - CTypes document .

Enum Type Definition from C-define Directives[Bearbeiten]

An enum type can also be defined from a list of C-#define directives. These can be conveniently copy-pasted from a C-header file. For this, choose "Enum (from C-defines)", and paste the defines into the text area. Support for this representation is part of the base expecco system.

As an example, the following list of C-defines:

#define STATUS_OK 0
#define STATUS_ERR_CONNECT 1
#define STATUS_ERR_BROKEN 2

will generate the following enum type:

enum(STATUS_OK=0 , STATUS_ERR_CONNECT, STATUS_ERR_BROKEN)

The define values can be decimal integers, hex integers (0xXXXX), octal integers (0XXX) or binary integers (0bXXXX).

XSD Type Definition[Bearbeiten]

A definition in XSD-XML. An XSD definition can also be used to specify a type.

This is an extension provided by a plugin. Please read the corresponding plugin documentation.

<usage: to be documented>

COBOL Copybook Definition[Bearbeiten]

Parses a COBOL Copybook type-definition.

This is only available as plugin. Please read the corresponding plugin documentation for details.

ASN.1 Type Definiton[Bearbeiten]

Parses an ASN.1 type-definition.

This is only available as plugin. Please read the corresponding plugin documentation for details.

Sun RPC IDL Type Definiton[Bearbeiten]

Parses a Sun RPC type-definition, which is used for example in the NFS file-system or in VISA lab equipment interfaces. This is only available as plugin. Please read the corresponding plugin documentation for details.

Microsoft COM/DCOM-IDL Type Definition[Bearbeiten]

Parses a COM/DCOM IDL type-definition. This is only available as plugin. Please read the corresponding plugin documentation for details.

See Also[Bearbeiten]

Datatype Element with more detail on primitive types and C-data types



Copyright © 2014-2024 eXept Software AG