raesl.compile.typechecking.type_checker#

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#

TypeData

Tuple-like class to keep type data from one side together.

Functions#

check_type(...)

Like 'check_type_unpacked', except the subtype and super-type data is packed in

check_type_unpacked(...)

Check whether sub_value is a subtype of super_value. Iff allow_subtype_limits

_check_type(...)

_check_elementaries(...)

Check sub/super type relation between two elementary types.

Attributes#

TypeValue

raesl.compile.typechecking.type_checker.TypeValue#
class raesl.compile.typechecking.type_checker.TypeData(name_tok: raesl.compile.scanner.Token, suffixes: List[str], value: TypeValue)#

Tuple-like class to keep type data from one side together.

Parameters:
  • name_tok – Initial name of the value in the source, and point of use of the type.

  • suffixes – Child texts after the initial name to indicate the subtype value being examined. See ‘get_name’ for a description of the suffixes.

  • value – Type or node value being examined.

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 - “.<childname>” for a child field in a bundle, or - “[<1-based index>]” for a variable in a variable group.

Returns:

The constructed name.

drop_to_type()#

For nodes, drop down to its type.

expand()#

Expand a sequence of values in ‘self.value’ to a sequence of child TypeData instances.

raesl.compile.typechecking.type_checker.check_type(subtype: Tuple[raesl.compile.scanner.Token, TypeValue], supertype: Tuple[raesl.compile.scanner.Token, TypeValue], allow_subtype_limits: bool = False) raesl.compile.diagnostics.EslDiagnostic | None#

Like ‘check_type_unpacked’, except the subtype and super-type data is packed in tuples.

raesl.compile.typechecking.type_checker.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) raesl.compile.diagnostics.EslDiagnostic | None#

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.

Parameters:
  • sub_nametok – Text in the input of the sub_value, usually a variable.

  • sub_value – Type or node of the sub value.

  • super_nametok – Text in the input of the super_value, usually a variable.

  • super_value – Type or node of the super value.

  • 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.

raesl.compile.typechecking.type_checker._check_type(subtype: TypeData, supertype: TypeData, allow_subtype_limits: bool = False) raesl.compile.diagnostics.EslDiagnostic | None#
raesl.compile.typechecking.type_checker._check_elementaries(subtype: TypeData, supertype: TypeData, allow_subtype_limits: bool = False) raesl.compile.diagnostics.EslDiagnostic | None#

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.