General Information
Tutorials
Reference Manuals
Libraries
Translation Tasks
Tools
Administration
|
Tutorial on Type AnalysisPointer Types
In this chapter we introduce pointer types to our language.
The notation
A new
A pointer value of type Here is an example program that uses these pointer constructs in different contexts: PointerExamp[114]== begin var int k; var int! pi, int! pj; var record int i, bool b, real! r end! rv; type record int x, t! next end t; var t l; pi = new int; pi! = 1; pi = pj; pi! = pj!; rv!.b = true; rv!.r! = 3.2; l.next!.x = 1; l.next = nil; end This macro is attached to a product file. The following productions are added to the grammar: Abstract pointer syntax[115]== RULE: TypeDenoter ::= PointerType END; RULE: PointerType ::= TypeDenoter '!' END; RULE: Variable ::= Variable '!' END; RULE: Expression ::= 'nil' END; RULE: Expression ::= Generator END; RULE: Generator ::= 'new' TypeDenoter END; This macro is invoked in definition 125.
There are two constructs which introduce a pointer type.
The first one is a denoter for a pointer type. Two monadic
operators are created for each pointer type:
One is applied to a pointer and yields the value pointed to,
the other yields the reference of an entity instead of its
value. The dereferencing operators of all pointer types are
overloaded on the indication DerefOpr; RefOpr; NilOpr; nilType -> IsType = {1}; This macro is invoked in definition 124.
Creating these pairs of operators for a pointer type establishes
the condition Pointer type denotation[117]== RULE: TypeDenoter ::= PointerType COMPUTE TypeDenoter.Type = PointerType.Type; END; SYMBOL PointerType INHERITS TypeDenotation, OperatorDefs END; RULE: PointerType ::= TypeDenoter '!' COMPUTE PointerType.GotOper += ORDER (Coercible (NilOpr, nilType, PointerType.Type), MonadicOperator (DerefOpr, NewKey(), PointerType.Type, TypeDenoter.Type), MonadicOperator (RefOpr, NewKey(), TypeDenoter.Type, PointerType.Type)); END; RULE: Expression ::= 'nil' COMPUTE PrimaryContext (Expression, nilType); END; This macro is invoked in definition 125.
A generator also introduces a pointer type. The
Generator[118]== SYMBOL Generator INHERITS TypeDenotation, OperatorDefs END; RULE: Generator ::= 'new' TypeDenoter COMPUTE Generator.GotOper += ORDER ( MonadicOperator (DerefOpr, NewKey(), Generator.Type, TypeDenoter.Type), MonadicOperator (RefOpr, NewKey(), TypeDenoter.Type, Generator.Type)); END; RULE: Expression ::= Generator COMPUTE PrimaryContext (Expression, Generator.Type); END; This macro is invoked in definition 125.
Types
We use the facilities of the RULE: PointerType ::= TypeDenoter '!' COMPUTE PointerType.GotType += AddTypeToBlock (PointerType.Type, PointerClass, VResetComponentTypes (PointerType.Type, SingleDefTableKeyList (TypeDenoter.Type))) <- .moreTypeProperies; END; RULE: Generator ::= 'new' TypeDenoter COMPUTE Generator.GotType += AddTypeToBlock (Generator.Type, PointerClass, VResetComponentTypes (Generator.Type, SingleDefTableKeyList (TypeDenoter.Type))) <- .moreTypeProperies; END; This macro is attached to a product file.
The Pointer type equality[120]== PointerClass; This macro is invoked in definition 124.
Pointer types are to be treated especially when types are checked for
equivalence: On the one hand, a type is allowed to be
recursively defined if the recursion goes through a pointer
component, for example in Pointer types allow recursion[121]== RULE: PointerType ::= TypeDenoter '!' COMPUTE .moreTypeProperies = ORDER (ResetTypeName (PointerType.Type, "pointer..."), ResetTypeLine (PointerType.Type, LINE), ResetAllowRecurType (PointerType.Type, 1)); END; RULE: Generator ::= 'new' TypeDenoter COMPUTE .moreTypeProperies = ORDER (ResetTypeName (Generator.Type, "pointer..."), ResetTypeLine (Generator.Type, LINE), ResetAllowRecurType (Generator.Type, 1)); END; This macro is invoked in definition 125. On the other hand, we have to check that pointer types are not defined directly recursively, or indirectly recursively s.t. only pointer types are involved: type p1! p1; type p2! p3; type p3! p2;In the example above all three type are pairwise equivalent. Recursion check for pointer types[122]== RULE: PointerType ::= TypeDenoter '!' COMPUTE IF (EQ (FinalType (PointerType.Type), FinalType (TypeDenoter.Type)), message (ERROR, "Recursively defined pointer type", 0, COORDREF)) <- INCLUDING Program.TypeIsSet; END; This macro is invoked in definition 125.
For the dereferencing operation applied to a Pointer variable[123]== RULE: Variable ::= Variable '!' COMPUTE MonadicContext (Variable[1], , Variable[2]); Indication (DerefOpr); IF(BadOperator, message(ERROR,"Dereferencing not allowed", 0, COORDREF)); END; This macro is invoked in definition 125. Pointer.pdl[124]== Pointer type equality[120] Pointer operators[116] This macro is attached to a product file. Pointer.lido[125]== Abstract pointer syntax[115] Pointer type denotation[117] Generator[118] Pointer types allow recursion[121] Recursion check for pointer types[122] Pointer variable[123] This macro is attached to a product file. Pointer.con[126]== Concrete pointer syntax[143] This macro is attached to a product file.
|