Modula-2 Reloaded

A Modern Typesafe & Literate Programming Notation

Site Menu

Project

Specification

Implementation

Recommendations

Reference

Needs Updating

Work in Progress

Wastebasket

Wiki Manual

edit SideBar

Synthesis Of Non Scalar Type Conversion

Objective

The objective of the facility described here is to facilitate synthesis of type conversion between non-scalar types even if no direct conversion path exists between them or their component types.

Given v of vector type V with component type T1 and w of vector type W with component type T2 ...

TYPE
    V = OPAQUE RECORD ("V-Type") v1, v2, v3 : T1 END;
    W = OPAQUE RECORD ("V-Type") v1, v2, v3 : T2 END;

VAR
    v : V; w : W;

the conversion from v to w ...

w := v :: W;

should be synthesised by the compiler in the event that no direct conversion path exists from type T1 to type T2, as long as V and W have the same number of components.

Approach

The key to synthesising such a conversion is to decompose v into its components, serialise the components using conversion primitive toASCII of type T1, then deserialise the components using conversion primitive fromASCII of type T2 and finally compose w from the so converted components.

To facilitate this, the non-scalar types must provide

  • a function to return the number of components or highest index
  • an accessor function to return the n-th component of a vector
  • a mutator procedure to overwrite the n-th component of a vector

The component type can be deduced form the return type of the accessor function.

This could be done using the following bindings:

PROCEDURE [HIGH] highestComponentIndex ( v : VECTOR ) : CARDINAL;
PROCEDURE [.] componentN ( n : CARDINAL; v : VECTOR ) : ComponentType;
PROCEDURE [!] setComponentN ( n : CARDINAL; VAR v : VECTOR; c : ComponentType );

An example is given in TypeSampleVector

The generalised synthesis algorithm is:

VAR v : V; w : W;
w := v :: W;

synthesises to =>

VAR v : V; w : W;
    index : CARDINAL;
    significand,
    exponent : ARRAY %MAX_LITERAL_LENGTH% OF CHAR;

IF HIGH(v) = HIGH(w) THEN
    FOR index := 0 TO HIGH(v) DO
        V.toASCII( %ACCESSOR%(index, v), %decOrHexT1%, significand, exponent );
        %MUTATOR%(index, w, W.fromASCII( %decOrHexT2%, significand, exponent ));
    END; (* FOR *)
END; (* IF *)

where %MAX_LITERAL_LENGTH% is a compiler constant designating the maximum length allowed for literals, %decOrHexT1% and %decOrHexT2% are boolean values indicating the radix system of a type's internal representation, %ACCESSOR% is the accessor function and %MUTATOR% is the mutator procedure.

NB: For the compiler to save stack space for the intermediate strings significand and exponent a means to obtain the exact required number of digits for a scalar type could be introduced. This is an optimisation issue and it has no impact on the semantics of the synthesis.