Skip to main content

Software > Software Development > IBM REXX Family >

NetRexx

Technical detail

Other language enhancements

This section describes additional features supported by the NetRexx reference implementation that are expected to be included in some future NetRexx language definition, should there be an updated definition.

The features here are:

Adapter classes

The class instruction [NRL 74] is used to introduce a class. In NetRexx 1.0, this instruction could specify a modifier to indicate that it is abstract, final, or an interface. An alternative keyword is supported in NetRexx 1.1, adapter, which indicates that the class is an adapter class. For example:

  class Macavity adapter implements MouseListener

An adapter class is a class that is guaranteed to implement all unimplemented abstract methods of its superclasses and interface classes that it inherits or lists as implemented on the class instruction.

If any unimplemented methods are found, they will be automatically generated by the language processor. Methods generated in this way will have the same visibility and signature as the abstract method they implement, and if a return value is expected then a default value is returned (as for the initial value of variables of the same type: that is, null or, for values of primitive type, an implementation-defined value, typically 0). Other than possibly returning a value, these methods are empty; that is, they have no side-effects.

An adapter class provides a concrete representation of its superclasses and the interface classes it implements. As such, it is especially useful for implementing event handlers and the like, where only a small number of event-handling methods are needed but many more might be specified in the interface class that describes the event model.[1]

An adapter class cannot be an interface or an abstract class (or have any abstract methods), and cannot be a final class.

Array initializers

A new form of simple term [NRL 41] is defined: the array initializer. The array initializer is recognized if it does not immediately follow (abut) a symbol, and has the form[2]

  '['expression[,expression]...']'

An array initializer therefore comprises a list of one or more expressions, separated by commas, within brackets. When an array initializer is evaluated, the expressions are evaluated in turn from left to right, and all must result in a value. An array [NRL 71] is then constructed, with a number of elements equal to the number of expressions in the list, with each element initialized by being assigned the result of the corresponding expression.

The type of the array is derived by adding one dimension to the type of the result of the first expression in the list, where the type of that expression is determined using the same rules as are used to select the type of a variable when it is first assigned a value [NRL 65]. All the other expressions in the list must have types that could be assigned to the chosen type without error.

For example, in

  var1=['aa', 'bb', 'cc']  var2=[char 'a', 'b', 'c']  var3=[String 'a', 'bb', 'c']  var4=[1, 2, 3, 4, 5, 6]  var5=[[1,2], [3,4]]

the types of the variables would be Rexx[], char[], String[], Rexx[], and Rexx[,] respectively. In a binary class in the reference implementation, the types would be String[], char[], String[], int[], and int[,].

Array initializers are most useful for initializing properties and variables, but like other simple terms, they may start a compound term. So, for example

  say [1,1,1,1].length

would display 4.

Notes:

  1. An array of length zero cannot be constructed with an array initializer, as its type would be undefined. An explicitly typed array constructor (for example, int[0]) must be used.
  2. Array initializers require Java 1.1.

Array partial terms

If a partial term results in a dimensioned array, its type is treated as type Object so that evaluation of the term can continue [NRL 46]. For example, in

  ca=char[] "tosh"  say ca.toString()

the variable ca is an array of characters; in the expression on the second line the method toString() of the class Object will be found. (In the reference implementation, this would return an identifier for the object.)

Binary methods

The method instruction [NRL 93] is used to introduce a method. The binary keyword may be added to the instruction to indicate that the method is a binary method.

In binary methods, literal strings and numeric symbols are assigned native string or binary (primitive) types, rather than NetRexx types, and native binary operations are used to implement operators where possible. When binary is not in effect (the default), terms in expressions are converted to NetRexx types before use by operators. The section Binary values and operations [NRL 142] describes the implications of binary methods and classes in detail.

Notes:

  1. Only the instructions inside the body of the method are affected by the binary keyword; any arguments and expressions on the method instruction are not affected (this ensures that a single rule applies to all the method signatures in a class).
  2. All methods in a binary class are binary methods; the binary keyword on methods is provided for classes in which only the occasional method needs to be binary (perhaps for performance reasons). It is not an error to specify binary on a method in a binary class.

copyIndexed(source)

copies the collection of indexed sub-values [NRL 70] of source into the collection associated with string, and returns the modified string. The resulting collection is the union of the two collections (that is, it contains the indexes and their values from both collections). If a given index exists in both collections then the sub-value of string for that index is replaced by the sub-value from source.

The non-indexed value of string is not affected.

Example:

Following the instructions:

  foo='def'  foo['a']=1  foo['b']=2  bar='ghi'  bar['b']='B'  bar['c']='C'  merged=foo.copyIndexed(bar)

