. navigate
 Navigate
4. Types left arrow
x
right arrow 6. Statements
Red Reference Manual
5.

EXPRESSIONS

Data Items     Operators & Operands     Primary     Built-in & User-defined Literals & Constructors
Manifest Exp & Conditional Translation     Built-in Constructors     Value Resolution & User-defined Values    



5.   EXPRESSIONS


5.1  DATA ITEMS

There are five kinds of data items: defined variables, dynamic variables, defined constants, readonly data items, and temporary data items. Defined variables and constants are described in Section 4.2. Readonly and temporary data items are discussed below.

The term variable is used to refer to defined and dynamic variables. The term constant is used to refer to defined constants, readonly data items, and temporary data items.



RULES

A data item can hold a single value. The value of any data item may be accessed (i.e., read). The value of variables (both defined and dynamic) and their components may also be modified. The value of other data items may not be modified.

A readonly data item is a variable whose use is restricted in certain contexts. Within those contexts, the value of the readonly data item cannot be modified directly. In some cases, however, it is possible for the value of the readonly data item to be modified indirectly, outside the context.

  1. When an actual parameter variable is bound to a READONLY formal parameter, the formal parameter is treated as a readonly data item within a deferred declaration. Changes to the actual parameter variable will change the formal parameter (see Section 7.3). This is the only way that dynamic variables may be made readonly.

  2. Variables imported READONLY into a compound declaration are treated as readonly data items within the compound declaration. The variable may be changed outside the compound declaration (see Section 3.7).

  3. Variables exported READONLY from a capsule into a scope where the capsule is invoked are treated as readonly data items within that scope. The variable may be changed within the capsule (see Section 8.2).

  4. Variables exported from a capsule and exposed as READONLY are treated as readonly data items within the scope in which the capsule is invoked. The variable may be changed within the capsule (see Section 8.1).

A temporary data item is the result of a built-in or user-defined literal or constructor (see Sections 2.3.5, 5.6, and 5.7), the result of a function or operator (see Section 7.2), or the result of attribute inquiry (see Section 4.5.3). For convenience, these results will be referred to as values.

The lifetime of all defined variables and constants and formal parameters (and their components) is the lifetime of the scope immediately containing their definition. The lifetime of dynamic variables extends from their creation by the allocation statement until the time when they can no longer be accessed. The lifetime of temporary data items extends from the time they are produced until the end of the elaboration of the construct in which the temporary is used.

Initialization can optionally be specified whenever a variable is created. For some types, if no initialization is specified, there is a default initial value. Otherwise, the variable is uninitialized until a value has been assigned to it. An attempt to access the value of an uninitialized variable will raise the X_INIT exception.



5.2  OPERATORS AND OPERANDS

expression diagram
11 - type comparison   13 - subtype comparison   26 - expression   27 - primary

An expression is a computational rule for producing a data item. An expression can be a single operand or a combination of operators and operands. Operators are either prefix or infix operators. Prefix operators immediately precede an operand. Infix operators operate upon a left and right operand to produce a value. The association of operands to an operator is determined by the precedence of operators. Operands are associated with the operator of higher precedence.

Parentheses can be used to modify the association (see Section 5.3).



RULES

Operator symbol 1 xx is a prefix operator. Valid prefix operator symbols are +, -, and NOT. Operator symbol 2 is an infix operator. Valid infix operator symbols are **, *, /, MOD, DIV, &, +, -, =, /=, <. <=, >, >=, IN, AND, OR, and XOR.

The operands of prefix and infix operators are determined based on the built-in precedence of operators given below:

operator precedence example

Within a precedence level, associativity is left to right.


RED RATIONALE

RED uses the ALGOL 60 precedence rules, as described by Niklaus Wirth



NOTES

Arithmetic Operators

    Arithmetic operators (infix +, -, *, /, **, modulo (MOD), integer division (DIV), and prefix +, -) take operands of arithmetic types (INT, FLOAT, and FIXED) and return arithmetic values.


Concatenation Operator

    A concatenation operator (infix &) takes string and enumeration operands and produces a string, or takes one-dimensional array operands and produces a one-dimensional array.


Relational Operators

    Relational operators (infix *, not equal (/=), <, <=, >, >=, set membership (IN)) take arithmetic, boolean, enumeration, string, and notoperands and return a boolean. For boolean operands, only - and /= are defined. For arithmetic operands, the relational operators define a numerical ordering. For enumeration and string operands, the relational operators define a collating sequence. For set operands, the relational operators define a subset relationship.


