General Information
Tutorials
Reference Manuals
Libraries
Translation Tasks
Tools
Administration
|
Tutorial on Type AnalysisRecord Types
We introduce record types to our language in order to
demonstrate how composed user defined types are specified.
A record type is described by a sequence of field declarations
which have the same semantics as
Here is an example program that defines and uses a record
variable named RecordExamp[47]== begin var record int i, bool b, real r end rv; var int j, bool c, real s; j = rv.i; c = rv.b; s = rv.r; end This macro is attached to a product file. The following productions describe record types and component selections: Abstract record syntax[48]== RULE: TypeDenoter ::= RecordType END; RULE: RecordType ::='record' ObjDecls 'end' END; RULE: Variable ::= Variable '.' SelectIdent END; RULE: SelectIdent ::= Ident END; This macro is invoked in definition 62.
An abstraction of a record type is the sequence of component
definitions, each consisting of a type and a name.
A Type denoter[49]== SYMBOL RecordType INHERITS TypeDenotation END; RULE: TypeDenoter ::= RecordType COMPUTE TypeDenoter.Type = RecordType.Type; END; RULE: RecordType ::= 'record' ObjDecls 'end' COMPUTE .GotTypeProp = ORDER ( ResetTypeName (RecordType.Type, "record..."), ResetTypeLine (RecordType.Type, LINE)); END; This macro is invoked in definition 62.
The last computation above sets the properties
The construct for component selection, e.g. $/Name/ScopeProp.gnrc:inst $/Type/TypeDep.gnrc:inst This macro is invoked in definition 60.
The role SYMBOL RecordType INHERITS ExportRange COMPUTE SYNT.ScopeKey = SYNT.Type; END; This macro is invoked in definition 62.
Type EquivalenceAs record types have non-trivial abstractions, the question arises under which circumstances two record types are the same. Consider the following examples: RecordEqual[52]== begin var record int i, bool b, real r end va; var record int i, bool b, real r end vc; var record int j, bool k, real l end vd; va = vc; va = vd; end This macro is attached to a product file.
Typing rules of the language have to state which of the variables
The first rule states that every occurrence of a description of a record type (or of any other compound type) introduces a type different from all other types, even from those that are equally notated. Under this rule all three variables have different types. This rule is called name equivalence, because every type description gets a name - explicitly or implicitly, as in this example -and types are distingushed by their names.
The second rule states that two types are equal if their
abstractions are equal; i.e. the sequences of components
coincide elementwise in the types and names of components.
In the above example In case of structural equivalence the type rules of the language may define precisely, which type properties belong to the abstraction that is used to determine type equivalence. For example, the rule could state that the types of the record components belong to the abstraction, and the names of the components do not belong to it. In that case all four variables of the above example would have the same type.
The type analysis library provides a module $/Type/StructEquiv.fw This macro is invoked in definition 60. In this language stuctural equivalence is specified, such that for record types only the sequence of types, but not the names of components are relevant for structural type equivalence. The following computation in the RULE context of a record type denotation specifies which properties of a record type are considered for the check whether two types are equivalent. Here we state two rules:
First, a record type can only be equivalent to a type that is
a record type, too. For that purpose we introduce a
key RecordClass; This macro is invoked in definition 61.
The rule computation
Second, two record types
Beyond type equivalence, our language requires further checks
on type structures. So, the list of component types is also
associated as a property ComponentTypes: DefTableKeyList [VReset]; "DefTableKeyList.h" This macro is invoked in definition 61. PropLib module[56]== $/Prop/PropLib.fw This macro is invoked in definition 60.
The attribute RULE: RecordType ::= 'record' ObjDecls 'end' COMPUTE RecordType.GotType += AddTypeToBlock (RecordType.Type, RecordClass, VResetComponentTypes (RecordType.Type, ObjDecls.OpndTypeList)) <- .GotTypeProp; END; SYMBOL ObjDecls INHERITS OpndTypeListRoot END; SYMBOL ObjDecl INHERITS OpndTypeListElem END; SYMBOL ObjDecl COMPUTE SYNT.DefTableKeyElem = SYNT.Type; END; This macro is invoked in definition 62.
Qualified Names
A record component selection of the form
RULE: Variable ::= Variable '.' SelectIdent COMPUTE PrimaryContext (Variable[1], SelectIdent.Type); END; This macro is invoked in definition 62.
The roles Selection types[59]== SYMBOL SelectIdent INHERITS QualIdUse, ChkQualIdUse, IdentOcc, TypedUseId, ChkTypedUseId, PrtType END; RULE: Variable ::= Variable '.' SelectIdent COMPUTE SelectIdent.ScopeKey = Variable[2].Type; IF (EQ (SelectIdent.Scope, NoEnv), message (ERROR, "selection applied to non record type", 0, COORDREF)); END; This macro is invoked in definition 62. Record.specs[60]== Scope property module[50] Struct equiv module[53] PropLib module[56] This macro is attached to a product file. Record.pdl[61]== Type class[54] Component type property[55] This macro is attached to a product file. Record.lido[62]== Abstract record syntax[48] Type denoter[49] Range[51] Type equality computation[57] Selection expression[58] Selection types[59] This macro is attached to a product file.
|