then:

  merged['a'] => '1'  merged['b'] => 'B'  merged['c'] => 'C'  merged['d'] => 'def'

Deprecation

Classes, methods, and properties may be designated as deprecated, which implies that a better alternative is available and documented. A compiler can use this information to warn of out-of-date or other use that is not recommended.

The class instruction [NRL 74] is used to introduce a class. The deprecated keyword may be added to the instruction to indicate that the class (and all its methods and properties) is deprecated. For example:

  class action deprecated

The method instruction [NRL 93] is used to introduce a method. The deprecated keyword may be added to the instruction to indicate that the method is deprecated. For example:

  method madness deprecated

Note that individual methods in interface classes cannot be deprecated; the whole class should be deprecated in this case.

The properties instruction [NRL 105] is used to define the attributes of following property variables. The deprecated keyword may be added to the instruction to indicate that the following properties are deprecated. For example:

  properties public deprecated    gaol=Months 11    jail=Days 12

Note: In the reference implementation, the intermediate .java file must be compiled with a Java 1.1 compiler for the information about deprecation to be reflected in the resulting .class file.

Dollar sign in symbols

The dollar sign character (?$’) may now be used in symbols (for instance, variable names). It is recommended that it only be used in mechanically generated programs or where otherwise essential.

Euro currency character

The euro character ('\u20ac') is now treated in the same way as the dollar character (that is, it may be used in the names of variables and other identifiers). It is recommended that it only be used in mechanically generated programs or where otherwise essential.

Note that only UTF8-encoded source files can currently use the euro character, and a 1.1.7 (or later) version of a Java compiler is needed to generate the class files.

Hexadecimal and binary numeric symbols

Numeric symbols (symbols in a NetRexx source program that start with a digit, [NRL 35]) may now be expressed in a hexadecimal or binary notation.

A hexadecimal numeric symbol describes a whole number, and is of the form nXstring. Here, n is a simple number with no decimal part (and optional leading insignificant zeros) which describes the effective length of the hexadecimal string, the X (which may be in lowercase) indicates that the notation is hexadecimal, and string is a string of one or more hexadecimal characters (characters from the ranges ?a-f’, ?A-F’, and the digits ?0-9’).

The string is taken as a signed number expressed in n hexadecimal characters. If necessary, string is padded on the left with '0' characters (note, not ?sign-extended’) to length n characters.

If the most significant (left-most) bit of the resulting string is zero then the number is positive; otherwise it is a negative number in twos-complement form. In both cases it is converted to a NetRexx number which may, therefore, be negative. The result of the conversion is a number comprised of the Arabic digits 0-9, with no insignificant leading zeros but possibly with a leading '-'.

The value n may not be less than the number of characters in string, with the single exception that it may be zero, which indicates that the number is always positive (as though n were greater than the the length of string).

Examples:

  1x8    => -8  2x8    => 8  2x08   => 8  0x08   => 8  0x10   => 16  0x81   => 129  2x81   => -127  3x81   => 129  4x81   => 129  04x81  => 129  16x81  => 129  4xF081 => -3967  8xF081 => 61569  0Xf081 => 61569

A binary numeric symbol describes a whole number using the same rules, except that the identifying character is B or b, and the digits of string must be either 0 or 1, each representing a single bit.

Examples:

  1b0    => 0  1b1    => -1  0b10   => 2  0b100  => 4  4b1000 => -8  8B1000 => 8

Note: Hexadecimal and binary numeric symbols are a purely syntactic device for representing decimal whole numbers. That is, they are recognized only within the source of a NetRexx program, and are not equivalent to a literal string with the same characters within quotes.

If and when enhancements

The if clause in the if instruction [NRL 80] and the when clause in the select instruction [NRL 108] both have the same form and serve the same purpose, which is to test a value either for being 1 or (for a when clause in a select case construct) being equal to the case expression.

In both if and when clauses multiple expressions may now be specified, separated by commas. These are evaluated in turn from left to right, and if the result of any evaluation is 1 (or equals the case expression) then the test has succeeded and the instruction following the associated then clause is executed.

Note that once an expression evaluation has resulted in a successful test, no further expressions in the clause are evaluated. So, for example, in:

  -- assume 'name' is a string  if name=null, name='' then say 'Empty'

then if name does not refer to an object it will compare equal to null and the say instruction will be executed without evaluating the second expression in the if clause.

Imports, automatic (clarification)

In the reference implementation, the fundamental NetRexx and Java package hierarchies are imported by default [NRL 82], as though the instructions:

  import netrexx.lang.  import java.lang.  import java.io.  import java.util.  import java.net.  import java.awt.  import java.applet.