Logical Operators

    Logical operators (infix AND, OR, XOR, and prefix NOT) take boolean operands and produce a boolean, or take set operands and produce a set. For boolean operands, the logical operators define and, or, exclusive or, and complement. For set operands, the logical operators define set intersection, union, symmetric difference, and complement.


    A type or subtype comparison is one which is used to compare types or subtypes and returns a boolean value. This form of expression is described in Section 4.5.1 and 4.5.2.

    It is possible to overload the built-in definitions of operators to allow user-defined operators (see Section 13.2).



EXAMPLES

operator and operand examples



5.3  PRIMARY

primary diagram
D - literal   25 - attribute inquiry   26 - expression   28 - variable   29 - constant
30 - referencing form   31 - constructor   35 - resolved constant   51 - function invocation primary




referencing form diagram
C - identifier   14 - range   26 - expression   27 - primary

A primary is the basic form of an expression.

A variable can be an entire variable or one or more components of a variable. A constant can be an entire constant or one or more components of a constant. A constant can be either a reference to a defined constant, written as a literal, created by a constructor, the result of a function, or an attribute value.

A variable or constant which is a component of a record or union type is referenced by dot selection. An underlying dynamic variable of an indirect variable or constant (see Section 4.4.3) is referenced by the dot selector .ALL. A variable or constant which is one or more components of an array or string is referenced by subscripting to produce a single component or slice.



RULES

Identifier 1 must be associated with a variable or constant in the scope immediately containing the expression containing identifier 1.

The result of elaboration of a parenthesized expression is the result of elaboration of the expression.


RED RATIONALE

RED has adopted a simple rule concerning parenthesization:

  1. when parentheses are present, they dictate the grouping of operators with operands, and

  2. when parentheses are absent, consecutive operators at the same precedence level in an expression are grouped with their operands from left to right.



NOTES

     Rules for subscripting are described in Appendix C under ARRAY and STRING types. Rules for dot selection are described in Appendix C under RECORD and UNION types, and in Section 13.4. User-defined subscripting and dot selection are described in Section 13.4. Literals and constructors are described in Section 5.4. User-defined literals and constructors are described in Section 13.5. Function invocation primaries are described in Section 7.2. Attribute inquiry is described in Section 4.5.3. Resolved constants are described in Section 5.7.




5.4  BUILT-IN AND USER-DEFINED LITERALS AND CONSTRUCTORS

Literals and constructors are used to specify values for variables and constants. Literals are provided for specifying values of each basic language type. For example,

various literals examples

The literal, NIL, is also provided to specify a value for all indirect types. Chapter 2 gives forms for built-in literals and Section 5.5 gives rules for their types and subtypes.

Values for variables consisting of multiple components are written using constructors. For example,

constructors examples

Section 5.6 gives rules for built-in constructors.

Users can also define literal and constructor forms for new types (see Section 13.5). For example,

defining literal and constructor examples




5.5  MANIFEST EXPRESSIONS AND CONDITIONAL TRANSLATION

A manifest expression is an expression whose value is known during translation. The simplest manifest expression is a literal. Manifest expressions have two important uses: first, they are used to achieve conditional translation and second, they are used as replacement elements for generic parameters with value generic constraints (see Section 11.3.4).



RULES

Manifest Expressions

The following are manifest expressions:

  1. any literal

  2. the result of any of the following built-in operators, when their operands (actual parameters) are manifest

    manifest operand examples

  3. a parenthesized expression, where the expression is a manifest expression;

  4. references to constants defined with the form

          CONST id := exp;

    where exp is a manifest expression; and

  5. references to generic parameters with a value generic constraint (see Section 11.3.4).

No other expressions are manifest expressions.

All built-in arithmetic operations in manifest expressions are performed using the maximum precision and range of the target system.


Conditional Translation

If the condition of an if or case statement is a manifest expression, code is generated only for the selected alternative body. Any translation time errors that occur in those bodies not selected will be treated as warnings and will not prevent program execution.

If the subtype constraint (i.e., the tag value) of a union subtype (see Appendix C.6) is manifest, then only space for that component is reserved.



NOTES

    Manifest expressions are guaranteed to be elaborated at translation time; however, this does not prohibit the translator from also elaborating any other expression whose value it can determine.

    Section 5.7 gives rules for type and subtype resolution of manifest expressions.


RED RATIONALE

Expressions which are manifest -- i.e., whose values are guaranteed to be computable at translation time - are important because type checking is to be performed at translation time, and the user can define type-determining properties which are specified by expressions.

