:py:mod:`raesl.compile.typechecking.type_checker` ================================================= .. py:module:: raesl.compile.typechecking.type_checker .. autoapi-nested-parse:: Type checking. Type compatibility ------------------ Type 'sub_type' is compatible with type 'super_type' if - Type 'sub_type' is (possibly indirectly) derived from 'super_type'. - Type 'sub_type' has no additional value constraints in the form of enumerations, upper or lower limits, or constants relative to 'super_type'. The former condition ensures the values are fundamentally compatible. This condition should always hold, the latter condition ensures that all possible values of 'super_type' can also be expressed in 'sub_type'. This is particularly relevant if 'sub_type' may receive data from the element with 'super_type'. If data flow is in the other direction only, the second condition seems less relevant. Note that units are not relevant in this context. If the sub_type is a subtype of of 'super_type', the former always has all units of the latter. Relevant code type-classes -------------------------- Several classes have or use types, or represent data of some type. These classes are - raesl.compile.ast.types.ElementaryType (type of a single value). - raesl.compile.ast.types.Compound (type of a bundle of values). - raesl.compile.ast.nodes.ElementaryVarNode (data of an elementary type). - raesl.compile.ast.nodes.CompoundVarNode (data of a bundle). - raesl.compile.ast.nodes.GroupNode (data of a variable group). where an ElementaryVarNode contains an ElementaryType, a CompoundVarNode contains a Compound (type), and GroupNode eventually always points at ElementaryVarNode or CompoundVarNode instances. The entry_point 'check_type' accepts all the above kinds of objects. Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: raesl.compile.typechecking.type_checker.TypeData Functions ~~~~~~~~~ .. autoapisummary:: raesl.compile.typechecking.type_checker.check_type raesl.compile.typechecking.type_checker.check_type_unpacked raesl.compile.typechecking.type_checker._check_type raesl.compile.typechecking.type_checker._check_elementaries Attributes ~~~~~~~~~~ .. autoapisummary:: raesl.compile.typechecking.type_checker.TypeValue .. py:data:: TypeValue .. py:class:: TypeData(name_tok: raesl.compile.scanner.Token, suffixes: List[str], value: TypeValue) Tuple-like class to keep type data from one side together. :param name_tok: Initial name of the value in the source, and point of use of the type. :param suffixes: Child texts after the initial name to indicate the subtype value being examined. See 'get_name' for a description of the suffixes. :param value: Type or node value being examined. .. py:method:: get_name() Construct a human-readable name of the point being examined. It consists of the initial name followed by zero or more suffixes, where a suffix can be one of the following - "." for a child field in a bundle, or - "[<1-based index>]" for a variable in a variable group. :returns: The constructed name. .. py:method:: drop_to_type() For nodes, drop down to its type. .. py:method:: expand() Expand a sequence of values in 'self.value' to a sequence of child TypeData instances. .. py:function:: check_type(subtype: Tuple[raesl.compile.scanner.Token, TypeValue], supertype: Tuple[raesl.compile.scanner.Token, TypeValue], allow_subtype_limits: bool = False) -> Optional[raesl.compile.diagnostics.EslDiagnostic] Like 'check_type_unpacked', except the subtype and super-type data is packed in tuples. .. py:function:: check_type_unpacked(sub_nametok: raesl.compile.scanner.Token, sub_value: TypeValue, super_nametok: raesl.compile.scanner.Token, super_value: TypeValue, allow_subtype_limits: bool = False) -> Optional[raesl.compile.diagnostics.EslDiagnostic] Check whether sub_value is a subtype of super_value. Iff allow_subtype_limits holds, the sub_value may have additional value constraints. Returns None if the sub_value is indeed a subtype of super_value, possibly taking additional value constraints into account. Otherwise it returns a problem description of how it fails. :param sub_nametok: Text in the input of the sub_value, usually a variable. :param sub_value: Type or node of the sub value. :param super_nametok: Text in the input of the super_value, usually a variable. :param super_value: Type or node of the super value. :param allow_subtype_limits: Whether sub_value may have additional value constraints relative to super_value. :returns: None if sub_value is a subtype of super_value taking allow_subtype_limits into account, else a problem description of how it fails to have the subtype relation. .. py:function:: _check_type(subtype: TypeData, supertype: TypeData, allow_subtype_limits: bool = False) -> Optional[raesl.compile.diagnostics.EslDiagnostic] .. py:function:: _check_elementaries(subtype: TypeData, supertype: TypeData, allow_subtype_limits: bool = False) -> Optional[raesl.compile.diagnostics.EslDiagnostic] Check sub/super type relation between two elementary types. :returns: None if subtype is a subtype of supertype taking allow_subtype_limits into account, otherwise it returns a diagnostic describing why the relation does not hold.