had been executed before the program begins.

In addition, classes in the current (working) directory are imported if no package instruction is specified. If a package instruction is specified then all classes in that package are imported.

[The Java packages are now listed explicitly, because new packages added in Java 1.1 or Java 1.2 are not included in the automatic import list.]

Imports, explicit

When a class is imported explicitly, for example, using

  import java.awt.List

this indicates that the short name of the class (List, in this example) may be used to refer to the class unambiguously. That is, using this short name will not report an ambiguous reference warning (as it would without the import instruction, because a java.util.List class has been added in Java 1.2).

It follows that:

  • Two classes imported explicitly cannot have the same short name.
  • No class in a program being compiled can have the same short name as a class that is imported explicitly.

because in either of these situations a use of the short name would be ambiguous.

Note also that an explicit import does not import the minor or dependent classes associated with a name; they each require their own explicit import (unless the entire package is imported).

Numeric enhancement

The numeric instruction [NRL 98] is used to change the way in which arithmetic operations are carried out by a program.

One or more numeric instructions may now be placed before the first class instruction in a program; they no longer imply the start of a class. The settings they make then apply to all classes in the program (except interface classes), as though the numeric instructions were placed immediately following the class instruction in each class.

Private and shared interfaces

The class instruction [NRL 74] is used to define interface classes. The restriction that interface classes cannot be private [NRL 75] has now been removed; they may be also be shared, which means the same as private for classes.

Properties enhancements

The properties instruction [NRL 105] is used to define the attributes of following property variables. There are two enhancements to the instruction:

  • The modifier for properties may include a new alternative: transient. Properties with this modifier are known as transient properties. For example:
      properties public transient    wayfarer=int 7
    Transient properties are properties which should not be saved when an instance of the class is saved (made persistent).
  • The unused keyword may be added to the instruction in addition to a visibility keyword (which must be private) and any modifier. It may be at any position within the instruction.
    For example:
      properties private constant unused    -- Serialization version    serialVersionUID=long 8245355804974198832
    The unused keyword indicates that the private properties which follow are not referenced explicitly in the code for the class, and so a language processor should not warn that they exist but have not been used.

Select case

The select instruction [NRL 108] is used to conditionally execute one of several alternatives.

A new keyword, case, has been added to the select instruction; it must follow any label or protect phrase, and must be followed by an expression.

When case is used, the expression following it is evaluated at the start of the select construct. The result of the expression is then compared, using the strict equality operator (==), to the result of evaluating the expression in each of the when clauses in turn until a match is found. As usual, if no match is found then control will pass to the instruction list (if any) following otherwise, and in this situation the absense of an otherwise is a run-time error.

For example, in:

  select case i+1    when 1 then say 'one'    when 1+1 then say 'two'    when 3, 4, 5 then say 'many'  end

then if i had the value 1 then the message displayed would be ?two’.

The third when clause in the example demonstrates the use of the when clause enhancement in this context. Multiple expressions are allowed, separated by commas, each of which is evaluated in turn from left to right. As soon as one matches the case expression, execution of the when clause stops and the instruction following the associated then clause is executed.

Notes:

  1. When case is used, the result of evaluating the expression following each when no longer has to be 0 or 1. Instead, it must be possible to compare each result to the result of the case expression.
  2. The case expression is evaluated only on entry to the select construct; it is not re-evaluated for each when clause.
  3. An exception raised during evaluation of the case expression will be caught by a suitable catch clause in the construct, if one is present. Similarly, evaluation of the case expression is protected by the protect phrase, if one is present.
  4. In the reference implementation, a select case construct will be translated into a Java switch construct provided that it meets the following criteria:
    • The type of the case expression is byte, char, int, or short.
    • The value of all the expressions on the when clauses are primitive constants (that is, they consist of only constants of primitive types and operators valid for them and so may be evaluated at compile time).
    • No two expressions on the when clauses evaluate to the same value.
    • It is not subject to tracing.
    Under these conditions the semantics of the switch construct match those defined for select. The example shown above would be translated to a switch construct if i had type int and options binary were in effect.

Shared classes, properties, and methods

Classes, properties, and methods have a specified visibility. A new form of visibility, known as shared, is available in NetRexx. A shared class, property, or method is one that is visible within the current package but is not visible outside the package. Shared properties and methods cannot be inherited by classes outside the package.

The properties instruction [NRL 105] is used to define the attributes of following property variables. The visibility for properties may include a new alternative, shared, which indicates that the following properties are shared and therefore cannot be inherited by classes outside the package. For example:

  properties shared constant    hours=int 24    minutes=int 60