Manifest values are substitutable for literals of predefined types. Thus literals are manifest, declared constants initialized to manifest expressions are manifest, and built-in operations applied to manifest expressions yield manifest values. Although the set of manifest values is limited, it provides the flexibility which is needed in dealing with type properties and conditional translation.



EXAMPLES

1) Conditional translation

conditional translation example



5.6  BUILT-IN CONSTRUCTORS

built-in constructors diagram
C - identifier   14 - range   26 - expression

Constructors are used to construct values for records, unions, arrays, and sets.



RULES

Values can only be constructed for assignable types.

For a record or union constructor which is resolved to a record type, there must be a value specified for each component of the record type, and the components must be specified in the same order as in the record type.

For a record or union constructor which is resolved to a union type, there must be a value specified for only one component of the union type.

For an array constructor which is resolved to some array subtype, there must be a single value specified for each component. The range form is used to specify a single value for some contiguous range of components.

For a set constructor which is resolved to a set type, there can be zero or more values specified, where each value must have the component type of the set. An empty set constructor is the value of an empty set.



NOTES

    Section 5.7 gives rules for type and subtype resolution of constructors.



EXAMPLES

constructors example



5.7  VALUE RESOLUTION AND USER-DEFINED VALUES

resolved constant diagram
10 - type   12 - subtype   27 - primary





The resolved constant has two purposes: it can be used to create a user-defined literal or constructor; and it can be used to specify the type or subtype of a manifest expression or constructor, when the expression would otherwise be ambiguous.



User-Defined Values

A literal or constructor can be defined for a user-defined type by overloading the definition of #. This is described in Section 13.5.



Type and Subtype Resolution

All expressions must have both a type and a subtype. For many kinds of expression, the type and subtype of the expression depends only upon the expression itself. For manifest expressios and constructors, the type and subtype may also depend upon the context in which the manifest expression or constructor appears. If the context is the right hand side of an assignment, then the type and subtype are those of the left hand side. For example,

type and subtype resolution example

and

type and subtype resolution example

In some cases, the type and/or subtype of a literal or constructor cannot be determined from the literal or constructor and its context. In these cases, the type or subtype must be explicitly specified. For example,

type and subtype resolution example

and

type and subtype resolution example

Manifest expressions can also depend upon context for their type and subtype. For example,

type and subtype resolution example

The type or subtype of a manifest expression or of a constructor are resolved based on the context in which they appear. If context is not sufficient, a default is provided for integer, enumeration, floating point, or string values. In cases where resolution cannot be done from the context or default alone, the resolved constant form can be used to explicitly specify a type or a subtype.



RULES

Context Resolution

If a type or subtype unresolved expression appears:

  1. on the right hand side of an assignment, it is resolved to the subtype of the left hand side.
  2. as an actual parameter, it is resolved to the specified type or subtype of the corresponding formal parameter, if there is no ambiguity

  3. within a constructor, it is resolved to the component subtype of the constructed subtype.

  4. in a resolved constant form, it is resolved to the specified type or subtype.

  5. for unresolved float expressions, which appear as one operand of a built-in binary float operator (+, -, *, /, **, relationals), the precision is resolved to be equal to that of the other operand.



Default Resolution

When a subtype cannot be resolved from context, in the following cases a default subtype is used. For an expression with value v, the default subtype for various types is shown below.

INT the default subtype is INT(v..v)
ENUM[...] the default subtype is ENUM[...]
FLOAT the default subtype is FLOAT(p,v..v) where p is the maximum of the default precisions of all the float literals that are part of the manifest expression
STRING[ENUM[...]] the default subtype is STRING[ENUM[...]] (len) where len is the number of components in v




Explicit Resolution

When a type or a subtype cannot be resolved from context or default, the manifest expression or constructor is written as a resolved constant. The unresolved expression preceding the # is resolved, if possible, to the type or subtype following #.



NOTES

    The resolved constant form can always be used to resolve an expression with an ambiguous type or subtype.


Data Items     Operators & Operands     Primary     Built-in & User-defined Literals & Constructors
Manifest Exp & Conditional Translation     Built-in Constructors     Value Resolution & User-defined Values    

4. Types left arrow
x
right arrow 6. Statements


Overview

Requirements
     Strawman
     Woodenman
     Tinman
     Ironman
     Steelman

RED Reference
RED Rationale

Types in RED
Time/Life Computer Languages
Memories

Site Index

Overview             Reference ToC             Rationale ToC             Site Index



Home   Favorites   Map

IME logo Copyright © 2009, Mary S. Van Deusen