Previous page Table of Contents Next page
The program syntax includes "type specifiers," which are used in situations where a type is required, for example after "is" and "as". To minimize verbosity, type specifiers are distinct from ordinary expressions, but are translatable to ordinary expressions by applying a simple naming convention.
A type specifier has exactly the same syntax as an ordinary expression except that every name in a type specifier automatically has a $ prefix added to it. The simplest type specifier is thus just the name of a class or protocol. The following operators are designed to be used in type specifiers:
$or | This infix operator returns the type union of its arguments. Unlike ordinary or, it is not a macro and both arguments are evaluated unconditionally. $or is also a function taking any number of arguments and is the pseudo-constructor for type unions. The 0-argument and 1-argument cases return $something and the argument respectively. The multi-argument case canonicalizes the union, removing members that are subtypes of other members, expanding members that are unions, and merging overlapping ranges. |
$( | As a prefix operator this is similar to the ordinary prefix left parenthesis macro, except that it encloses a type specifier instead of an ordinary expression. As an infix operator this is identical to the ordinary infix left parenthesis macro, which allows type specifiers to contain function calls. The arguments in such a function call are ordinary expressions, not type specifiers, and do not have $ prefixes added to them. |
$bits | This postfix operator (an infix operator macro that parses no right-hand side) returns the range of signed, two's complement integers that fit in the number of bits given as the left-hand side. Normally the left-hand side will be a literal integer but any expression that fits the $ prefix convention can be used. |
Note that, as in ordinary expressions, newline can only appear in a type specifier immediately following an infix operator.
A type-specifier parses into a P-expression which, when evaluated at run time, will yield a type. A type is a run-time object that represents a binary partition of all run-time objects into those that are instances of that type and those that are not.
A type object (a class, protocol, range, or type union) can also be used as a type specifier. It will be quoted. This can be useful in macros.
type-specifier is a syntactic type so you can use it in patterns.
When a type specifier is used in a def statement or in an optional or keyword parameter specifier, it can be followed by = or :=. So long as $= and $:= are not defined as infix operators there is no ambiguity. For the same reason, \"$," and \"$)" must not be defined as infix operators.
A type-specifier "my-class or false" translates to the expression "\$or($my-class, $false)" which evaluates to the type union that includes all instances of my-class and also the false object (the only instance of the false class), assuming the definitions of $or and $false in the PLOT module are in scope. This is a very common idiom.
A type-specifier such as "32 bits" translates to the expression "range(-1 << 31, (1 << 31) - 1)" or something equivalent, which evaluates to the type of all 32-bit signed integers, assuming the definition of $bits in the PLOT module is in scope.
To specify other integer ranges, use the following functions. These functions are designed to be used in type specifiers. Their arguments are ordinary expressions and are not subject to $ prefixing.
$integer-below(x is integer)returns a range of all integers strictly less than x.
$integer-above(x is integer)returns a range of all integers strictly greater than x.
$integer-between(start is integer, end is integer, optional: stride is integer = 1)returns a range of all integers greater than or equal to start and less than or equal to end. If stride is specified, it is the interval between consecutive elements of the range.
Previous page Table of Contents Next page