The method instruction [NRL 93] is used to introduce a method. The visibility for methods may include a new alternative, shared, which indicates that the method is shared and therefore cannot be inherited by classes outside the package. For example:

  -- This method is only visible to the current package  method inpackage shared

The class instruction [NRL 74] is used to introduce a class. The shared keyword on the class instruction means exactly the same as the keyword private, and is accepted for consistency with the other meanings of shared. For clarity, it is recommended that, if required, shared be specified rather than private.

Note that interface classes may now be shared.

Special names

The following special names are added to the list [NRL 118]:

class

The object of type Class that describes a specific type. This word is only recognized as the second part of a compound term, where the evaluation of the first part of the term resulted in a type or qualified type.

Example:

  obj=String.class  say obj.isInterface /* would say '0' */
Note that this special name requires Java 1.1.
sourceline

The line number of the first token [NRL 33] of the current clause in the NetRexx program, returned as a string of type Rexx. This will be one or more Arabic numerals, with no leading blanks, zeros, or sign, and no trailing blanks or exponent.

sourceline can only appear alone, or at the start of a compound term.

Trace enhancements

The trace instruction [NRL 111] is used to control the tracing of the execution of NetRexx methods. Three enhancements have been made to tracing:

  1. The trace instruction has a new option, var, which allows variables to be traced selectively. This option is described in detail in the next section. Note that the trace special word can now have the value ?var’.
  2. One or more trace instructions may now be placed before the first class instruction in a program; they no longer imply the start of a class. The settings they make (both overall and trace var selections) then apply to all classes in the program (except interface classes), as though the trace instructions were placed immediately following the class instruction in each class.
  3. If a trace line is produced in a different context (program or thread) from the preceding trace line (if any) then a trace context line is shown. This shows the name of the program that produced the trace line, and also the name of the thread (and thread group) of the context.
    The thread group name is not shown if it is main, and in this case the thread name is then also suppressed if its name is main.

Trace Var

The trace instruction [NRL 111] is used to control the tracing of the execution of NetRexx methods. A new option, var, is now available.

The trace var instruction adds names to a list of monitored variables; it can also remove names from the list. If the name of a variable in the current class or method is in the list, then trace results is turned on for any assignment, loop, or parse instruction that assigns a new value to the named variable.

Variable names are specified by listing them after the var keyword. Each name may be optionally prefixed by a + or a - sign. A + sign indicates that the variable is to be added to the list of monitored variables (the default), and a - sign indicates that the variable is to be removed from the list. Blanks may be added before and after variable names and signs to separate the tokens and to improve readability.

For example:

  trace var a b c  -- now variables a, b, and c will be traced  trace var -b -c d  -- now variables a and d will be traced

Notes:

  1. Names in the list following the var keyword are simple symbols that name variables in the current class or current method. The variables may be properties, method arguments, or local variables, and may be of any type, including arrays. The names are not case-sensitive; any variables whose names match, independent of case, will be monitored.
  2. No variable name can appear more than once in the list on one trace var instruction. However, it is not an error to add the name of a variable which does not exist or is not then assigned a value. Similarly, it is not an error to remove a name which is not currently being monitored.
  3. One or more trace var instructions (along with one other trace instruction) are allowed before the first method in a class. They all modify an initial list of monitored variables which is then used for all methods in the class. Similarly, trace var instructions are allowed before the first class in a program, in which case they apply to all classes (except interface classes).
  4. Other trace instructions do not affect the list of monitored variables. The trace off instruction may be used to turn off tracing completely; in this case trace var (with or without any variable names) will then turn the tracing of variables back on, using the current (or modified) variable list.
  5. For a parse instruction, only monitored variables have their assignments traced (unless trace results is in effect).

Type operation enhancement

A type on the left hand side of an operator that could be a prefix operator (+, -, or \) is now assumed to imply a cast (type concatentation) after the prefix operator is applied to the right-hand operand, rather than being an error.

For example:

  x=int -y

now means that -y is evaluated, and then the result is cast to int before being assigned to x. It would previously need to have been written x=int (-y) to avoid being treated as subtracting y from the type int (which is not possible).

Footnotes:

[1]  For example, see the ?Scribble’ sample in the NetRexx package.

[2]  The notations '[' and ']' indicate square brackets appearing in the NetRexx program.

Supplement to The NetRexx Language by Mike Cowlishaw, mfc@uk.ibm.com (ISBN 0-13-806332-X, 197pp, Prentice-Hall, 1997).

 

 

PreviousTable of contents Next
We're here to help
Easy ways to get the answers you need.
Request a quote
E-mail IBM

or call us at
877-426-3774
Priority code:
104CBW67