Oil Reference Manual



An OIL specification is composed of a list of statements. The statements
describe relationships among identifiers which the library functions
will interpret as describing an operator identification scheme.
With the specification language a compiler writer defines four sets of
mutually exclusive identifiers:
-
Operators represent both indications and denotations. That is an
operator can be used as an indication and also have a type signature.
-
Types represent primitive types. Unlike the types which are
instantiations of classes.
-
Classes represent parameterized sets of operators. A new version
of each operator is constructed for each instantiation of the class.
Likewise each instantiation of a class creates a new type which is not
primitive.
-
Type Sets represent a set of primitive types which can be used to
construct multiple instances of an operator; one for each element in the
type set.
The rest of this chapter of the manual describes the syntax
of the specification language by covering the three main
lexical and syntactic constructs:
Identifiers, Statements and Comments.
An identifier in an OIL specification is a sequence of characters which:
-
begins with an alphabetic character: A-Z, a-z
-
continues with an alphanumeric or underscore character: A-Z, a-z, 0-9, _.
Examples:
iAdd, Fmul2
Identifiers are defined both explicitly and implicitly. OPER and
COERCION statements explicitly define operators. CLASS statements
explicitly define classes. SET statements explicitly define sets.
Types are all implicitly defined; if an identifier appears only in a
function signature or as a type element in a type set expression then it
is a type. If the indication in an INDICATION statement has no defining
OPER statement it is implicitly defined as an operator.
An identifier can only be in one of the sets:
operator, type, class or type set.
Constraints:
An identifier can denote a type or an operator but not both.
An identifier list is a sequence of identifiers separated by commas.
Since OIL produces names to be used in your attribute grammar, you must
not use a reserved word of your attribute grammar as an identifier in an
OIL specification.
Examples:
iAdd,iMul or Fmul, Fadd, Fdiv
C-style comments, beginning with /* and ending with */, are
allowed in an OIL specification.
A comment may appear anywhere that white space might be appropriate.
There are five types of statements in OIL:
-
Operator definition which defines the functional type signature of
one or more operator denotations.
-
Coercion operator definition which defines a coercion operator and
the ability for the source type of the coercion operator
to be acceptable in place of the destination type of the
coercion operator when performing operator identification.
-
Operator identification which defines an operator indication and
a set of operator denotations which the indication may identify.
-
Class definition which defines a set of operators to be
constructed when a parameterized type is instantiated.
-
Type set definition which defines an identifier to represent a
set of types and allows explicit multiple operator definitions when used
in an operator definition.
The basic form of an operator definition is:
`OPER' <Op-name> `(' <arg-list> `)' `:' <result-id> `;'
where:
<Op-name> is an operator identifier.
<arg-list> is a list of identifiers separated with commas which
describes the argument signature of the operator.
<result-id> is an identifier which determines the result type of
the operator.
The <result-id> and each identifier in the <arg-list> may
be either a primitive type name, a SET name or if in a CLASS definition
then they may refer to the CLASS name being defined or one of the
parameters to the CLASS definition. see Function Signatures
Constraints:
Any given <Op-name> can appear only once in all definition statements.
An example is:
OPER iAdd( int_t, int_t ): int_t;
In the example operator definition statement above, `iAdd' is
defined to be an operator and `int_t' to be an operand type.
The multiple form of an operator definition is:
`OPER' <Op-name-list> `(' <arg-list> `)' `:' <result-id> `;'
where:
<Op-name-list> is a list of operators separated by commas.
<arg-list> and <result-id> are as before.
All the operators appearing in <Op-name-list> are given the same
functional signature.
Constraints:
Each operator in <Op-name-list> must appear only once
in any operator definition.
An example is:
OPER rAdd, rSub, rMul, rDiv ( real_t, real_t ): real_t;
How many and what kind of operator is being defined can vary a great
deal depending on the definition of the identifiers which appear in the
function signature. There are essentially three different kinds of
function signatures:
-
Simple signature which only references primitive types.
-
Class signature which references a class or parameter name, though it
may also refer to primitive types.
-
Set signature which references a set name in its signature, though it may
also refer to primitive types.
A simple signature only defines a single operator.
A class signature defines a pattern of a single operator to be created
when the class is instantiated. The actual signature constructed has
the class name replaced by the created type and the parameter names are
replaced with the corresponding positional argument which is used in
instantiating the class.
A set signature defines one operator for each element in the value of
the referenced set. Consider the example:
SET s=[a,b];
sop(s):c;
There are two operators with the name sop defined, with the
signatures:
sop(a):c;
sop(b):c;
If a set name is referenced more than once in the
signature the same value appears in the corresponding position in the
signature. For example consider the specification:
SET s=[a,b];
SET r=[c,d];
OPER sop(s,r):s;
Four operators with the name sop are created. With the four
signatures:
sop(a,c):a;
sop(b,c):b;
sop(a,d):a;
sop(b,d):b;
The signature is duplicated once for each value in a unique set name.
The set name is replaced with each value in turn reguardless of how many
times the set name is referenced in the signature.
Constraints:
If an identifier in a function signature is a CLASS name or a
parameter to a CLASS then the operator definition must be in the body of
the CLASS definition.
No reference to a SET name may be used in a CLASS operator definition.
The basic form of a coercion operator definition is:
`COERCION' <Cop-name> `(' <source-id> `)' `:' <result-id> `;'
where:
<Cop-name> is a coercion operator identifier.
<source-id> is an identifier which determines the source type of
the coercion.
<result-id> is an identifier which determines the result type of
the coercion.
The <source-id> and <result-id> may be either a primitive
type name, a SET name or if in a CLASS definition then they may refer to
the CLASS name being defined or one of the parameters to the CLASS
definition.
An example is:
COERCION cFloat( int_t ): real_t;
In the example coercion operator definition statement above, `cFloat'
is defined to be an operator and, `int_t' and `real_t'
are defined to be a operand types.
Constraints:
<Cop-name> can appear in only one definition statement.
The basic form of an operator identification is:
`INDICATION' <Op-name> `:' <Op-name-list> `;'
where:
<Op-name> is an operator identifier.
<Op-name-list> is list of operator denotations separated by commas.
The order of appearance from left to right of the operators in
the <Op-name-list> determines a search order for the identification process.
When an operator identification operation is performed on <Op-name> then
each operator in <Op-name-list> is tried from left to right.
Constraints:
-
All the operator denotations referenced
must have signatures of the same length. (i.e. If the first
operator denotation has two arguments all the rest of the operators
referenced must also have two arguments.)
-
All operator denotations must have appeared in an operator
definition statement.
-
<Op-name> must not appear in any other operator identification
statements. All potential operators to be identified by
<Op-name> must appear in one operator identification statement.
An example is:
INDICATION Plus: iAdd, rAdd, sUnion;
In the example operator identification statement above, `Plus' is
defined to be an operator and, `iAdd', `rAdd' and `sUnion' are
defined to be operators.
The example defines that `iAdd' will be the first operator tested for
identification of `Plus' and `sUnion' would
be the last operator tested for identification.
The form of a class definition is:
`CLASS' <Class-name>`(' <Param-name-list> `)' `BEGIN' <simple-stmts> `END' `;'
where:
<Class-name> is a class identifier.
<Param-name-list> is a list of parameter identifiers separated by
commas.
<simple-stmts> is a set of operator, coercion and indication statements
that will be created by an instantiation of this class.
The declarations in the <simple-stmts> do not define operators
and coercions but patterns for the creation of such operators. When a
class is instantiated then the patterns for that class are used to
define the operators and coercions from the patterns.
The type identifiers referenced in the declarations in
<simple-stmts> may refer to the class name(<Class-name>),
a specific primitive type or a parameter name(from
<Param-name-list>.) When a class is instantiated a type
corresponding to each identifier is used to create an operator of
coercion from the patterns in <simple-stmts>.
The form of set definition is:
`SET' <Set-name>`=' <set-expression> `;'
where:
<Set-name> is a set identifier.
<set-expression> is a expression which defines the types which
are members of the set.
A set expression may be composed of any of the following
constructs(where s1,s2... are set expressions):
-
[ <Type-name-list> ] where <Type-name-list> is a list of
one or more primitive type names.
-
<Set-name> which identifies a previously defined type set and
yields its value.
-
s1 + s2 which yields the union of the two type sets.
-
s1 * s2 which yields the intersection of the two type sets.
-
s1 - s2 which yields the difference of the two type sets.



|