Previous Table of Contents Next


11.8.9. NEW

An allocation operation has the form

   NEW(T, ...)

where T is a reference type other than REFANY, ADDRESS, or NULL. The operation returns the address of a newly-allocated variable of T’s referent type; or if T is an object type, a newly allocated data record paired with a method suite. The reference returned by NEW is distinct from all existing references. The allocated type of the new reference is T.

It is a static error if T’s referent type is empty. If T is declared as an opaque type, NEW(T) is legal only in scopes where T’s concrete type is known completely or is known to be an object type.

The initial state of the referent generally represents an arbitrary value of its type. If T is an object type or a reference to a record or open array, then NEW takes additional arguments to control the initial state of the new variable.

If T is a reference to an array with k open dimensions, the NEW operation has the form

   NEW(T, n1, ..., nk)

where the ns are integer-valued expressions that specify the lengths of the new array in its first k dimensions. The values in the array will be arbitrary values of their type.

If T is an object type or a reference to a record, the NEW operation has the form

   NEW(T, Bindings)

where Bindings is a list of keyword bindings used to initialize the new fields. Positional bindings are not allowed.

Each binding f := v initializes the field f to the value v. Fields for which no binding is supplied will be initialized to their defaults if they have defaults; otherwise, they will be initialized to arbitrary values of their types. The order of the field bindings makes no difference.

If T is an object type, then Bindings can also include method overrides of the form m := P, where m is a method of T and P is a top-level procedure constant. This is syntactic sugar for the allocation of a subtype of T that includes the given overrides, in the given order. For example, NEW(T, m := P) is syntactic sugar for NEW(T OBJECT OVERRIDES m := P END).

11.8.10. Arithmetic Operations

The basic arithmetic operations are built into the language; additional operations are provided by the required floating-point interfaces.

To test or set the implementation’s behavior for overflow, underflow, rounding, and division by zero, see the required interface FloatMode. Modula-3 arithmetic was designed to support the IEEE floating-point standard but not to require it.

To perform unsigned word arithmetic operations, programs should use the routines in the required interface Word.

Implementations must not rearrange the computation of expressions in a way that could affect the result. For example, (x+y)+z generally cannot be computed as x+(y+z) because addition is not associative either for bounded integers or for floating-point values:

Operator + definition

   prefix   +(x: INTEGER)    : INTEGER
            +(x: Float)      : Float
   infix    +(x,y: INTEGER)  : INTEGER
            (x,y: Float)     : Float
            (x,y: Set)       : Set

As a prefix operator, +x returns x. As an infix operator on numeric arguments, + denotes addition. On sets, + denotes set union. That is, e IN (x + y) if and only if (e IN x) OR (e IN y). The types of x and y must be the same, and the result is the same type as both. In unsafe modules, + is extended to ADDRESS.

Operator - is defined as

   prefix  -(x: INTEGER)    : INTEGER
           (x: Float)       : Float
   infix   -(x,y: INTEGER)  : INTEGER
           (x,y: Float)    : Float
           (x,y: Set)      : Set

As a prefix operator, -x is the negative of x. As an infix operator on numeric arguments, - denotes subtraction. On sets, - denotes set difference. That is, e IN (x - y) if and only if (e IN x) AND NOT (e IN y). The types of x and y must be the same, and the result is the same type as both. In unsafe modules, - is extended to ADDRESS.

Operator * is defined as

   infix   *(x,y: INTEGER)  : INTEGER
          (x,y: Float)      : Float
          (x,y: Set)        : Set

On numeric arguments, * denotes multiplication. On sets, * denotes intersection. That is, e IN (x * y) if and only if (e IN x) AND (e IN y). The types of x and y must be the same, and the result is the same type as both.

Operator / is defined as

   infix   /(x,y: Float)    : Float
           (x,y: Set)       : Set

On reals, / denotes division. On sets, / denotes symmetric difference. That is, e IN (x / y) if and only if (e IN x) # (e IN y). The types of x and y must be the same, and the result is the same type as both.

DIV and MOD operators are defined as

   infix   DIV  (x,y: INTEGER)  : INTEGER
   infix   MOD  (x,y: INTEGER)  : INTEGER
           MOD  (x, y: Float)   : Float

The value x DIV y is the floor of the quotient of x and y—that is, the maximum integer not exceeding the real number z such that z * y = x. For integers x and y, the value of x MOD y is defined to be x - y * (x DIV y).

This means that for positive y, the value of x MOD y lies in the interval [0 .. y-1], regardless of the sign of x. For negative y, the value of x MOD y lies in the interval [y+1 .. 0], regardless of the sign of x.

If x and y are floats, the value of x MOD y is x - y * FLOOR(x / y). This may be computed as a Modula-3 expression or by a method that avoids overflow if x is much greater than y. The types of x and y must be the same, and the result is the same type as both.

ABS operator is defined as

   ABS  (x: INTEGER)   : INTEGER
        (x: Float)     : Float

ABS(x) is the absolute value of x. If x is a float, the type of ABS(x) is the same as the type of x.


Previous Table of Contents Next