Basic language elements
This topic includes information about the following basic language elements:
- Character set
- Data types
- Statements
- Preprocessor and compiler directives
- Identifiers
- Textual literals
- Variables
- Variable references
Character set
The basic unit of Synergy DBL is the ASCII character. (Appendix B: ASCII Character Set contains the complete ASCII character set.) ASCII characters are combined into sequences that represent the elements of Synergy DBL. Certain characters, called delimiters, separate adjacent language elements in a statement. Note that identifier names and keywords are case insensitive in DBL.
This documentation refers to the following ASCII character subsets:
Numeric |
0, 1, 2, 3, 4, 5, 6, 7, 8, and 9 |
Alphabetic |
Uppercase characters A through Z and lowercase characters a through z |
Alphanumeric |
Both numeric and alphabetical characters |
Alpha |
All ASCII characters except the nonprintable characters (for example, carriage return, line feed, and form feed) |
Data types
Synergy DBL supports all of the data types listed in Data types.
Statements
Synergy DBL provides six types of statements:
- Declarative
- Data manipulation
- File manipulation
- Control
- Input/output
- Interprogram communication
This section is merely intended as an introduction to Synergy DBL statements. You will find more complete information in Synergy DBL Statements.
In this documentation, we refer to the statement name as a “keyword.”
Declarative statements
Declarative statements declare the variables and definitions that the routine can access. Many, but not all, declarative statements appear in the data division or class definition of your program. The declared variables can be local to the routine, global to the routine, or used to exchange data with other routines.
ADDHANDLER registers a method as an event handler for an event.
CLASS defines a class within the current namespace or within another class.
COMMON defines a shared data record and its associated fields. A GLOBAL COMMON statement allocates a shared data area. An EXTERNAL COMMON statement references a data area that was allocated by a GLOBAL COMMON statement.
DATA defines a local stack variable in the procedure division.
DELEGATE-ENDDELEGATE declares a delegate.
ENDPARAMS indicates the end of a parameter list.
ENUM declares an enumeration.
EVENT declares an event.
EXTERNAL FUNCTION declares a user-defined or system-supplied external function.
FUNCTION indicates the beginning of a user-defined function.
GLOBAL specifies that all RECORD definitions that follow the GLOBAL statement are stored in a global named data area instead of the local data area. ENDGLOBAL designates the end of a global data section.
GROUP defines a data structure within another data structure. A group member can be a field or another group. ENDGROUP designates the end of a group.
IMPORT imports the specified namespace from a prototype file or a .dbl source file into the current .dbl source file, enabling you to use members of that namespace without having to type the fully qualified member name.
INTERFACE defines an interface, which is like a contract that a class agrees to abide by.
LAMBDA provides a way to generate inline methods that have access to variables within the method in which the lambda is declared.
LITERAL defines a data structure and its associated fields that cannot be modified during program execution.
MAIN indicates the beginning of a main routine.
METHOD indicates the beginning of a method.
NAMESPACE creates a namespace, which enables you to group related entities together for use in a Synergy application.
PROC indicates the end of the data division and the beginning of the procedure division. END designates the end of the procedure division.
PROPERTY indicates the beginning of a property, which must contain a get or set accessor method.
RECORD defines a data structure and its associated data fields. ENDRECORD designates the end of a record.
REMOVEHANDLER unregisters a registered event handler.
STRUCTURE defines how data is laid out, without allocating any data space.
SUBROUTINE indicates the beginning of an external subroutine.
Data manipulation statements
Data manipulation statements directly change data.
CLEAR initializes one or more variables to either blanks (for alpha variables) or zero representation (for numeric variables).
DECR decrements a numeric variable by 1.
INCR increments a numeric variable by 1.
INIT initializes a named data structure to its declared default values.
LOCASE converts all uppercase characters in an alphabetic variable to their corresponding lowercase characters.
SET initializes a set of variables of the same data type to a single value.
UPCASE converts all lowercase characters in an alphabetic variable to their corresponding uppercase characters.
File manipulation statements
File manipulation statements access records within a file or group of files.
MERGE merges the contents of two or more sorted files into a single file. Synergy DBL supports an in-place merge and an n-way merge.
SORT orders a file by specified key fields and places the sorted result in either a new file or the original file.
Control statements
When a routine is being executed, control begins with the statement that follows the PROC statement and flows sequentially to each successive statement. Control statements alter the order of execution by directing control to another statement, transferring control to another routine, ending processing of the current routine, or returning control to a referencing routine. This type of statement is used to create loops and internal functions within a program.
The AWAIT statement waits for an asynchronous task to complete.
The BEGIN and END statements define a compound statement, which is logically considered to be a single statement.
CALL transfers control to an internal subroutine until a corresponding RETURN statement is executed. Synergy DBL provides both an unconditional form and a computed form, which transfers control based on the result of an expression.
CASE executes one of a set of statements based on the value of a selection expression.
DO FOREVER executes a statement repeatedly until a condition occurs to transfer control outside of the statement. (DO FOREVER works just like the REPEAT statement.)
DO-UNTIL executes a statement repeatedly until the specified condition becomes true. The DO loop is always executed at least once.
EXIT terminates execution of the current BEGIN-END compound statement. Control is transferred to the END statement of the current compound statement.
EXITLOOP terminates execution of the current loop. Control is transferred to the statement that immediately follows the loop.
EXITTRY exits a TRY statement.
FOR
FOR executes a statement repeatedly under the control of a specified variable. FOR has three forms:
FOREACH iterates sequentially through all elements in a collection.
FRETURN specifies the return value of a user-defined function and returns control to the calling program.
GOTO transfers program control to the specified label. Synergy DBL provides both an unconditional form and a computed form, which transfers control based on the result of an expression.
IF executes a statement based on the result of an expression.
The IF-THEN-ELSE sequence executes one of two statements based on the result of an expression.
MRETURN returns control from a method to the calling program.
NEXTLOOP terminates the current iteration of a loop and moves to the start of the next iteration. (NEXTLOOP performs like the EXIT statement within the BEGIN-END block of a loop structure.)
NOP performs no operation. It is ignored.
OFFERROR disables any runtime error trapping established by an ONERROR statement.
ONERROR enables program trapping of one or more runtime errors.
RAISEEVENT executes all registered event handlers.
REPEAT executes a statement repeatedly until control is explicitly transferred outside of the statement. (REPEAT works just like the DO FOREVER statement.)
RETURN completes the processing of an internal subroutine and returns control to the statement that follows the CALL that invoked the subroutine.
SLEEP suspends execution of a routine for the specified number of seconds.
STOP terminates execution of the current program. Synergy DBL provides two forms of this statement: an unconditional form, which returns control to the controlling system, and a chaining form, which passes control to another program.
THROW throws an exception.
The TRY-CATCH-FINALLY-ENDTRY block handles exceptions.
USING and USING-RANGE execute one statement from a list of statements based on the result of an expression.
WHILE executes a statement repeatedly based on the result of an expression. If the initial result is false, the WHILE statement never executes.
XCALL transfers execution control to an external subroutine.
XRETURN completes the processing of an external subroutine and returns control to the statement that follows the XCALL statement in the calling routine.
Input/output statements
Input/output statements control the exchange of data between the executing program and the input/output devices attached to the computer system. Such devices include printers, terminals, mass storage devices (like disks and floppies), and any other data transmission devices attached to your computer system.
ACCEPT receives the next sequential character from an input device.
CLOSE completes any pending I/O activity and disassociates a Synergy DBL channel from a device or a file.
DELETE removes a record from an ISAM file.
DISPLAY outputs a sequence of one or more characters to a character-oriented device or file.
FIND locates the position of a record within a file.
FLUSH flushes all buffers associated with a channel.
FORMS outputs special form-positioning characters to a character-oriented device or file.
GET reads a fixed-length record from a specified point in a file. This is a binary operation that does not interpret the ASCII characters that are read.
GETS reads the next sequential fixed-length record from a file. This is a binary operation that does not interpret the ASCII characters that are read.
OPEN associates an internal Synergy DBL channel with an I/O device or file.
PURGE ends I/O activity on a Synergy DBL channel. PURGE is equivalent to CLOSE, except that PURGE deletes a file opened in output (O) mode.
PUT outputs a fixed-length record to a specified point in a file. This is a binary output operation, not a record operation, as is the WRITE statement.
PUTS outputs a fixed-length record, updating the next sequential record in the file. This is a binary output operation, not a record operation, as is the WRITE statement.
READ obtains a record from a specified point in a file.
READS reads the next sequential record from a file.
STORE adds a new record to an ISAM file.
UNLOCK releases any record locks the current program may have on a specified channel.
WRITE updates an existing record in a file.
WRITES updates the next sequential record.
Interprogram communication statements
Interprogram communication statements pass and obtain data from interactive processes.
LPQUE queues a file for printing by the system.
RECV receives a message sent by a previously executed SEND statement (either in the current program or some other Synergy program).
SEND transmits a message to the current or a different program. The message is saved until a RECV statement retrieves it.
Preprocessor and compiler directives
Preprocessor directives are instructions for the preprocessor and are implemented before any code is compiled. Compiler directive statements instruct the Synergy compiler and are evaluated only when a program is compiled. Directives are not included in the resulting executable program. See Types of directives and syntax for more information.
.ALIGN aligns the data location counter to a boundary.
.DEFINE defines a replacement identifier and optionally assigns replacement text that will be substituted for that identifier. The replacement identifier can be used anywhere in the routine. (See .DEFINE for more information about text replacement.)
.IDENT defines a routine identifier string to be included in a routine’s object file.
The .IF-.ELSE-.ENDC conditional block specifies that compilation of the statements within the block depends on the truth value of an expression.
The .IFDEF-.ELSE-.ENDC conditional block specifies that compilation of the statements within the block depends on the declaration of a variable or replacement identifier.
The .IFNDEF-.ELSE-.ENDC conditional block specifies that compilation of the statements within the block depends on the nondeclaration of a variable or replacement identifier.
.IFT, .IFF, and .IFTF are used within conditional blocks to provide greater control over conditional processing. .IFT tests whether the original condition of the current conditional block was true. .IFF tests whether the original condition was false. .IFTF allows processing regardless of whether the original condition was true or false.
.INCLUDE causes the compiler to read source code from another source file or from the Repository. Included statements are compiled as if they were part of the current routine at the point where the .INCLUDE statement appears.
.LIST and .NOLIST control the listing of source code.
.NODEBUG prevents the debugger from stopping at breakpoints, watchpoints, or anything else that causes the program to pause.
.NOPROTO turns off prototype generation for a block of source code in a program, and .PROTO turns it back on.
.PAGE ends the current listing page and begins a new listing page.
.REGION-.ENDREGION specifies a collapsible region of code that you can hide from view.
.START optionally sets or unsets compilation flags that control the information printed in the program listing. See .START for a complete list of compilation flags.
.TITLE changes the title in the listing page header.
.UNDEFINE removes the declaration of a replacement identifier that was established by a previous .DEFINE directive.
Identifiers
Identifiers are used as names for namespaces, classes, methods, subroutines, functions, parameters, records, fields, and properties. Identifiers begin with an alpha character (or an underscore in Synergy .NET), optionally followed by a sequence of alphanumeric characters, underscores (_), and dollar signs ($) that identify a statement, variable, or routine to the compiler. For example, Read, a10, namelast, and TAX$RATE_single are all valid identifiers. Destructor method identifiers prefix a tilde (~) to the name of the class.
Identifiers are not case sensitive. For example, NAME_FIRST is the same as name_first and NAME_first.
An identifier section is one of the sections in a nested identifier which may include namespace, class, or member name. For example, the following identifier has three identifier sections:
mynamespace.myclass.myfield
The maximum length of an identifier section is 30 characters on Windows and UNIX and 31 characters on OpenVMS.
All identifiers within a scope, such as classes and structures in a namespace or member identifiers in a class, must be distinct, independent of kind, except where the names are identical and resolved via overloading, such as two routines with the same name but different parameters. A scope is defined to be the smallest of one of the following groupings that has the identifier declared as one of its members, not including inherited members:
- Namespace
- Class
- Structure
- Record
- Group
- CATCH block
- Local data block
Thus, you cannot have two fields with the same name, or a field and a method with the same name in the same class, but you can have two methods with the same name in the same class if their method signatures are different. A field name and a property in the same class can have the same name as long as the case is different.
You can’t have two classes with the same name or a class and structure with the same name in the same namespace.
Two method signatures are considered to match if their identifier, number of arguments, and argument types match exactly. Two subroutine or function signatures are considered a match if their identifiers match exactly.
Keywords
Keywords (like READ, END, and .DEFINE) have predefined meanings in Synergy DBL and identify statements and compiler directives. They must be spelled exactly as documented.
Replacement identifiers
A replacement identifier defines a text string that is to be substituted for the identifier throughout the program. A replacement identifier is defined by the .DEFINE statement.
Variable names
Variable names are identifiers that refer to data records, groups, and fields. A variable name can have a maximum of 30 characters. Although variable names appear in a program listing exactly as you typed them, the compiler translates the names to uppercase. For example, the compiler recognizes both of the following identifiers as the identifier ABCDE:
aBcdE
abcDe
Statement labels
You can label any statement in the procedure division with a symbolic name. Several of the program control statements can reference this label, enabling you to transfer control to a specific statement during program execution. For example, you might use a label to transfer control to an error-trapping routine or when using a CALL statement.
The statement label must be the first nonblank item in the statement, followed by a comma and must be unique within the routine. A statement label can have a maximum of 30 characters on Windows and UNIX and 31 characters on OpenVMS.
Here’s an example:
call lbl02 ;Unlabeled, references label lbl02 . . . lbl02, ;Labeled incr flg return
Routine names
Routine names identify which main routine, external subroutine, or function is being referenced. Like all other identifiers, a routine name can have a maximum of 30 characters on Windows and UNIX and 31 characters on OpenVMS.
To call a global routine from within a class that contains a routine of the same name, include ^global as part of the routine name path. For example,
xcall ^global.sub1()
Data reference operation names
A data reference operation name identifies a data reference operation. See Data reference operations for more information.
Textual literals
A textual literal is either a sequence of characters enclosed between matching delimiters (single or double quotation marks) or a sequence of numeric characters, which may be preceded by a plus or minus sign. A literal represents a specific value that is defined at compile time and cannot be changed during execution.
In Synergy .NET, a literal or literal cast as type object or passed to a parameter of type object has its type changed from a Synergy literal type to the corresponding .NET literal type, and then it is boxed. (For example, “abc” is type string, and 10 is @int.) If you want a Synergy literal type instead, cast the literal as the desired Synergy type (@a or @i).
An alpha literal is a sequence of characters enclosed in matching single or double quotation marks. An alpha literal can be up to 255 characters long.
Here are some examples of alpha literals:
- 'This is an ALPHA literal'
- "as is this one ........."
If an alpha literal contains either a single or double quotation mark and you’re using the same character as the delimiter, you must use two successive characters to represent a single embedded mark. The examples below illustrate embedded delimiters: two successive quotation marks are required to specify one quotation mark within the literal.
- "An" "is embedded"
- "quotation mark at end"""
If the embedded character is different from the ones delimiting the literal, you don’t need to double the embedded character (as shown in the examples below).
- "An ' is embedded"
- ' "Quotation marks are present"...'
Sometimes it’s more convenient to split an alpha literal into smaller physical parts. For example, you might do this if you’re using the literal to initialize an entire record and you want to append comments to each field. The Synergy compiler concatenates several alpha literals if they are separated only by blanks and tabs. (If sections of the alpha literal are on continuation lines, each line must begin with the continuation character [&].)
For example:
"This is " "an alpha " "literal"
and
"This is " &"an alpha " &"literal"
are functionally the single alpha literal
"This is an alpha literal"
The blanks and tabs between the separate alpha literals are not part of the concatenated literal. (See Continuation lines for a warning about splitting alpha literals across two or more physical lines.)
Alpha literals are case sensitive.
Decimal literals
A decimal literal is any consecutive sequence of numeric characters, which may be preceded by a plus (+) or minus (–) sign. A decimal literal can consist of a maximum of 28 digits. The compiler strips nonsignificant leading zeros to a minimum of one digit. For example, the literal 00003 is stored as 3. The literal 000 is stored as 0.
Here are some examples of decimal literals:
- 273949830000000000
- 1
- -391
Implied-decimal literals
An implied-decimal literal is a sequence of not more than 56 numeric characters, which may be preceded by a plus or minus sign. A maximum of 28 digits can appear before the decimal point, and a maximum of 28 can occur after it. The decimal point cannot be the first or the last character in an implied-decimal literal; at least one leading and trailing digit must appear before and after the decimal point.
Here are some examples:
- 1234.567
- 123456789012345678.0123456789
- +18.10
- 0.928456989
- -518.0
The compiler strips nonsignificant leading and/or trailing zeros prior to processing.
Integer literals
You cannot explicitly write an actual integer literal in a source line in the same way that you can specify alpha, decimal, and implied-decimal literals. However, if you include a decimal literal in an arithmetic expression with an integer variable, the compiler builds an integer literal into the code.
You can also use %INTEGER with a numeric literal argument to create an integer literal. |
Error literals
An error literal has the format $ERR_mnemonic, where mnemonic is an error identification mnemonic. One error literal is defined for every trappable runtime error. (For example, $ERR_DIVIDE specifies the “Divide by zero” error.)
The entire error literal is treated as a decimal literal, and you can use error literals with ONERROR statements, in I/O error lists, and anywhere else in your program that you can use decimal literals. Here’s an example:
onerror($ERR_IOFAIL, $ERR_DIGIT) proc_err1, ($ERR_EOF) proc_err2 read(CHN, data, rec_id) [$ERR_IOFAIL=proc_err1]
The Synergy Errors tab contains a complete list of Synergy DBL error mnemonics, numbers, and messages.
Variables
A variable is an identifier that refers to a data location in your program. Before using a variable in statements in the procedure division, you must first define it in the data division. The data division statement that defines the name and data type of the variable also determines the characteristics of the variable’s data area: size, possible initial values, and position relative to the other variables.
Shared variables (common records, global records, and global literals) can be declared by any routine in a program and can be accessed by any routine in a program. A shared variable name must be unique. Variables that are not shared are local to the routine in which they are declared.
A path uniquely references a named record or a field within a data structure (as specified by the RECORD or GROUP statement). Variable path specifications have the following format:
[struct_name.][struct_name….]field_name
Paths have the following characteristics:
- The path can contain any number of data structure names as long as it creates a unique variable reference. Use a period (without any spaces) as the delimiter between data structure names or between a structure name and the field name. Let’s use the following group as an example:
record a group b fld ,a2 group c nam ,a20 city ,a10 endgroup endgroup
You can reference the field city with the following paths:
city a.city b.city c.city a.b.city a.c.city b.c.city a.b.c.city
Note that you don’t have to use the whole path name to reference a field.
- You can use the same field name more than once in GROUP and named RECORD statements. However, when you reference a non-unique field, make sure the path specification is unique. For example, for the following data area:
record inhouse accnt ,d5 name ,a30 address ,a40 zip ,d10 record client accnt ,[100]d5 group customer ,[100]a name ,a30 group bldg ,a group address ,a street ,a4 zip ,d10 endgroup endgroup group contact ,a name ,a30 group address ,a street ,a40 zip ,d10 endgroup endgroup endgroup
the following paths are valid:
contact.name contact.address.street customer[5].bldg.address.street client.accnt inhouse.accnt inhouse.name
while the following paths are invalid because they are not unique:
name customer[1].name address.street accnt
If you specify one of these paths, the compiler generates a “Path specification is ambiguous” error (AMBIGUOUS).
- If you do not define structures with unique paths to all fields, you may end up with fields that you cannot access directly. For example, the fields in the first address group in the following group specification can never be accessed directly:
group customer ,a name ,a30 group address ,a street ,a40 zip ,d10 endgroup group contact ,a name ,a30 group address ,a street ,a40 zip ,d10 endgroup endgroup endgroup
Because partial path names can access fields, the second address group’s street field can be referenced in any of the following ways:
customer.contact.address.street customer.contact.street contact.street
The path specification
customer.address.street
generates a “Path specification is ambiguous” compiler error, because it could reference either the first address group or the second. The only way to reference the data in the first address group is by ranging. See Ranged references for information.
- If no other delimiters are present, the period character in a valid path specification takes precedence over any logical or Boolean operator. For example, if your group looks like this:
group var1 ,a group and ,d4 var2 ,d4 endgroup endgroup
and you reference it with the following path:
var1.and.var2
the Synergy compiler interprets this reference as a path, not a Boolean expression. (To use it as a Boolean expression, add a space before and after the .AND. operator.)
- The data type of the variable reference is the data type of the rightmost element in the path.
Object paths
You can refer to the current instance of a class within the class using the this keyword. For example,
this.mymethod()
Path specifications that contain classes are resolved in the following order:
- Local variables
- Local class members
- Inherited class members (moving up the inheritance chain)
- Local namespaces
- Imported namespaces
Real arrays
When referencing a real array, you must specify each declared dimension. For example, if you declare a variable as follows:
record brk ,[3,4]d1
the references brk[1,2] and brk[2,2] are valid because each dimension is referenced.
In contrast, brk[1] is not valid, and the compiler generates an “Incorrect number of dimensions” error (INVNUMDIM), because it specifies only one of the two dimensions.
The reference brk[ ], however, is valid and refers to the entire scope, or contents, of the dimensioned array as a single element. The maximum size of a scope reference is 65,535. If the array is larger than 65,535 bytes, the scope size is modulo 65,535.
If your dimension specification is larger than the declared size of its corresponding array dimension, you can reference outside the defined area up to the end of the data area, except for class data fields and when -qstrict or -qcheck is specified. We recommend using -qcheck in all development environments and -qstrict for all production builds.
Here’s an example that references a real array:
record demo alpha ,[3,2]d2 , 12 ,34, & 56 ,78, & 98 ,76 beta ,[2,4]a3, "JOE" ,"JIM" ,"TED" ,"SAM", & "LOU" ,"NED" ,"BOB" ,"DAN"
Data is referenced as follows:
Variable reference |
Data obtained |
---|---|
alpha[1,2] |
34 |
alpha[3,1] |
98 |
alpha[3] |
INVNUMDIM error |
alpha[3,3] |
JO |
alpha[4,1] |
JO |
alpha[ ] |
123456789876 |
beta[ ] |
JOEJIMTEDSAMLOUNEDBOBDAN |
beta[1,3] |
TED |
beta[2,4] |
DAN |
Variable references
You can specify variables in a simple, subscripted, or ranged form. Each form is described below. (This information also applies to all Synergex array classes: Synergex.SynergyDE.Collections.ArrayList, System.Collections.ArrayList, and System.Array.)
Simple references
A simple reference consists of the name of a data area, without any subscripting or range specifications. If it’s not defined as an array, the reference refers to the entire data area. Otherwise, the simple reference refers to the first element of the array or the element of the array at the specific index specified inside square brackets ([]) next to the variable name (i.e., variable_name[indexer]). In Synergy .NET, you can also use the square bracket format to access the indexer of any class that has an integer indexer method.
Here are some examples of simple references:
- amount
- a_result
- Y73
- days[m,l]
- cust[i,j].name
- var[]
- HELP
Subscripted references
A subscripted reference refers to an individual element within a list of like elements. The variable name is followed by the subscript value, which is enclosed in parentheses. The subscript value can be any numeric expression greater than zero and defines which element in the list is being accessed. For example, a subscript value of 1 represents the first element in the list.
Any variable reference can be subscripted, provided the data area is accessible to the routine. If the data area is inaccessible, or if the subscript value is less than one, an “Invalid subscript specified” error ($ERR_SUBSCR) is generated. Note that you cannot subscript beyond the defined size of class data fields and records or when the -qcheck compiler option is specified.
To understand how subscripted variables work, consider the following example.
Assume the following data division statements:
record demo alpha ,3d4, 3, 9876, 4321 beta ,a6, "ABCDEF" gamma ,d3, 545 delta ,4a2, "LM", "NP", "RS" ,"TV" episilon ,3d3.2, 6.75, 1.23, 8.00 group theta ,[3]a one ,d3, 123 two ,a3, "abc" endgroup
Data is allocated as follows (shaded boxes are not part of the data space):
Variable |
Data area (characters) |
|||||
---|---|---|---|---|---|---|
alpha(1) |
0 |
0 |
0 |
3 |
|
|
alpha(2) |
9 |
8 |
7 |
6 |
|
|
alpha(3) |
4 |
3 |
2 |
1 |
|
|
beta |
A |
B |
C |
D |
E |
F |
gamma |
5 |
4 |
5 |
|
|
|
delta(1) |
L |
M |
|
|
|
|
delta(2) |
N |
P |
|
|
|
|
delta(3) |
R |
S |
|
|
|
|
delta(4) |
T |
V |
|
|
|
|
epsilon(1) |
6 |
7 |
5 |
|
|
|
epsilon(2) |
1 |
2 |
3 |
|
|
|
epsilon(3) |
8 |
0 |
0 |
|
|
|
theta[1].one |
1 |
2 |
3 |
|
|
|
theta[1].two |
a |
b |
c |
|
|
|
theta[2].one |
1 |
2 |
3 |
|
|
|
theta[2].two |
a |
b |
c |
|
|
|
theta[3].one |
1 |
2 |
3 |
|
|
|
theta[3].two |
a |
b |
c |
|
|
|
Here are some sample variable references:
Variable reference |
Data obtained |
Explanation |
---|---|---|
demo |
000398764321ABCDEF545LMNPRSTV675123800123abc123abc123abc |
Refers to the entire data area. |
alpha |
0003 |
Refers to the first element of the array. |
alpha(1) |
0003 |
Refers to the first element of the array. |
alpha(3) |
4321 |
Refers to the third element of the array. |
alpha(4) |
ABCD |
Refers to the fourth group of four characters after the beginning of alpha’s data area (because a single alpha data item is four characters). |
alpha(5) |
EF54 |
Refers to the fifth group of four characters after the beginning of alpha’s data area. |
beta(2) |
545LMN |
Refers to the second group of six characters after the beginning beta’s data area (because a single beta data item is six characters). |
gamma |
PRS |
Refers to the third group of three characters after the beginning of gamma’s data area (because the variable alpha(1) has a value of 3 and a single gamma data item is three characters). |
delta(4) |
TV |
Refers to the fourth element of the array. |
delta(-3) |
$ERR_SUBSCR |
The subscript value is less than one. |
epsilon(3) |
8.00 |
Refers to the third element of the array. (The decimal point is shown here for clarity; it is not stored in the data area.) |
epsilon(4) |
123 |
Refers to the fourth group of three characters after the beginning of epsilon’s data area. |
theta[1].two(2) |
123 |
Refers to the second set of three characters after the first array element in the group. |
theta[3].two(2) |
$ERR_SUBSCR |
Refers to data outside of the data area accessible to the program. |
Alpha(4) and alpha(5) are both valid references because they don’t extend beyond the total data space allocated by the data division statements. Theta[3].two(2), on the other hand, attempts to refer past the end of the data area, which is not possible.
Notice that beta and gamma can be subscripted even though they are simple variable references.
A ranged reference is a variable reference followed by a range specification, either in absolute or relative form, that is enclosed in parentheses. In either case, the specification indicates starting and ending character positions relative to the beginning of the variable’s data space. The ranged variable’s value is the sequence of characters between the starting and ending positions, inclusive. If the range in a variable reference goes beyond the first variable, Synergy DBL continues to the next variable to obtain data.
You can range real arrays. Here’s an example:
brk[1,2](1,23)
You cannot range subscripted arrays. The following generates an error:
array(4)(1,23)
If the variable being ranged is implied-decimal, it is interpreted as decimal. Note that you cannot range beyond the defined size of class data fields and records or when the -qcheck compiler option is specified.
Absolute ranging
The absolute form of a range specification indicates the starting and ending positions of a character sequence using two numeric expressions separated by a comma.
Absolute ranging has the following format:
variable(start_pos,end_pos)
Here’s an example:
record abs alpha ,d8, 10203405 beta ,a13, "ABCDEFGHIJKLM" gamma ,[3,2]a3, "ABC", "DEF", & "GHI", "JKL", & "MNO", "PQR" group theta ,[3]a one ,d3, 123 two ,a3, "abc" endgroup
Variable reference |
Data obtained |
---|---|
alpha(2,4) |
020 |
alpha(8,13) |
5ABCDE |
beta(3,6) |
CDEF |
beta(alpha(2,3),alpha(7,8)) |
BCDE |
beta(alpha(2,3)+2,5) |
DE |
beta(13,14) |
MA |
gamma[1,2](2,3) |
EF |
gamma[2,2](3,6) |
LMNO |
alpha(6,3) |
$ERR_SUBSCR |
theta[1].two(2,8) |
bc123ab |
Note that the ability to access characters that extend past (or in front of) the specified field has been deprecated. For backward compatibility, the Synergy Runtime will continue to support this type of access. However, we recommend that you compile and run with -qcheck and make the appropriate changes to avoid future memory access violations.
The relative form of a range specification indicates the starting or ending character position and length of a character sequence range using two numeric expressions separated by a colon. The value that is referenced depends on the sign of the length. For positive lengths, the specified position is the starting point, and the value is the character sequence of the specified length that begins at that position. For negative lengths, the position is the ending point, and the value is the character sequence that begins the specified number of characters before that position.
Relative ranging has the following format:
variable(position:length)
Here’s an example of a data division:
record abs alpha ,d8, 10203405 beta ,a13, "ABCDEFGHIJKLM" gamma ,[3,2]a3, "ABC", "DEF", & "GHI", "JKL", & "MNO", "PQR" group theta ,[3]a one ,d3, 123 two ,a3, "abc" endgroup
Variable reference |
Data obtained |
---|---|
alpha(3:1) |
2 |
alpha(3:2) |
20 |
alpha(6:-2) |
34 |
beta(13:2) |
MA |
gamma[1,2](1:2) |
DE |
gamma[1,1](1:12) |
ABCDEFGHIJKL |
gamma[3,2](1:12) |
PQR123abc123 |
beta(2:-15) |
$ERR_SUBSCR |
theta[2].one(3:10) |
3abc123abc |
Note that the ability to access characters that extend past (or in front of) the specified field has been deprecated. For backward compatibility, the Synergy Runtime will continue to support this type of access. However, we recommend that you compile and run with -qcheck and make the appropriate changes to avoid future memory access violations.